1. Avant de commencer
L'incroyable percée d'AlphaGo et d'AlphaStar a démontré le potentiel du machine learning pour créer des agents de jeu de niveau surhumain. Créer un petit jeu basé sur le ML est un exercice amusant pour acquérir les compétences nécessaires pour créer des agents de jeu puissants.
Dans cet atelier de programmation, vous allez apprendre à créer un jeu de société à l'aide des éléments suivants:
- L'agent TensorFlow pour entraîner un agent de jeu à l'aide de l'apprentissage par renforcement
- TensorFlow Serving pour inférer le modèle
- Flutter pour créer une application de jeu de société multiplate-forme
Prérequis
- Connaissances de base du développement Flutter avec Dart
- Connaissances de base du machine learning avec TensorFlow, telles que l'entraînement par rapport au déploiement
- Vous disposez de connaissances de base sur Python, les terminaux et Docker.
Points abordés
- Entraîner un agent de caractères non-joueurs (NPC) à l'aide d'agents TensorFlow
- Inférer le modèle entraîné à l'aide de TensorFlow Serving
- Créer un jeu de société multiplate-forme Flutter
Prérequis
- SDK Flutter
- Android et iOS configurés pour Flutter
- Ordinateur configuré pour Flutter
- Configuration Web pour Flutter
- Visual Studio Code (VS Code) configuré pour Flutter et Dart
- Docker
- Bash
- Python 3.7 et versions ultérieures
2. Le jeu Plane Strike
Le jeu que vous créez dans cet atelier de programmation s'appelle "Plane Strike", un petit jeu de société à deux joueurs qui ressemble au jeu de société Battleship. Les règles sont très simples:
- Le joueur humain affronte un agent NPC entraîné par le machine learning. Le joueur humain peut lancer le jeu en appuyant sur n'importe quelle cellule du plateau de l'agent.
- Au début du jeu, le joueur humain et l'agent ont chacun un "avion" objet (huit cellules vertes qui forment un "plan", comme vous pouvez le voir sur le plateau du joueur humain dans l'animation ci-dessous) sur leur propre plateau. ces "avions" sont placés au hasard et ne sont visibles que par les propriétaires du plateau et sont masqués pour leurs adversaires.
- Le joueur humain et l'agent frappent à tour de rôle une cellule du plateau de l'autre. Le joueur humain peut appuyer sur n'importe quelle cellule du plateau de l'agent, tandis que l'agent effectue automatiquement un choix en fonction de la prédiction d'un modèle de machine learning. La cellule saisie devient rouge s'il s'agit d'une cellule "avion". cellule ("hit'); sinon il devient jaune ("miss").
- Celui qui atteint 8 cellules rouges en premier gagne la partie. puis le jeu redémarre avec de nouveaux plateaux.
Voici un exemple de gameplay du jeu:
3. Configurer votre environnement de développement Flutter
Pour le développement Flutter, cet atelier de programmation nécessite deux logiciels : le SDK Flutter et un éditeur.
Vous pouvez exécuter l'atelier de programmation sur l'un des appareils suivants :
- Le simulateur iOS (les outils Xcode doivent être installés)
- Android Emulator (à configurer dans Android Studio)
- Un navigateur (Chrome est requis pour le débogage)
- En tant qu'application de bureau Windows, Linux ou macOS. Vous devez développer votre application sur la plate-forme où vous comptez la déployer. Par exemple, si vous voulez développer une application de bureau Windows, vous devez le faire sous Windows pour accéder à la chaîne de compilation appropriée. Les exigences spécifiques aux systèmes d'exploitation sont détaillées sur docs.flutter.dev/desktop.
4. Configuration
Pour télécharger le code de cet atelier de programmation, procédez comme suit :
- Accédez au dépôt GitHub pour cet atelier de programmation.
- Cliquez sur Code > Download ZIP (Code > Télécharger le fichier ZIP) afin de télécharger l'ensemble du code pour cet atelier de programmation.
- Décompressez le fichier ZIP téléchargé pour accéder au dossier racine
codelabs-main
contenant toutes les ressources dont vous avez besoin.
Pour cet atelier de programmation, vous n'avez besoin que des fichiers du sous-répertoire tfagents-flutter/
du dépôt, qui contient plusieurs dossiers:
- Les dossiers
step0
àstep6
contiennent le code de démarrage sur lequel s'appuie chaque étape de cet atelier de programmation. - Le dossier
finished
contient le code final de l'application exemple. - Chaque dossier contient un sous-dossier
backbend
, qui inclut le code backend, et un sous-dossierfrontend
, qui inclut le code de l'interface Flutter
5. Télécharger les dépendances pour le projet
Backend
Ouvrez votre terminal et accédez au sous-dossier tfagents-flutter
. Exécutez la commande suivante :
pip install -r requirements.txt
Interface
- Dans VS Code, cliquez sur File > Ouvrez le dossier, puis sélectionnez le dossier
step0
dans le code source que vous avez téléchargé précédemment. - Ouvrir le fichier
step0/frontend/lib/main.dart
. Si une boîte de dialogue VS Code vous invite à télécharger les packages requis pour l'application de démarrage, cliquez sur Get packages (Télécharger les packages). - Si cette boîte de dialogue ne s'affiche pas, ouvrez votre terminal, puis exécutez la commande
flutter pub get
dans le dossierstep0/frontend
.
6. Étape 0: Exécuter l'application de démarrage
- Ouvrez le fichier
step0/frontend/lib/main.dart
dans VS Code, puis assurez-vous qu'Android Emulator ou le simulateur iOS est correctement configuré et s'affiche dans la barre d'état.
Par exemple, voici ce que vous voyez lorsque vous utilisez le Pixel 5 avec Android Emulator :
Voici ce qui s'affiche lorsque vous utilisez l'iPhone 13 avec le simulateur iOS :
- Cliquez sur l'icône Démarrer le débogage .
Exécuter et explorer l'application
L'application devrait se lancer sur Android Emulator ou le simulateur iOS. L'UI est assez simple. L'établissement possède 2 plates-formes de jeux. un joueur humain peut appuyer sur n'importe quelle cellule du plateau de l'agent en haut pour servir de position de frappe. Vous allez entraîner un agent intelligent à prédire automatiquement où frapper en fonction du plateau du joueur humain.
En arrière-plan, l'application Flutter envoie le plateau actuel du joueur humain au backend, qui exécute un modèle d'apprentissage par renforcement et renvoie une position prédite de cellule à frapper. L'interface affiche le résultat dans l'interface utilisateur après avoir reçu la réponse.
Si vous cliquez sur n'importe quelle cellule du tableau de bord de l'agent, rien ne se passe, car l'application ne peut pas encore communiquer avec le backend.
7. Étape 1: Créez un environnement Python Agents TensorFlow
L'objectif principal de cet atelier de programmation est de concevoir un agent qui apprend en interagissant avec un environnement. Bien que le jeu Plane Strike soit relativement simple et qu'il soit possible de créer manuellement des règles pour l'agent NPC, vous utilisez l'apprentissage par renforcement pour entraîner un agent afin d'acquérir ses compétences et de pouvoir facilement créer des agents pour d'autres jeux à l'avenir.
Avec le paramètre d'apprentissage par renforcement standard, l'agent reçoit une observation à chaque étape et choisit une action. L'action est appliquée à l'environnement, et celui-ci renvoie une récompense ainsi qu'une nouvelle observation. L'agent entraîne une règle pour choisir des actions afin de maximiser la somme des récompenses (ou "retour"). En jouant à ce jeu à de nombreuses reprises, l'agent est capable d'apprendre les schémas et de perfectionner ses compétences pour maîtriser le jeu. Pour formuler le jeu Plane Strike comme un problème d'apprentissage par renforcement, considérez l'état du plateau comme une observation, une position d'attaque comme l'action et le signal de succès/manche comme la récompense.
Pour entraîner l'agent NPC, vous devez utiliser les agents TensorFlow, une bibliothèque d'apprentissage par renforcement fiable, évolutive et facile à utiliser pour TensorFlow.
TF Agents est idéal pour l'apprentissage par renforcement, car il est fourni avec un vaste ensemble d'ateliers de programmation, d'exemples et une documentation complète pour vous aider à démarrer. Vous pouvez utiliser des agents TF pour résoudre des problèmes d'apprentissage par renforcement réalistes et complexes avec évolutivité, et développer rapidement de nouveaux algorithmes d'apprentissage par renforcement. Vous pouvez facilement passer d'un agent et d'un algorithme à un autre pour effectuer des tests. Il a également fait l'objet de tests très efficaces et est facile à configurer.
De nombreux environnements de jeu prédéfinis sont implémentés dans OpenAI Gym (par exemple, Atari), Mujuco, etc., que les agents TF peuvent facilement exploiter. Mais comme le jeu Plane Strike est un jeu personnalisé complet, vous devez d'abord implémenter un nouvel environnement en partant de zéro.
Pour implémenter un environnement Python d'agents TF, vous devez implémenter les méthodes suivantes:
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."""
Le plus important est la fonction _step()
, qui effectue une action et renvoie un nouvel objet time_step
. Dans le cas du jeu Plane Strike, vous disposez d'un plateau de jeu, Lorsqu'une nouvelle position d'attaque arrive, en fonction de l'état du plateau de jeu, l'environnement détermine:
- À quoi le plateau de jeu doit ressembler ensuite (la cellule doit-elle changer de couleur en rouge ou en jaune, étant donné l'emplacement de l'avion caché ?)
- Quelle récompense le joueur doit-il recevoir pour ce poste (récompense de succès ou absence de pénalité ?)
- Le jeu doit-il se terminer (quelqu'un a-t-il gagné ?)
- Ajoutez le code suivant à la fonction
_step()
dans le fichier_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. Étape 2: Entraîner l'agent de jeu avec les agents TensorFlow
Une fois l'environnement TF Agents en place, vous pouvez entraîner l'agent de jeu. Pour cet atelier de programmation, vous allez utiliser un agent REINFORCE. REINFORCE est un algorithme de gradient de règle en RL. Son principe de base est d'ajuster les paramètres du réseau de neurones des règles en fonction des signaux de récompense collectés pendant le jeu, afin que le réseau puisse maximiser le retour sur investissement lors des prochaines parties.
- Tout d'abord, vous devez instancier les environnements d'entraînement et d'évaluation. Ajoutez le code suivant à la fonction
train_agent()
dans le fichierstep2/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)
- Vous devez ensuite créer un agent d'apprentissage par renforcement qui sera entraîné. Dans cet atelier de programmation, vous allez utiliser l'agent REINFORCE, qui est basé sur des règles. Ajoutez ce code juste en dessous du code ci-dessus:
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, )
- Enfin, entraînez l'agent dans la boucle d'entraînement. Dans la boucle, vous commencez par collecter quelques épisodes de parties du jeu dans un tampon, puis vous entraînez l'agent avec les données mises en mémoire tampon. Ajoutez le code suivant à la fonction
train_agent()
dans le fichierstep2/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()
- Vous pouvez maintenant commencer la formation. Dans votre terminal, accédez au dossier
step2/backend
de votre ordinateur et exécutez la commande suivante:
python training.py
L'entraînement prend entre 8 et 12 heures, selon vos configurations matérielles (vous n'avez pas besoin de terminer l'entraînement vous-même, car un modèle pré-entraîné est fourni dans step3
). En attendant, vous pouvez surveiller la progression avec TensorBoard. Ouvrez un nouveau terminal, accédez au dossier step2/backend
de votre ordinateur et exécutez la commande suivante:
tensorboard --logdir tf_agents_log/
tf_agents_log
correspond au dossier qui contient le journal d'entraînement. Voici un exemple d'exécution d'entraînement:
Comme vous pouvez le constater, la durée moyenne de l'épisode diminue et le retour moyen augmente à mesure que l'entraînement progresse. Intuitivement, vous pouvez comprendre que si l'agent est plus intelligent et fait de meilleures prédictions, la durée du jeu diminue et l'agent collecte plus de récompenses. C'est logique, car l'agent souhaite terminer le jeu en moins d'étapes afin de minimiser les remises importantes sur les récompenses lors des étapes suivantes.
Une fois l'entraînement terminé, le modèle entraîné est exporté vers le dossier policy_model
.
9. Étape 3: Déployer le modèle entraîné avec TensorFlow Serving
Maintenant que vous avez entraîné l'agent de jeu, vous pouvez le déployer avec TensorFlow Serving.
- Dans votre terminal, accédez au dossier
step3/backend
de votre ordinateur et démarrez TensorFlow Serving avec 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 commence par télécharger automatiquement l'image TensorFlow Serving, ce qui prend une minute. Le service TensorFlow Serving devrait alors démarrer. Le journal doit se présenter comme cet extrait de code :
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 ...
Vous pouvez envoyer un exemple de requête au point de terminaison pour vous assurer qu'il fonctionne comme prévu:
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
Le point de terminaison renvoie une position prédite 45
, qui est (5, 5) au centre du plateau (pour les plus curieux, vous pouvez essayer de comprendre pourquoi le centre de la grille est une bonne estimation de la position du premier coup).
{ "predictions": [45] }
Et voilà ! Vous venez de créer un backend afin de prédire la position d'avertissement suivante pour l'agent NPC.
10. Étape 4: Créez l'application Flutter pour Android et iOS
Le backend est prêt. Vous pouvez commencer à lui envoyer des demandes pour récupérer des prédictions de position d'avertissement à partir de l'application Flutter.
- Tout d'abord, vous devez définir une classe qui encapsule les entrées à envoyer. Ajoutez le code suivant au fichier
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; } }
Vous pouvez maintenant envoyer la requête à TensorFlow Serving pour effectuer des prédictions.
- Ajoutez le code suivant à la fonction
predict()
dans le fichierstep4/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'); }
Une fois que l'application a reçu la réponse du backend, mettez à jour l'interface utilisateur du jeu pour refléter la progression dans le jeu.
- Ajoutez le code suivant à la fonction
_gridItemTapped()
dans le fichierstep4/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(() {});
Exécuter le code
- Cliquez sur l'icône Démarrer le débogage , puis attendez que l'application se charge.
- Appuyez sur n'importe quelle cellule du plateau de l'agent pour lancer le jeu.
11. Étape 5: Activez l'application Flutter pour les plates-formes de bureau
En plus d'Android et d'iOS, Flutter est également compatible avec les plates-formes de bureau, y compris Linux, Mac et Windows.
Linux
- Assurez-vous que l'appareil cible est défini sur dans la barre d'état de VSCode.
- Cliquez sur l'icône Démarrer le débogage , puis attendez que l'application se charge.
- Cliquez sur n'importe quelle cellule du plateau de l'agent pour lancer le jeu.
Mac
- Sous Mac, vous devez configurer les droits d'accès appropriés, car l'application enverra des requêtes HTTP au backend. Pour en savoir plus, consultez Droits d'accès et bac à sable de l'application.
Ajoutez ce code à step4/frontend/macOS/Runner/DebugProfile.entitlements
et step4/frontend/macOS/Runner/Release.entitlements
respectivement:
<key>com.apple.security.network.client</key>
<true/>
- Assurez-vous que l'appareil cible est défini sur dans la barre d'état de VSCode.
- Cliquez sur l'icône Démarrer le débogage , puis attendez que l'application se charge.
- Cliquez sur n'importe quelle cellule du plateau de l'agent pour lancer le jeu.
Windows
- Assurez-vous que l'appareil cible est défini sur dans la barre d'état de VSCode.
- Cliquez sur l'icône Démarrer le débogage , puis attendez que l'application se charge.
- Cliquez sur n'importe quelle cellule du plateau de l'agent pour lancer le jeu.
12. Étape 6: Activez l'application Flutter pour la plate-forme Web
Vous pouvez également ajouter la compatibilité Web à l'application Flutter. Par défaut, la plate-forme Web est automatiquement activée pour les applications Flutter. Il vous suffit donc de la lancer.
- Assurez-vous que l'appareil cible est défini sur dans la barre d'état de VSCode.
- Cliquez sur Démarrer le débogage, puis attendez que l'application se charge dans le navigateur Chrome.
- Cliquez sur n'importe quelle cellule du plateau de l'agent pour lancer le jeu.
13. Félicitations
Vous avez créé une application de jeu de société avec un agent basé sur le ML pour jouer contre le joueur humain.