1. Zanim zaczniesz
Niesamowite przełomowe rozwiązanie w dziedzinie AlphaGo i AlphaStar udowodniło, że można wykorzystać systemy uczące się do tworzenia agentów gier na poziomie superludzkich. To ciekawe ćwiczenie polegające na zbudowaniu małej gry opartej na ML, w której nauczysz się umiejętności potrzebnych do tworzenia potężnych agentów.
Z tego ćwiczenia w Codelabs dowiesz się, jak stworzyć grę planszową przy użyciu:
- Agent TensorFlow do trenowania agenta gry z użyciem uczenia przez wzmacnianie
- Udostępnianie modelu TensorFlow
- Flutter tworzy wieloplatformową grę planszową
Wymagania wstępne
- Podstawowa wiedza o rozwoju technologii Flutter w Dart
- Podstawowa wiedza na temat systemów uczących się z wykorzystaniem TensorFlow, np. do trenowania i wdrażania
- Podstawowa znajomość Pythona, terminali i Dockera
Czego się nauczysz
- Jak wytrenować agenta postaci niezależnej (NPC) za pomocą agentów TensorFlow
- Jak udostępnić wytrenowany model za pomocą TensorFlow Serving
- Jak stworzyć wieloplatformową grę planszową Flutter
Czego potrzebujesz
- Pakiet SDK Flutter
- Konfiguracja aplikacji Flutter na Androida i iOS
- Konfiguracja Flutter na komputerze
- Konfigurowanie przeglądarki na potrzeby Flutter
- Konfigurowanie kodu VS Code w usługach Flutter i Dart
- Docker
- Bash
- Python w wersji 3.7 lub nowszej
2. Gra The Plane Strike
Stworzona w tym ćwiczeniu gra nosi nazwę „Plane Strike”, czyli małą dwuosobową grę planszową przypominającą grę planszową „Battleship”. Zasady są bardzo proste:
- Gracz gra z agentem NPC wytrenowanym przez systemy uczące się. Gracz może rozpocząć grę, klikając dowolną komórkę na planszy agenta.
- Na początku gry człowiek i agent mają „samolot” (8 zielonych komórek tworzących „płaszczyznę”, jak widać na planszy gracza na ilustracji poniżej) na jej własnej planszy; te „samoloty” są umieszczane losowo, widoczne tylko dla właścicieli planszy i ukryte dla przeciwników.
- Gracz i agent uderzają na zmianę w jedną komórkę ze planszy przeciwnika. Gracz może kliknąć dowolną komórkę na planszy agenta, a agent sam dokona wyboru na podstawie prognozy modelu systemów uczących się. Komórka, którą próbowano wyświetlić, ma kolor czerwony, jeśli jest to „samolot” komórka („hit”); w przeciwnym razie zmieni kolor na żółty („miss”).
- Gra, która zdobędzie 8 czerwonych komórek. gra jest ponownie uruchamiana z nowymi planszami.
Oto przykładowa rozgrywka:
3. Konfigurowanie środowiska programistycznego Flutter
Do programowania w technologii Flutter potrzebujesz 2 programów do ukończenia ćwiczenia – pakietu SDK Flutter i edytora.
Ćwiczenie z programowania możesz uruchomić na dowolnym z tych urządzeń:
- Symulator iOS (wymaga zainstalowania narzędzi Xcode).
- Emulator Androida (wymaga skonfigurowania Android Studio).
- Przeglądarka (do debugowania wymagany jest Chrome).
- Aplikacja komputerowa w systemie Windows, Linux lub macOS Programowanie należy tworzyć na platformie, na której zamierzasz wdrożyć usługę. Jeśli więc chcesz opracować aplikację komputerową dla systemu Windows, musisz to zrobić w tym systemie, aby uzyskać dostęp do odpowiedniego łańcucha kompilacji. Istnieją wymagania związane z konkretnymi systemami operacyjnymi, które zostały szczegółowo omówione na stronie docs.flutter.dev/desktop.
4. Konfiguracja
Aby pobrać kod do tego ćwiczenia z programowania:
- Aby przeprowadzić ten moduł, przejdź do repozytorium GitHub.
- Kliknij Kod > Pobierz plik ZIP, aby pobrać cały kod do tego ćwiczenia z programowania.
- Rozpakuj pobrany plik ZIP, aby rozpakować folder główny
codelabs-main
ze wszystkimi potrzebnymi zasobami.
Aby wykonać te ćwiczenia w Codelabs, potrzebujesz tylko plików w podkatalogu tfagents-flutter/
repozytorium, które zawiera wiele folderów:
- Foldery od
step0
dostep6
zawierają kod startowy, który powstał w każdym kroku tego ćwiczenia z programowania. - Folder
finished
zawiera kompletny kod gotowej przykładowej aplikacji. - Każdy folder zawiera podfolder
backbend
z kodem backendu i podfolderfrontend
zawierający kod frontendu Flutter
5. Pobierz zależności w projekcie
Backend
Otwórz terminal i przejdź do podfolderu tfagents-flutter
. Wykonaj zapytanie:
pip install -r requirements.txt
Frontend
- W sekcji VS Code kliknij File (Plik) > Otwórz folder, a następnie wybierz folder
step0
z pobranego wcześniej kodu źródłowego. - Otwórz plik
step0/frontend/lib/main.dart
. Jeśli pojawi się okno VS Code z prośbą o pobranie pakietów wymaganych do aplikacji startowej, kliknij Pobierz pakiety. - Jeśli nie widzisz tego okna, otwórz terminal i uruchom polecenie
flutter pub get
w folderzestep0/frontend
.
6. Krok 0. Uruchom aplikację startową
- Otwórz plik
step0/frontend/lib/main.dart
w VS Code. Sprawdź, czy emulator Androida lub symulator iOS są prawidłowo skonfigurowane i wyświetlają się na pasku stanu.
Na przykład podczas używania Pixela 5 z emulatorem Androida możesz zobaczyć takie elementy:
Oto, co możesz zobaczyć, używając iPhone'a 13 za pomocą symulatora iOS:
- Kliknij Rozpocznij debugowanie.
Uruchamianie i poznawanie aplikacji
Aplikacja powinna się uruchomić w emulatorze Androida lub symulatorze iOS. Interfejs jest dość prosty. Na gości czekają 2 plansze do gier. człowiek może kliknąć u góry dowolną komórkę na planszy agenta. Wytrenujesz agenta, aby automatycznie przewidywał, gdzie uderzyć, na podstawie planszy gracza.
Znajdująca się w nich aplikacja Flutter wysyła bieżącą planszę gracza do backendu, który uruchamia model uczenia się przez wzmocnienie i zwraca przewidywaną pozycję komórki, która ma zostać zaatakowana. Po otrzymaniu odpowiedzi frontend wyświetli wynik w interfejsie użytkownika.
Jeśli teraz klikniesz dowolną komórkę na tablicy agenta, nic się nie stanie, ponieważ aplikacja nie może jeszcze komunikować się z backendem.
7. Krok 1. Utwórz środowisko Pythona dla agentów TensorFlow
Głównym celem tych ćwiczeń w Codelabs jest zaprojektowanie agenta, który uczy się przez interakcję ze środowiskiem. Chociaż gra Plane Strike jest stosunkowo prosta i można opracować reguły dla agenta NPC, musisz wykorzystać uczenie się przez wzmacnianie, aby szkolić agenta, aby zdobyć nowe umiejętności i łatwo budować agentów do innych gier w przyszłości.
W standardowym ustawieniu uczenia się przez wzmacnianie (RL) agent otrzymuje obserwację w każdym kroku i wybiera działanie. Działanie jest wykonywane w środowisku, a środowisko zwraca nagrodę i nową obserwację. Agent uczy się zasad, aby wybierać działania mające na celu maksymalizację sumy nagród, inaczej nazywanych zwrotem. Wielokrotnie grając w grę, agent może poznać wzorce i szlifować swoje umiejętności, aby opanować rozgrywkę. Aby sformułować grę Plane Strike jako zagadnienie RL, potraktuj stan planszy jako obserwację, pozycję uderzenia jako działanie, a sygnał uderzenia/braku jako nagrodę.
Aby wytrenować agenta NPC, użyj agentów TensorFlow – niezawodna, skalowalna i łatwa w obsłudze biblioteka do uczenia przez wzmacnianie do TensorFlow.
Agenty TF świetnie się nadają do uczenia przez wzmacnianie, bo zawierają obszerny zestaw ćwiczeń z programowania, przykłady i obszerną dokumentację, które pomogą Ci zacząć. Agenty TF mogą służyć do rozwiązywania realistycznych i złożonych problemów z funkcją RL przy skalowalności oraz do szybkiego opracowywania nowych algorytmów RL. Możesz łatwo przełączać się między różnymi agentami i algorytmami eksperymentów. Usługa została dobrze przetestowana i łatwa w konfiguracji.
W OpenAI Gym jest zaimplementowanych wiele gotowych środowisk gier (np. gry Atari), Mujuco itp., które agenty TF mogą łatwo wykorzystać. Plane Strike to kompletna gra niestandardowa, więc najpierw musisz wdrożyć nowe środowisko od zera.
Aby wdrożyć środowisko agentów TF Python, musisz wdrożyć te metody:
class YourGameEnv(py_environment.PyEnvironment): def __init__(self): """Initialize environment.""" def action_spec(self): """Return action_spec.""" def observation_spec(self): """Return observation_spec.""" def _reset(self): """Return initial_time_step.""" def _step(self, action): """Apply action and return new time_step."""
Najważniejsza to funkcja _step()
, która wykonuje działanie i zwraca nowy obiekt time_step
. w przypadku gry Plane Strike masz planszę do gry. gdy pojawi się nowe uderzenie, w zależności od stanu planszy środowisko określa:
- Jak powinna wyglądać plansza do gry w następnej kolejności (czy komórka powinna zmienić kolor na czerwony lub żółty w zależności od ukrytej lokalizacji samolotu?)
- Jaką nagrodę powinien otrzymać zawodnik za tę pozycję (nagroda za trafienie lub kara za nieudane uderzenie?)
- Czy należy zakończyć grę (czy ktoś wygrał?)
- Dodaj ten kod do funkcji
_step()
w pliku_planestrike_py_environment.py
:
if self._hit_count == self._plane_size: self._episode_ended = True return self.reset() if self._strike_count + 1 == self._max_steps: self.reset() return ts.termination( np.array(self._visible_board, dtype=np.float32), UNFINISHED_GAME_REWARD ) self._strike_count += 1 action_x = action // self._board_size action_y = action % self._board_size # Hit if self._hidden_board[action_x][action_y] == HIDDEN_BOARD_CELL_OCCUPIED: # Non-repeat move if self._visible_board[action_x][action_y] == VISIBLE_BOARD_CELL_UNTRIED: self._hit_count += 1 self._visible_board[action_x][action_y] = VISIBLE_BOARD_CELL_HIT # Successful strike if self._hit_count == self._plane_size: # Game finished self._episode_ended = True return ts.termination( np.array(self._visible_board, dtype=np.float32), FINISHED_GAME_REWARD, ) else: self._episode_ended = False return ts.transition( np.array(self._visible_board, dtype=np.float32), HIT_REWARD, self._discount, ) # Repeat strike else: self._episode_ended = False return ts.transition( np.array(self._visible_board, dtype=np.float32), REPEAT_STRIKE_REWARD, self._discount, ) # Miss else: # Unsuccessful strike self._episode_ended = False self._visible_board[action_x][action_y] = VISIBLE_BOARD_CELL_MISS return ts.transition( np.array(self._visible_board, dtype=np.float32), MISS_REWARD, self._discount,
8. Krok 2. Wytrenuj agenta gry za pomocą agentów TensorFlow
Po wdrożeniu środowiska agentów TF możesz wytrenować agenta gry. W tym ćwiczeniu w Codelabs używasz agenta REINFORCE. REINFORCE to algorytm gradientu zasad w RL. Podstawowym założeniem jest dostosowanie parametrów sieci neuronowej zasad na podstawie sygnałów nagród zebranych podczas rozgrywki, tak aby sieć zasad mogła zmaksymalizować zwrot z kolejnych rozgrywek.
- Najpierw trzeba utworzyć instancje środowisk trenowania i oceny. Dodaj ten kod do funkcji
train_agent()
w plikustep2/backend/training.py
:
train_py_env = planestrike_py_environment.PlaneStrikePyEnvironment( board_size=BOARD_SIZE, discount=DISCOUNT, max_steps=BOARD_SIZE**2 ) eval_py_env = planestrike_py_environment.PlaneStrikePyEnvironment( board_size=BOARD_SIZE, discount=DISCOUNT, max_steps=BOARD_SIZE**2 ) train_env = tf_py_environment.TFPyEnvironment(train_py_env) eval_env = tf_py_environment.TFPyEnvironment(eval_py_env)
- Musisz utworzyć agenta uczenia przez wzmacnianie, który będzie trenowany. W tym ćwiczeniu w Codelabs używasz agenta REINFORCE, który jest agentem opartym na zasadach. Dodaj ten kod tuż pod kodem powyżej:
actor_net = tfa.networks.Sequential( [ tfa.keras_layers.InnerReshape([BOARD_SIZE, BOARD_SIZE], [BOARD_SIZE**2]), tf.keras.layers.Dense(FC_LAYER_PARAMS, activation="relu"), tf.keras.layers.Dense(BOARD_SIZE**2), tf.keras.layers.Lambda(lambda t: tfp.distributions.Categorical(logits=t)), ], input_spec=train_py_env.observation_spec(), ) optimizer = tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE) train_step_counter = tf.Variable(0) tf_agent = reinforce_agent.ReinforceAgent( train_env.time_step_spec(), train_env.action_spec(), actor_network=actor_net, optimizer=optimizer, normalize_returns=True, train_step_counter=train_step_counter, )
- Na koniec wytrenuj agenta w pętli trenowania. W pętli najpierw zbierasz w buforze kilka odcinków rozgrywki, a potem trenujesz agenta, korzystając z buforowanych danych. Dodaj ten kod do funkcji
train_agent()
w plikustep2/backend/training.py
:
# Collect a few episodes using collect_policy and save to the replay buffer. collect_episode( train_py_env, collect_policy, COLLECT_EPISODES_PER_ITERATION, replay_buffer_observer, ) # Use data from the buffer and update the agent's network. iterator = iter(replay_buffer.as_dataset(sample_batch_size=1)) trajectories, _ = next(iterator) tf_agent.train(experience=trajectories) replay_buffer.clear()
- Teraz możesz rozpocząć szkolenie. W terminalu przejdź do folderu
step2/backend
na komputerze i uruchom polecenie:
python training.py
W zależności od konfiguracji sprzętowej trenowanie może potrwać 8–12 godzin (nie musisz samodzielnie kończyć trenowania, ponieważ w step3
dostępny jest już wytrenowany model). W międzyczasie możesz śledzić postęp za pomocą usługi TensorBoard. Otwórz nowy terminal, przejdź do folderu step2/backend
na komputerze i uruchom polecenie:
tensorboard --logdir tf_agents_log/
tf_agents_log
to folder zawierający dziennik trenowania. Przykładowe uruchomienie treningowe wygląda tak:
Widać, że średnia długość odcinka zmniejsza się i średnia wartość zwrotu wzrasta w miarę postępów trenowania. Intuicyjnie zrozumiesz, że jeśli agent jest mądrzejszy i lepiej przewiduje, gra staje się krótsza i zdobywa więcej nagród. Ma to sens, ponieważ agent chce ukończyć grę w mniejszej liczbie kroków, aby zminimalizować liczbę rabatów na nagrody w późniejszych krokach.
Po zakończeniu trenowania wytrenowany model zostanie wyeksportowany do folderu policy_model
.
9. Krok 3. Wdróż wytrenowany model za pomocą TensorFlow Serving
Po wytrenowaniu agenta gry możesz wdrożyć go za pomocą TensorFlow Serving.
- W terminalu otwórz folder
step3/backend
na komputerze i uruchom TensorFlow Serving with Docker:
docker run -t --rm -p 8501:8501 -p 8500:8500 -v "$(pwd)/backend/policy_model:/models/policy_model" -e MODEL_NAME=policy_model tensorflow/serving
Docker automatycznie pobiera najpierw obraz TensorFlow Serving, co zajmuje minutę. Następnie powinna uruchomić się usługa TensorFlow Serving. Dziennik powinien wyglądać tak:
2022-05-30 02:38:54.147771: I tensorflow_serving/model_servers/server.cc:89] Building single TensorFlow model file config: model_name: policy_model model_base_path: /models/policy_model 2022-05-30 02:38:54.148222: I tensorflow_serving/model_servers/server_core.cc:465] Adding/updating models. 2022-05-30 02:38:54.148273: I tensorflow_serving/model_servers/server_core.cc:591] (Re-)adding model: policy_model 2022-05-30 02:38:54.262684: I tensorflow_serving/core/basic_manager.cc:740] Successfully reserved resources to load servable {name: policy_model version: 123} 2022-05-30 02:38:54.262768: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: policy_model version: 123} 2022-05-30 02:38:54.262787: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: policy_model version: 123} 2022-05-30 02:38:54.265010: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:38] Reading SavedModel from: /models/policy_model/123 2022-05-30 02:38:54.277811: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:90] Reading meta graph with tags { serve } 2022-05-30 02:38:54.278116: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:132] Reading SavedModel debug info (if present) from: /models/policy_model/123 2022-05-30 02:38:54.280229: I external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. 2022-05-30 02:38:54.332352: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle. 2022-05-30 02:38:54.337000: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 2193480000 Hz 2022-05-30 02:38:54.402803: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/policy_model/123 2022-05-30 02:38:54.410707: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 145695 microseconds. 2022-05-30 02:38:54.412726: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/policy_model/123/assets.extra/tf_serving_warmup_requests 2022-05-30 02:38:54.417277: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: policy_model version: 123} 2022-05-30 02:38:54.419846: I tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models 2022-05-30 02:38:54.420066: I tensorflow_serving/model_servers/server.cc:367] Profiler service is enabled 2022-05-30 02:38:54.428339: I tensorflow_serving/model_servers/server.cc:393] Running gRPC ModelServer at 0.0.0.0:8500 ... [warn] getaddrinfo: address family for nodename not supported 2022-05-30 02:38:54.431620: I tensorflow_serving/model_servers/server.cc:414] Exporting HTTP/REST API at:localhost:8501 ... [evhttp_server.cc : 245] NET_LOG: Entering the event loop ...
Aby sprawdzić, czy punkt końcowy działa zgodnie z oczekiwaniami, możesz wysłać przykładowe żądanie:
curl -d '{"signature_name":"action","instances":[{"0/discount":0.0,"0/observation":[[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]],"0/reward":0.0,"0/step_type":0}]}' -X POST http://localhost:8501/v1/models/policy_model:predict
Punkt końcowy zwróci przewidywaną pozycję 45
, czyli (5, 5) na środku planszy (jeśli jesteś ciekawostką, możesz spróbować dowiedzieć się, dlaczego środek planszy najlepiej przydaje się przy pierwszym uderzeniu).
{ "predictions": [45] }
Znakomicie. Udało Ci się zbudować backend, który przewiduje kolejne ostrzeżenie dla agenta NPC.
10. Krok 4. Utwórz aplikację Flutter na Androida i iOS
Backend jest gotowy. Możesz zacząć wysyłać do tego zespołu prośby, aby otrzymywać z aplikacji Flutter prognozy dotyczące pozycji ostrzeżenia.
- Najpierw musisz zdefiniować klasę, która opakowuje dane wejściowe do wysłania. Dodaj ten kod do pliku
step4/frontend/lib/game_agent.dart
:
class Inputs { final List<double> _boardState; Inputs(this._boardState); Map<String, dynamic> toJson() { final Map<String, dynamic> data = <String, dynamic>{}; data['0/discount'] = [0.0]; data['0/observation'] = [_boardState]; data['0/reward'] = [0.0]; data['0/step_type'] = [0]; return data; } }
Teraz możesz wysłać żądanie do TensorFlow Serving, aby generować prognozy.
- Dodaj ten kod do funkcji
predict()
w plikustep4/frontend/lib/game_agent.dart
:
var flattenedBoardState = boardState.expand((i) => i).toList(); final response = await http.post( Uri.parse('http://$server:8501/v1/models/policy_model:predict'), body: jsonEncode(<String, dynamic>{ 'signature_name': 'action', 'instances': [Inputs(flattenedBoardState)] }), ); if (response.statusCode == 200) { var output = List<int>.from( jsonDecode(response.body)['predictions'] as List<dynamic>); return output[0]; } else { throw Exception('Error response'); }
Gdy aplikacja otrzyma odpowiedź z backendu, zaktualizujesz interfejs gry, aby odzwierciedlić postępy w grze.
- Dodaj ten kod do funkcji
_gridItemTapped()
w plikustep4/frontend/lib/main.dart
:
int agentAction = await _policyGradientAgent.predict(_playerVisibleBoardState); _agentActionX = agentAction ~/ _boardSize; _agentActionY = agentAction % _boardSize; if (_playerHiddenBoardState[_agentActionX][_agentActionY] == hiddenBoardCellOccupied) { // Non-repeat move if (_playerVisibleBoardState[_agentActionX][_agentActionY] == visibleBoardCellUntried) { _agentHitCount++; } _playerVisibleBoardState[_agentActionX][_agentActionY] = visibleBoardCellHit; } else { _playerVisibleBoardState[_agentActionX][_agentActionY] = visibleBoardCellMiss; } setState(() {});
Uruchom
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji.
- Aby rozpocząć grę, kliknij dowolną komórkę na planszy agenta.
11. Krok 5. Włącz aplikację Flutter na platformach komputerowych
Oprócz Androida i iOS Flutter obsługuje także platformy komputerowe, takie jak Linux, Mac i Windows.
Linux
- Upewnij się, że urządzenie docelowe na pasku stanu VSCode jest ustawione na .
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji.
- Aby rozpocząć grę, kliknij dowolną komórkę na planszy agenta.
Mac
- W przypadku Maca musisz skonfigurować odpowiednie uprawnienia, ponieważ aplikacja będzie wysyłać żądania HTTP do backendu. Więcej informacji znajdziesz w artykule Uprawnienia i piaskownica aplikacji.
Dodaj ten kod odpowiednio do step4/frontend/macOS/Runner/DebugProfile.entitlements
i step4/frontend/macOS/Runner/Release.entitlements
:
<key>com.apple.security.network.client</key>
<true/>
- Upewnij się, że urządzenie docelowe na pasku stanu VSCode jest ustawione na .
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji.
- Aby rozpocząć grę, kliknij dowolną komórkę na planszy agenta.
Windows
- Upewnij się, że urządzenie docelowe na pasku stanu VSCode jest ustawione na .
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji.
- Aby rozpocząć grę, kliknij dowolną komórkę na planszy agenta.
12. Krok 6. Włącz aplikację Flutter na platformie internetowej
Możesz też dodać obsługę sieci do aplikacji Flutter. Domyślnie platforma internetowa jest automatycznie włączona dla aplikacji Flutter, więc wystarczy ją uruchomić.
- Upewnij się, że urządzenie docelowe jest ustawione na na pasku stanu VSCode.
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji w przeglądarce Chrome.
- Aby rozpocząć grę, kliknij dowolną komórkę na planszy agenta.
13. Gratulacje
Udało Ci się stworzyć aplikację do gry planszowej z pomocą agenta opartego na ML, w którym możesz zmierzyć się z człowiekiem.