Création d'un jeu de tic-tac-toe. Fondements théoriques du développement

Salutations, chers amis ! Dans cette leçon, je vais montrer comment créer un jeu par navigateur - tic-tac-toe, en javascript ! Vous savez tous ce qu'est ce jeu et comment y jouer, mais permettez-moi de vous le rappeler :

Le tic-tac-toe est un jeu logique entre deux joueurs sur un terrain carré de 3 cases sur 3 (éventuellement plus grand). L'un joue avec les « croix », l'autre avec les « orteils ».

P.S. comme dans toutes les leçons javascript similaires, à la fin de l'article vous pouvez télécharger le fichier source, et également voir le résultat du travail dans un exemple de démonstration !

Description du jeu en cours de création

Regardons les fonctionnalités du jeu :

  • le jeu démarre immédiatement après le chargement de la page ;
  • le droit de passer en premier est choisi au hasard (soit vous commencez à marcher, soit l'ordinateur) ;
  • le signe que vous miserez est choisi au hasard (une croix ou un zéro) ;
  • si le joueur gagne, les symboles gagnants (une bande de croix ou de zéros) sont surlignés en vert ;
  • si le joueur perd face à l'ordinateur, la barre est surlignée en rouge ;
  • Au dessus du champ se trouve une ligne d'information où est affiché le résultat (victoire ou défaite).

Logiques

Je n'ai pas proposé d'algorithmes complexes (universels) pour un terrain de jeu carré de 3 x 3, j'ai fait l'inverse : la force brute ! (nous en reparlerons un peu plus tard). J’ai identifié trois grandes étapes séquentielles sur lesquelles repose toute la logique :

Étape 1 : vérifier si le joueur a gagné ?

A ce stade, on vérifie s'il y a 3 cellules (sur la même ligne) remplies des mêmes symboles joueurs (croix ou zéros). Ceux. quel que soit le coup (même le premier), nous vérifions toujours d'abord si le joueur a gagné. Voici à quoi ressemble la victoire :

Étape 2 : vérification : l'ordinateur peut-il gagner au prochain coup ?

À ce stade, nous recherchons une ligne où il y aurait 2 cellules remplies par l'ordinateur et une cellule vide - c'est-à-dire que nous essayons de gagner en raison de l'inattention du joueur. Voici à quoi ressemble une défaite (c’est-à-dire une victoire informatique) :

Étape 3 : on ne vous laisse pas gagner !

Ici, nous recherchons la même ligne que dans la deuxième étape, seules 2 cellules doivent être remplies avec les signes de jeu du joueur, c'est-à-dire qu'à ce stade nous ne permettons pas à l'ordinateur de perdre en plaçant un signe dans une cellule vide. Chacune des étapes représente une fonction indépendante - vous pouvez le voir dans le code js ci-dessous.

Mise en œuvre

La disposition du terrain de jeu est très simple - le bloc principal contient une ligne d'informations (classe - résultat) et 9 blocs, qui sont des cellules (classe - bloc) Disposition HTML des cellules :

À ton tour!

La cellule de classe auxiliaire est nécessaire pour identifier avec précision la cellule souhaitée sur le terrain de jeu. Styles CSS pour le terrain de jeu :

Krestiki_noliki( largeur : 306px ; marge : 0 auto ; ) .krestiki_noliki .block( largeur : 100px ; hauteur : 100px ; bordure : 1px solide #ccc ; curseur : pointeur ; flotteur : gauche ; alignement du texte : centre ; taille de police : 100px ; hauteur de ligne : 94px ; )

Examinons maintenant l'intégralité du code JS, après quoi je parlerai des points principaux :

$(document).ready(function())( var znak_user = "O"; var znak_comp = "X"; var rand_num = Math.round((Math.random() * (9 - 1) + 1)); if (rand_num > 3)( var znak_comp = "O"; var znak_user = "X"; $(".cell"+rand_num).text(znak_comp); ) var exit_flag = false; var win_user_array = ["123", " 456","789","147","258","369","159","357"]; //Déterminer la fonction de victoire du joueur check_3_user(znak)( for (var i = 0; i< 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first+",."+second+",."+third).css("background-color", "#83e2c3"); $(".result").text("Вы выиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем возможность победы компьютера function check_2_comp(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == "" && exit_flag == false){ $("."+third).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak && exit_flag == false){ $("."+second).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak && exit_flag == false){ $("."+first).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем ход компьютера function check_2_user(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == ""){ $("."+third).text(znak_comp); exit_flag = true; } } if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak){ $("."+second).text(znak_comp); exit_flag = true; } } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first).text(znak_comp); exit_flag = true; } if(exit_flag) break; } } $(".krestiki_noliki .block").click(function(){ //Если клетка пустая if($(this).text() == ""){ $(this).text(znak_user); check_3_user(znak_user); check_2_comp(znak_comp); check_2_user(znak_user); if(exit_flag == false){ for (var i = 1; i < 10; i++) { if($(".cell"+i).text() == ""){ $(".cell"+i).text(znak_comp); break; } } }else exit_flag = false; } }); });

Tout d'abord, nous déclarons les variables : znak_user - dans cette variable nous stockons le signe avec lequel l'utilisateur va jouer (par défaut, un zéro y est stocké - c'est la case anglaise "O"). znak_comp - dans cette variable nous stockons le signe avec lequel l'ordinateur va jouer (par défaut, une croix y est stockée - c'est la case anglaise "X").

La logique est la suivante : si le nombre aléatoire est supérieur à 3, alors l'ordinateur joue avec des zéros et il (l'ordinateur) fait le premier pas.

Vous pouvez modifier cette logique à votre guise, par exemple, vous pouvez créer plusieurs nombres aléatoires afin de proposer plus d'options pour savoir qui sera le premier et quels signes. exit_flag - ce drapeau (variable) est responsable de la sortie de la fonction, c'est-à-dire, par exemple, lorsque l'ordinateur a déjà effectué son mouvement et que vous devez quitter la fonction et transmettre le mouvement au joueur. win_user_array - ce tableau stocke toutes les options gagnantes pour remplir les cellules. Pour que ce soit clair, regardons cette image :

Chaque élément du tableau est une chaîne de trois nombres, qui constitue une combinaison gagnante, c'est-à-dire, par exemple, si vous remplissez les cellules sous les nombres 1, 2 et 3, alors la victoire (ou la défaite) se produira. Comme vous pouvez le voir, il y a 8 options gagnantes au total ; notre tâche est de parcourir toutes ces options. Viennent ensuite 3 fonctions :

  1. check_3_user();
  2. check_2_comp();
  3. check_2_user();

Le but de ces fonctions est décrit (en trois étapes) dans la section Logique (ci-dessus). Ces fonctions sont appelées en cliquant sur l'une des cellules du champ. Un paramètre (znak) est transmis à chacune des fonctions - c'est le signe du joueur ou de l'ordinateur (une croix ou un zéro), par exemple, à la fonction qui détermine la victoire du joueur (check_3_user), on passe le signe du joueur dans l'ordre trouver 3 signes identiques sur une même ligne.

Après trois fonctions (si l'ordinateur n'a pas encore effectué de mouvement), l'ordinateur remplit l'une des cellules libres. Ici, vous pouvez compliquer le jeu, par exemple, en faisant en sorte que si la cellule centrale est libre (cellule numéro 5), alors pariez d'abord dessus ; si elle est occupée, alors pariez dans l'un des coins libres (ce sont cellules n°1, 3, 7 et 9) et ainsi de suite - en général, ici c'est à votre discrétion.

C’est en principe tout ce qui est nécessaire pour créer un tel jeu.

Vous pouvez maintenant regarder le jeu en utilisant un exemple de démonstration et télécharger le fichier source (1 fichier au total).

08/06/2018 - merci pour votre attention à l'auteur de la lettre : Patvakan Baghdasaryan, un bug a été corrigé lorsque l'ordinateur en avait plusieurs options possibles les victoires et tous ses coups gagnants ont été repeints (de 4 à 6 cases, au lieu de 3).

C'est tout pour moi, j'espère que cette leçon vous a été utile, je vous souhaite bonne chance, au revoir !

Comment écrire un bot qui ne peut pas être battu au tic-tac-toe, ou Introduction à la règle minimax

Il est fort possible qu'après des centaines de parties de tic-tac-toe, vous vous soyez demandé : quel est l'algorithme optimal ? Mais si vous êtes ici, alors vous avez probablement aussi essayé d'écrire une implémentation de ce jeu. Nous irons plus loin et écrirons un bot qui sera impossible à battre au tic-tac-toe. Anticipant votre question « pourquoi ? », nous répondrons : grâce à l’algorithme.

Comme un joueur d'échecs professionnel, cet algorithme calcule les actions de l'adversaire plusieurs coups à l'avance - jusqu'à la fin de la partie, qu'il s'agisse d'une victoire, d'une défaite ou d'un match nul. Une fois dans cet état final, l'IA s'attribuera un nombre de points positif (dans notre cas +10) pour une victoire, négatif (-10) pour une défaite, et neutre (0) pour un match nul.

Dans le même temps, l’algorithme effectue des calculs similaires pour les mouvements du joueur. Il choisira le coup avec le score le plus élevé si l'IA bouge, et le coup avec le score le plus bas si le joueur bouge. En utilisant cette stratégie, minimax évite la défaite.

Essayez de jouer à ce jeu.

L'algorithme minimax est plus facilement décrit comme une fonction récursive qui :

  1. renvoie une valeur si l'état final est trouvé (+10, 0, -10),
  2. parcourt toutes les cellules vides du terrain,
  3. appelle la fonction minimax pour chacun d'eux (récursion),
  4. évalue les valeurs obtenues
  5. et renvoie le meilleur.

Si vous n'êtes pas familier avec la récursivité, vous devriez regarder cette conférence du cours Harvard CS50 :

Pour comprendre le fonctionnement de minimax, écrivons son implémentation et modélisons son comportement. Nous traiterons de cela dans les deux prochaines sections.

Implémentation Minimax

Nous examinerons une situation où le jeu touche à sa fin (voir image ci-dessous). Étant donné que minimax parcourt tous les états de jeu possibles (et il y en a des centaines de milliers), il est logique de considérer la fin du jeu - de cette façon, nous devrons suivre un plus petit nombre d'appels de fonctions récursifs (9 au total).

Laissez l'IA jouer avec les croix, la personne - avec les zéros.

Pour faciliter le travail avec le champ, déclarons-le comme un tableau de 9 éléments avec des valeurs égales au contenu des cellules. Remplissons-le de croix et d'orteils, comme dans l'image ci-dessus, et appelons-le origBoard.

Var origBoard = ["O",1,"X","X",4,"X",6,"O","O"];

Ensuite, nous déclarerons les variables aiPlayer et huPlayer et leur attribuerons respectivement les valeurs "X" et "O".

De plus, nous aurons besoin d'une fonction qui recherche les combinaisons gagnantes et renvoie une vraie valeur si la recherche réussit, ainsi que d'une fonction qui stocke les indices des cellules disponibles.

/* Etat initial planches O | | X --------- X | | X --------- | Ô | O */ var origBoard = ["O",1 ,"X", "X",4 ,"X", 6 ,"O", "O"] ; // personne var huPlayer = « O » ; // AI var aiPlayer = « X » ; // renvoie une liste d'indices de cellules vides sur le tableau function emptyIndices(board)( return board.filter(s => s != "O" && s != "X"); ) // combinaisons gagnantes prenant en compte fonction d'indices gagnant(board, joueur)( if((board == joueur && board == joueur && board == joueur) || (board == joueur && board == joueur && board == joueur) || (board = = joueur && tableau == joueur && tableau == joueur) || (plateau == joueur && tableau == joueur && tableau == joueur) || (plateau == joueur && tableau == joueur && tableau == joueur) | | (tableau == joueur && tableau == joueur && tableau == joueur) || (tableau == joueur && tableau == joueur && tableau == joueur) || (plateau == joueur && tableau == joueur && tableau = = joueur)) ( return true; ) else ( return false; ) )

Définissons donc une fonction minimax avec deux arguments : newBoard et player. Ensuite nous retrouverons les indices des cellules libres sur le champ et les transmettrons à la variableavaSpots.

// fonction minimax principale function minimax(newBoard, player)( // cellules disponibles varavaSpots = emptyIndices(newBoard);

De plus, nous devons garder une trace des états finaux et renvoyer les valeurs appropriées. Si le "zéro" gagne, vous devez rendre -10, si le "croix" - +10. Si la taille du tableauavailSpots est nulle, alors il n'y a pas de cellules libres, le jeu se terminera par un match nul et zéro devra être renvoyé.

// vérifie l'état du terminal (gagnant/perdu/nul) // et renvoie une valeur en conséquence if (winner(newBoard, huPlayer))( return (score:-10); ) else if (winner(newBoard, aiPlayer)) ( return (score: 10); ) else if (availSpots.length === 0)( return (score: 0); )

Après cela, vous devez collecter des points dans chacune des cellules vides. Pour ce faire, nous allons créer un tableau de mouvements et parcourir toutes les cellules vides dans une boucle, en plaçant les indices et les points de chaque mouvement dans l'objet de déplacement.

Ensuite, nous définissons l'index de la cellule vide, qui a été stockée sous forme de nombre dans origBoard, égal à la propriété index de l'objet de déplacement. Ensuite, en tant que joueur actuel, nous irons dans une cellule vide du nouveau champ newBoard et appellerons la fonction minimax de l'autre joueur et le champ résultant newBoard . Après cela, vous devez mettre la propriété score de l'objet renvoyé par la fonction minimax dans la propriété score de l'objet de déplacement.

Si minimax ne trouve pas d'état terminal, il continue à avancer récursivement plus profondément dans le jeu jusqu'à ce qu'il atteigne un état terminal. Après cela, il transfère les points de ce « niveau » de récursion vers un niveau supérieur.

Enfin, la fonction réinitialise les modifications apportées à newBoard et place l'objet de déplacement dans le tableau des mouvements.

// tableau pour stocker tous les objets var move = ; // parcourt les cellules disponibles pour (var i = 0; i< availSpots.length; i++){ //create an object for each and store the index of that spot var move = {}; move.index = newBoard]; // совершить ход за текущего игрока newBoard] = player; //получить очки, заработанные после вызова минимакса от противника текущего игрока if (player == aiPlayer){ var result = minimax(newBoard, huPlayer); move.score = result.score; } else{ var result = minimax(newBoard, aiPlayer); move.score = result.score; } // очистить клетку newBoard] = move.index; // положить объект в массив moves.push(move); }

Minimax doit ensuite sélectionner le meilleur coup parmi le tableau des mouvements. Il a besoin du coup avec le score le plus élevé si l'IA se déplace, et avec le score le plus bas s'il s'agit d'un mouvement humain. Ainsi, si la valeur de player est aiPlayer , l'algorithme initialise la variable bestScore à un très petit nombre et parcourt le tableau des mouvements : si le score d'un coup vaut plus que bestScore , l'algorithme se souvient de ce coup . Dans le cas de coups avec égalité de points, l’algorithme mémorise le premier.

Dans le cas où player est égal à huPlayer , tout est similaire - seulement maintenant, bestScore est initialisé à un grand nombre et minimax recherche le coup avec le moins de points.

En conséquence, minimax renvoie l'objet stocké dans bestMove .

// s'il s'agit d'un mouvement de l'IA, parcourez les mouvements et sélectionnez le mouvement avec le plus de points var bestMove; if(player === aiPlayer)( var bestScore = -10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score >bestScore)( bestScore = move[i].score; bestMove = i; ) ) )else( // sinon parcourez les mouvements et sélectionnez le mouvement avec le moins de points var bestScore = 10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score < bestScore){ bestScore = moves[i].score; bestMove = i; } } } // вернуть выбранный ход (объект) из массива ходов return moves; }

Dans la section suivante, nous simulerons notre programme pour comprendre son fonctionnement.

Minimax en action

À l'aide du schéma ci-dessous, nous analyserons le modèle étape par étape de l'algorithme.

Note: Dans le diagramme, les grands nombres indiquent le numéro de série de l'appel de fonction, et les niveaux indiquent le nombre de mouvements effectués par l'algorithme.

  1. L'origBoard et l'aiPlayer sont transmis à l'algorithme. Il dresse une liste des trois cellules vides trouvées, vérifie la finitude de l'état et parcourt toutes les cellules vides. L'algorithme change ensuite newBoard , plaçant aiPlayer dans le premier carré vide. Après cela, il s'appelle depuis newBoard et huPlayer et attend le deuxième appel pour renvoyer une valeur.
  2. Pendant que le premier appel de fonction est toujours en cours d'exécution, le second s'exécute, créant une liste de deux cellules vides, vérifiant l'état fini et parcourant toutes les cellules vides. Le deuxième appel modifie ensuite newBoard en plaçant huPlayer dans la première case vide. Après cela, il s'appelle depuis newBoard et aiPlayer et attend le troisième appel pour renvoyer une valeur.

  3. Étant donné que le deuxième appel a trouvé deux cellules vides, minimax modifie newBoard en plaçant huPlayer dans la deuxième cellule vide. Il s'appelle ensuite depuis newBoard et aiPlayer.

  4. L'algorithme compile une liste de cellules vides et enregistre la victoire du joueur après avoir vérifié la finitude de l'état. Il renvoie donc un objet avec un champ de score de (-10).

    Lors du deuxième appel de fonction, l'algorithme reçoit les valeurs renvoyées par le niveau inférieur par les troisième et quatrième appels de fonction. Puisque le mouvement de huPlayer a produit ces deux résultats, l'algorithme choisit le plus petit. Puisqu'ils sont identiques, l'algorithme choisit le premier et le transmet au premier appel de fonction.

    À ce stade, le premier appel de fonction a reçu une estimation du déplacement d'aiPlayer vers la première cellule vide. Il modifie ensuite newBoard en plaçant aiPlayer dans la deuxième case vide. Après cela, il s'appelle depuis newBoard et huPlayer.

  5. Dans le cinquième appel de fonction, l'algorithme compile une liste de cellules vides et enregistre la victoire de l'IA après avoir vérifié la finitude de l'état. Il renvoie donc un objet avec un champ de score de +10.

    Après cela, le premier appel modifie newBoard en plaçant aiPlayer dans la troisième cellule vide. Il s'appelle ensuite depuis newBoard et huPlayer.

  6. Le sixième appel crée une liste de deux cellules vides, vérifie la finitude de l'état et parcourt toutes les cellules vides. Il modifie ensuite newBoard en plaçant huPlayer dans la première case vide. Ensuite, il s'appelle depuis newBoard et aiPlayer et attend le septième appel pour renvoyer une valeur.
  7. Le nouvel appel construit une liste d'une cellule vide, vérifie l'état fini et modifie newBoard pour placer aiPlayer dans la cellule vide. Après cela, il s'appelle depuis newBoard et huPlayer et attend que cet appel renvoie une valeur.
  8. Le huitième défi est liste vide cellules vides et enregistre la victoire d'aiPlayer après avoir vérifié l'état des membres. Par conséquent, il renvoie un objet avec un champ de comptage égal à (+10) au niveau supérieur, le septième appel.

    Le septième appel n’a reçu qu’une seule valeur positive des niveaux inférieurs. Puisque cette valeur a été obtenue pendant le tour d'aiPlayer, l'algorithme renvoie la plus grande valeur obtenue. Il renvoie donc une valeur positive (+10) au niveau supérieur, au sixième appel.

    Étant donné que le sixième appel a trouvé deux cellules vides, minimax modifie newBoard en plaçant huPlayer dans la deuxième cellule vide. Il s'appelle ensuite depuis newBoard et aiPlayer.

  9. Après cela, l'algorithme compile une liste de cellules vides et enregistre la victoire d'aiPlayer après avoir vérifié la finitude de l'état. Par conséquent, il renvoie un objet avec un champ de score égal à (+10) au niveau supérieur.

    À ce stade, le sixième défi doit choisir entre le score (+10) renvoyé par le septième défi et le score (-10) renvoyé par le neuvième défi. Puisque le mouvement de huPlayer a produit ces deux résultats, l'algorithme sélectionne le plus petit et le renvoie au niveau suivant en tant qu'objet avec des champs de score et d'index.

    Enfin, les trois branches du premier appel sont évaluées (-10, +10, -10). Puisque le mouvement d'aiPlayer a produit ces trois résultats, l'algorithme sélectionne l'objet contenant le score le plus élevé (+10) et son indice (4).

Dans le scénario ci-dessus, minimax décide que choix optimal il y aura un déplacement vers la place centrale du terrain.

Fin!

Vous devriez maintenant avoir compris comment fonctionne l’algorithme minimax. Essayez d'écrire une implémentation vous-même, ou regardez un exemple sur GitHub ou CodePen et optimisez-la.

Si vous êtes intéressé par le sujet de l'IA dans les jeux, nous vous recommandons de lire nos documents sur ce sujet.

ÉTAPE 1. CONFIGURATION DES PARAMÈTRES DU FORMULAIRE1. Pour personnaliser un formulaire, définissez sa taille
510 points horizontalement et 480 points horizontalement
verticale. Maximum et minimum
indiquer la taille égale aux mêmes valeurs.
2. Nommez la forme « Tic Tac Toe ».
3. Pour l'arrière-plan du formulaire, utilisez un fichier du dossier
Images sous le nom background.png, et placez-le
au centre du formulaire.
4. Pour une icône dans la ligne de titre
utiliser utiliser le fichier du dossier
Images sous le nom menu4.ico.
5. La couleur de fond du formulaire doit être définie
Crème à la Menthe.

ÉTAPE 2. AJOUT D'UN BOUTON ET D'UNE ÉTIQUETTE AU FORMULAIRE

1. Pour les éléments placés, modifiez
taille de police à 12 et jeu d'arrière-plan
transparent.

1. Créez une barre de menus avec des éléments dans
comme le montre l'image.

ÉTAPE 3. AJOUT D'UNE BARRE DE MENU AU FORMULAIRE

1. Dans l'élément de menu Fichier, créez une commande
Sortie.
2. Pour
équipes
Sortie
prescrivons
le code du programme est le même que dans
demande précédente.

ÉTAPE 3. AJOUT D'UNE BARRE DE MENU AU FORMULAIRE

1. Dans l'élément de menu Jeu, créez une équipe
Un nouveau jeu.
2. Pour la commande Nouveau jeu nous écrirons
code de programme dans le futur via
quelques pas.

ÉTAPE 3. AJOUT D'UNE BARRE DE MENU AU FORMULAIRE

1. Dans l'élément de menu Aide, créez une commande
À propos du programme.
2. Pour la commande À propos du programme, créez-en une nouvelle.
former et écrire le code du programme
semblable au précédent
application.

1. En faisant glisser un objet PictureBox sur le formulaire
changez sa taille en 100x100.
2. Définissez un arrière-plan transparent.
3. Placez la PictureBox comme indiqué dans
image au-dessus de la première cellule du terrain de jeu.

ÉTAPE 4. AJOUT D'OBJETS PICTUREBOX AU FORMULAIRE

1
2
3
4
5
6
7
8
9
1. Au-dessus des cellules restantes, nous plaçons
Objets PictureBox, copies du premier
objet, selon la numérotation indiquée sur
Images.

1. Avant d'écrire du code
nécessaire dans le dossier
\Visual Studio
2010\Projets\Tic Tac Toe\X's
zeros\bin\Debug\ doit être relancé
fichiers x.png, 0.png, none.png du dossier Images.
2. Double-cliquez avec le bouton gauche de la souris sur le premier
Boîte d'image.

ÉTAPE 5. AJOUT DE CODE POUR LES OBJETS PICTUREBOX

1. Créez un tableau bidimensionnel accessible à tous les éléments de
créé sous la forme d'éléments 3x3 constitués d'entiers. Tout de suite
nous le remplissons de zéros lors de sa déclaration. Pour les cellules vides, nous
Nous utiliserons 0, pour les « croix » - 1 et pour les « zéros » - -1.

ÉTAPE 5. AJOUT DE CODE POUR LES OBJETS PICTUREBOX

Dans la procédure lorsque vous cliquez sur le premier
PictureBox, ajouter un opérateur
choix
lequel
volonté
vérifier l'état
cellules du tableau. Si la valeur
les cellules du tableau seront égales à 0, ce qui
cela veut dire qu’il n’y a ni « zéro » ni
"croix", puis dans cette cellule
le tableau est écrit 1 et dans
ImageBox1
affiché
image d'une "croix", et si
la valeur de la cellule du tableau sera
est égal à 1 alors il contient
"croix" et 0 y est écrit, et
Une cellule vide s'affiche.

ÉTAPE 5. AJOUT DE CODE POUR LES OBJETS PICTUREBOX

1
2
3
4
5
6
7
8
9



Pour les cellules restantes du champ, ajoutez le code
pareil que dans le premier, mais en changeant
Numéro d'objet PictureBox et adresse de cellule
tableau.
EXEMPLE pour la deuxième cellule :

Dans la procédure lorsque vous cliquez sur un bouton
ajouter
opérateur
faire du vélo
qui vérifie
toutes les cellules, de la première à
présence de cellules vides. Et si
la cellule est vide,
puis en elle
« zéro » est écrit, à savoir en
la cellule du tableau s'écrit -1.
Pour plus de commodité dans les travaux futurs
variables
JE,
j
lequel
utilisé pour parcourir des boucles
Nous l'annoncerons pour l'ensemble du formulaire.

ÉTAPE 6. AJOUT DE CODE POUR LE BOUTON DE MARCHE

Pour afficher des zéros sur
jeu
champ
nécessaire
ajouter le code du programme au corps
cycle de vérification du vide des cellules.
Utiliser une instruction imbriquée
ramification
volonté
prend place
analyse de l'adresse des cellules du tableau pour
sortie zéro dans le bon sens
Boîte d'image.
Nous ajoutons également une instruction break
pour une fin prématurée
boucle en trouvant vide
cellules.

ÉTAPE 6. AJOUT DE CODE POUR LE BOUTON DE MARCHE

Pour indiquer l'état du jeu
l'élément d'interface est utilisé
Étiquette1. Puisque le joueur bouge toujours
d'abord
Que
à
téléchargements
applications
nécessaire
V
élément
Étiquette1
nécessaire
refléter
phrases « Votre
se déplacer."
Pour
ce
créons
variable
répondre
lequel
Attribuons cette phrase. UN
lors du chargement du formulaire une variable
doit être affecté à l'élément
Label1, pour créer le nécessaire
procédures
nécessaire
double-cliquez d'abord
selon la forme

ÉTAPE 7. AJOUT DU CODE DE PROGRAMME POUR LE NOUVEL ÉLÉMENT DE MENU DE JEU

Lorsqu'on appuie sur la commande nouveau
le jeu sera réinitialisé
toutes les cellules du tableau, en remplaçant toutes
"croix" et "orteils" sur
cellules vides. Aussi la conclusion
Panneaux « Votre déménagement »

ÉTAPE 8. SORTIR LE RÉSULTAT DU JEU

Pour vérifier les résultats des mouvements
nécessaire
analyser
contenu des lignes, des colonnes et
diagonales. Si les trois éléments
sont égaux à 1, alors c'est une victoire pour le joueur, et
si trois -1 alors c'est une défaite
joueur.
Chèque de victoire obligatoire
conduire
avant
progrès
ordinateur,
UN
vérifier
défaite après.
La dernière commande de la procédure
les résultats seront affichés à l'écran
progrès.

ÉTAPE 8. SORTIR LE RÉSULTAT DU JEU

Code du programme pour vérifier la victoire de l'utilisateur :
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Vous gagnez";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Vous gagnez";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Vous gagnez";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Vous gagnez";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Vous gagnez";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Vous gagnez";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Vous gagnez";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Vous gagnez";
Code du programme pour vérifier la victoire de l'utilisateur :
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Tu as perdu";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Tu as perdu";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Tu as perdu";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Tu as perdu";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Tu as perdu";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Tu as perdu";
label1.Text = réponse ;

ÉTAPE 9 AMÉLIORER LA JOUABILITÉ

Pour améliorer la jouabilité
au lieu d'une sortie série
aux premiers vides
cellules de « zéros », on implémente
sortie via un générateur aléatoire
Nombres.
Pour ce faire, vous devez ajouter
une variable logique
uslovie, et changez le type de boucle de For
sur While, puisqu'on ne sait pas
nombre exact de répétitions
Générateur nombres aléatoires Au revoir
il ne tombera pas dans une cellule vide.

MINISTÈRE DE L'ÉDUCATION ET DES SCIENCES DE RUSSIE

établissement d'enseignement budgétaire de l'État fédéral d'enseignement professionnel supérieur

"Université d'État de Vologda"

Département d'automatisation et de génie informatique

Note explicative du projet de cours dans la discipline

Bases de programmation et d'algorithmique

"Tic Tac Toe"

Complétéétudiant du groupe EM-21

Butorova L. Yu.

Accepté Rzheutskaya S. Yu.

INTRODUCTION

1. ANALYSE DU PROBLÈME ET DÉTERMINATION DES EXIGENCES DU PROGRAMME À DÉVELOPPER

1 Objectif du programme, ses utilisateurs, principales fonctions et objectifs poursuivis au cours du développement

2 Examen des programmes bien connus qui remplissent des fonctions similaires

3 Base théorique du développement

4 Sélection des outils de développement

CONCEPTION PARTIE DU DÉVELOPPEMENT

1 Développement de l'interface utilisateur

2.2 Développement des structures de données (en externe et RAM)

2.3 Développement et analyse d'algorithmes

IMPLÉMENTATION DU PROGRAMME EN LANGAGE C++

1 Architecture du programme

2 Sélection des composants visuels et non visuels standards

RÉSULTATS DE TEST

CONCLUSION

Bibliographie

Applications

INTRODUCTION

Le tic-tac-toe est un jeu logique entre deux adversaires sur un terrain carré de 3 cases sur 3 ou plus (jusqu'à un « champ sans fin »). L'un des joueurs joue avec des "croix", le second - avec des "orteils". Ce jeu est devenu populaire bien avant l’avènement des ordinateurs, seulement avant qu’on y joue avec une simple feuille de papier et un stylo. Le jeu traditionnel chinois utilise des pierres noires et blanches.

Dans ce travail de cours Les règles de base et la taille standard du terrain de jeu (3x3 cellules) sont conservées. Pour la commodité du jeu, le droit de faire le premier coup est laissé à l'utilisateur, c'est-à-dire les « croix ».

Tic Tac Toe est un programme conçu pour divertir l'utilisateur, c'est pourquoi son interface, dans ce cours, est réalisée dans un style de jeu avec une combinaison de couleurs positives qui renforcent la partie émotionnelle du processus de jeu.

Il existe trois types dans le jeu : X contre 0 - utilisateur contre utilisateur, « 1er niveau avec un ordinateur » - pour ceux qui apprennent juste les bases du jeu mondial, et le niveau « 2ème niveau avec un ordinateur » - pour ceux qui sont absolument confiants dans leur victoire. Aux niveaux 1 et 2, il y a trois résultats possibles : « gagner », « perdre » et « nul ». Les gains sont fixes si les lignes verticales, horizontales ou diagonales sont entièrement remplies de croix ou de zéros.

Si les cellules libres du terrain sont épuisées, mais que personne ne gagne, alors le jeu est considéré comme se terminant par un « nul ».

1. ANALYSE DU PROBLÈME ET DÉTERMINATION DES EXIGENCES DU PROGRAMME À DÉVELOPPER

interface croisée du programme

1.1 Objectif du programme, ses utilisateurs, principales fonctions et objectifs poursuivis au cours du développement

Le but de ce programme est avant tout de divertir les utilisateurs, d'égayer le temps d'attente d'une personne, car tout travail nécessite du repos, et ce jeu simple vous aidera à vous détendre et à vous distraire des affaires quotidiennes. "Tic Tac Toe" appartient également à la classe des jeux intellectuels et logiques, conçus pour entraîner la pensée logique, permettre de concentrer l'attention et de développer la mémoire.

Le public cible des utilisateurs est constitué d’enfants et d’adolescents, ainsi que d’adultes. Les principaux critères d'utilisation du produit sont la capacité de lire le texte écrit dans le programme et la possibilité de sélectionner la tâche nécessaire pour l'ordinateur à l'aide de boutons.

De là, nous pouvons conclure que les tâches principales sont : la tâche de divertissement et la tâche de développement du potentiel logique d’une personne.

1.2 Examen des programmes bien connus qui remplissent des fonctions similaires

Sur Internet, vous pouvez trouver un grand nombre d'ouvrages mettant en œuvre ce jeu. Actuellement, il existe de nombreux analogues de ce jeu qui s'écartent des normes d'origine. Un exemple de tels programmes est « Tic-tac-toe sur un champ sans fin » et « Tic-tac-toe 3D ». De plus, dans de nombreux jeux, les « croix » et les « orteils » sont remplacés par d'autres symboles, comme par exemple les « pierres ».

Mon projet de cours est une application PC. Le jeu est destiné à la fois à un utilisateur dont l'adversaire est une intelligence artificielle (ou un ordinateur) et à deux utilisateurs. Il est présenté sur un terrain classique 3x3.

Le plus intéressant et inhabituel, à mon avis, était le jeu « Tic Tac Toe 3D ». C'est pourquoi je l'ai choisi pour comparaison.

Le tic-tac-toe 3D est bien plus intéressant que sur papier ou sur un tableau ordinaire. Il y a plus d’opportunités de gagner et de perdre, et les nuls sont moins fréquents. Vous pouvez jouer seul - contre l'ordinateur - ou avec un ami. Et le plus insolite ici, c'est que pour gagner, vous pouvez faire une combinaison de trois boules de votre couleur (noire ou blanche) non seulement sur n'importe quel niveau, mais aussi le long du plan des murs et même en diagonale sur tout le terrain ( Fig.1.1).

Riz. 1.1

Parmi la grande variété de jeux sur un sujet similaire, on peut souligner dans chaque œuvre une mise en œuvre unique du plan. Chaque projet se distingue des autres par son individualité.

1.3 Base théorique du développement

Analyse

Pour chacune des parties, il existe des algorithmes bien connus qui garantissent un match nul dans le jeu de n'importe quel adversaire, et si son adversaire commet une erreur, ils lui permettent de gagner. Le jeu est donc dans un état "personne n'est mort"<#"877528.files/image002.gif">

Figure 1.2. Arbre des situations de jeu

Un arbre partiel des situations de jeu est présenté sur la Fig. 1.2 pour le jeu tic-tac-toe. Un arbre de situations de jeu pour le jeu tic-tac-toe, où le joueur des « croix » commence en premier et agit selon l'algorithme ci-dessus, et le joueur des « orteils » peut faire ce qu'il veut (et un sommet est donné pour une action rationnelle et pour une action irrationnelle, c'est-à-dire n'importe quelle autre), se compose de 50 nœuds.

1.4 Sélection des outils de développement

Pour atteindre nos objectifs, nous avons besoin d’un environnement de développement d’applications intégré. Par conséquent, le développement du projet a été réalisé dans l'environnement de programmation Microsoft Visual Studio 2008.

Microsoft Visual Studio est une gamme de produits Microsoft , y compris un environnement de développement intégré logiciels et un certain nombre d'autres outils. Ces produits vous permettent de développer en mode console applications et applications GUI , y compris la prise en charge de la technologie Windows Forms , ainsi que des sites Web , services Web comme en natif , et contrôlé codes pour toutes les plates-formes prises en charge par Windows ,Windows Mobile ,WindowsCE , .NET-Framework , Xbox , Téléphone Windows Cadre compact .NET et Silverlight .

2. PARTIE CONCEPTION DU DÉVELOPPEMENT

2.1 Développement de l'interface utilisateur

Lors de la création d'une application de jeu, il est nécessaire de prendre en compte l'un des principaux éléments du succès du produit : l'interface. L'interface utilisateur du programme doit avant tout être compréhensible et attrayante pour l'utilisateur. Vous devez essayer de supprimer tous les moments qui pourraient distraire l'utilisateur ou lui causer un inconfort. L'ensemble de l'interface du programme peut être divisé en deux composants.

) Menu principal du programme

Riz. 2.1 - Menu principal du programme

Le menu principal est conçu pour permettre à l'utilisateur de rejoindre l'atmosphère de jeu, c'est pourquoi l'interface est conçue dans des couleurs colorées et ludiques. Grâce au menu, vous pouvez accéder au terrain de jeu, consulter les règles du jeu ou quitter le jeu.

) Terrain de jeu

Fig 2.2 - Terrain de jeu

Le terrain de jeu contient la zone de jeu immédiate, où le joueur et l'ordinateur placent leurs icônes. Avant de démarrer le jeu, l'utilisateur doit sélectionner le type de jeu tel que "X vs 0", "1 niveau avec ordinateur" ou "2 niveaux avec ordinateur", sinon le programme donnera un message sur ce qu'il faut faire. Un bouton qui aidera le joueur à revenir au menu principal. À la fin, des fenêtres supplémentaires apparaîtront pour informer le participant des résultats du match.

Riz. 2.3 - fenêtres de résultats de jeu supplémentaires

2.2 Développement des structures de données (en externe et RAM)

La RAM est utilisée pour un tableau unidimensionnel composé de 9 éléments qui stocke les états du terrain de jeu, où chaque cellule du tableau correspond à une cellule du terrain de jeu. La mémoire est également dépensée en variables statiques : numéro de niveau, ordre du tour.

Son fonctionnement nécessite 803 Ko de mémoire libre.

.3 Développement et analyse d'algorithmes

Pour implémenter l'algorithme de réflexion du jeu, vous devez définir un tableau statique gcnew array (9); dans lequel seront stockés les états du terrain de jeu, où chaque cellule du tableau correspond à une cellule. "0" - correspond à une cellule vide, si un joueur s'est déplacé dans la cellule, c'est-à-dire "X", la valeur "1" est enregistrée et si l'ordinateur a effectué un mouvement, c'est-à-dire "O", la valeur est "2". Initialement, tous les éléments du tableau sont égaux à "0". Il est nécessaire de définir la variable statique lvl, qui stocke les données de niveau. Il y a 3 niveaux au total dans ce jeu : le lvl prend la valeur « 1 » si l'utilisateur a choisi le type de jeu « X vs O », la valeur « 2 » si « 1er niveau avec un ordinateur », et la valeur « 3 ». » si « 2ème niveau avec un ordinateur » » La variable joueur stocke l’ordre du tour (« vrai » est le tour du joueur, « faux » est le tour de l’ordinateur). Puisque le droit de faire le premier pas est donné à l'utilisateur, au début du jeu joueur = vrai. La variable statique flag stocke des informations indiquant s'il y a ou non des cellules vides sur le terrain de jeu : si flag = true - c'est-à-dire faux - il n'y a pas de cellules vides. L'algorithme de vérification doit contenir une itération des paramètres du tableau x et proposer sa propre solution, qui sera optimale pour la suite du jeu. Ce programme propose 2 niveaux de jeu avec un ordinateur. Au niveau 1, la tâche de l'ordinateur n'est pas de battre l'adversaire. C'est pourquoi cette fonction renvoie une valeur aléatoire de la cellule où ira l'ordinateur. Le code de cet algorithme est présenté dans [Annexe 1]. La figure 2.4 montre le schéma fonctionnel de l'implémentation du code.

Le mouvement le plus gagnant au début du jeu est de se déplacer vers le centre du terrain. Dans la fonction dif_level(), une condition est vérifiée au début : si le joueur ne s'est pas rendu sur le terrain central, alors l'ordinateur s'y rend. Sinon, si le joueur se rend au centre, la fonction check(2) est appelée pour vérifier la combinaison informatique et, s'il y a une opportunité de gagner, renvoie le numéro de cellule. Si l’ordinateur ne peut pas gagner au coup suivant, alors la fonction check(1) est appelée : vérifier la combinaison du joueur. Le numéro de la cellule dans laquelle le joueur aurait gagné s'il avait parié est renvoyé. S'il n'existe pas de telle combinaison, alors la fonction low_level() est appelée.

Figure 2.4. - Diagramme

Figure 2.5. - Diagramme

3. MISE EN ŒUVRE DU PROGRAMME EN LANGAGE C++

.1 Architecture du programme

Ce programme implémente 3 formulaires : le menu principal (Fig. 2.1.), le terrain de jeu (Fig. 2.2) et le champ d'aide (règles du jeu) ; 12 panneaux dont 9 principaux. Aussi, à la fin du jeu, une PictureBox apparaît avec le résultat, il y en a 5 au total (Figure 2.3).

Vous pouvez utiliser comme base les gestionnaires de clics du panneau, qui sont exactement 9 sur le terrain de jeu. Chaque gestionnaire appelle plusieurs fonctions. Au début il y a une condition, si l'utilisateur sélectionne le type de jeu « X contre 0 », les cellules sont simplement remplies avec les valeurs 1 ou 2 (croix ou zéro). Viennent ensuite les fonctions : indication de progression (CrossZero()), qui change la croix à zéro et vice versa, bloque les cellules occupées, checkArray(), trouve le gagnant gagnant(). La fonction gagnant() considère toutes les options gagnantes possibles, donc si l'un des joueurs aligne 3 de ses pièces (une croix ou un zéro) verticalement, horizontalement ou en diagonale, il gagnera. Sinon, si le terrain est plein, mais qu'aucun des joueurs ne s'est aligné, alors la fonction de contrôle d'égalité (_friend()) est appelée, qui vérifie s'il reste des cellules libres sur le terrain ou non. Si fr = true, alors il n'y a pas de cellules libres sur le champ. Si la valeur a changé, cela signifie qu'il y a une cellule libre sur le champ.

La deuxième condition fonctionne si le deuxième ou le troisième type de jeu est sélectionné. Ensuite, la fonction dans laquelle le déplacement de l'ordinateur a été effectué s'appelle : move(int n). Il transmet le numéro de la cellule sur laquelle le joueur a cliqué. Viennent ensuite les fonctions : indication de progression (CrossZero()), blocage des cellules occupées, checkArray(). Ensuite, la fonction gagnant() est appelée, qui vérifie si le joueur a gagné avec ce coup ou non. Dans le cas contraire, la présence de cellules libres est vérifiée. S’il y a des cellules libres, alors l’ordinateur bouge. Ensuite, selon le niveau choisi par le joueur « 1 » ou « 2 », les fonctions suivantes sont appelées : low_level(), dif_level(). La fonction low_level() sélectionne où placer le zéro de manière aléatoire, et la fonction dif_level() présente un algorithme spécial pour que l'ordinateur gagne. Viennent ensuite les fonctions : indication de progression (CrossZero()), blocage des cellules occupées, checkArray(). Ensuite, la fonction gagnant() est appelée, qui vérifie si l'ordinateur a gagné avec ce coup ou non. Dans le cas contraire, la présence de cellules libres est vérifiée. S'il y a des cellules libres, alors le joueur se déplace.

.2 Sélection des composants visuels et non visuels standards

Pour mettre en œuvre ce travail, les composantes suivantes ont été sélectionnées :

1) Formulaire1, avec paramètres donnés Texte = Tic-Tac-Toe, ControlBox = False

2) f2, avec les paramètres spécifiés BackColor, Text=Game

) comboBox1 avec les paramètres Items spécifiés :

X contre 0

1er niveau avec ordinateur

Niveau 2 avec ordinateur

4) panneau, avec les paramètres BackColor spécifiés et différentes valeurs pour les paramètres Visible et Enabled. Pour certains panneaux, des événements tels que Click ont ​​été écrits.

5) bouton, avec les paramètres spécifiés Font, Fore Color, BackColor, Text, pour tous les boutons, des événements tels que Click ont ​​été écrits.

6) étiquette, avec les paramètres spécifiés BackColor, Font, Fore Color, Text.

) PictureBox, avec les paramètres spécifiés Image, SizeMode= StretchImage.

) textBox, avec les paramètres spécifiés BackColor, Font, Fore Color, Text=" ".

4. RÉSULTATS DES TESTS

Testons le programme en passant par 3 types de jeux.

Essayons les actions des boutons du menu principal. Les boutons fonctionnent correctement. Essayons de démarrer le jeu sans choisir de type de jeu. Le programme affiche un message d'erreur et vous demande de sélectionner le type de jeu. (Fig. 4.1).

Figure 4.1.

Choisissons 1 type de jeu - "X contre 0", c'est-à-dire utilisateur contre utilisateur. A ce stade du jeu, l'utilisateur peut également jouer avec lui-même. (Fig.4.2)

Figure 4.2.

Lors du jeu « Niveau 1 avec l'ordinateur », l'ordinateur ne se fixe pas pour objectif de gagner le participant. Il met juste des zéros places libres des champs. A ce stade, l'utilisateur peut facilement battre l'ordinateur. Bien qu'à ce niveau d'autres options pour le développement d'événements soient également possibles.

Figure 4.3.

Type de jeu : « Niveau 2 avec ordinateur ». A ce stade, le jeu analyse tous les mouvements et essaie de choisir le mouvement le plus optimal. Ici aussi, les trois scénarios sont possibles, car L'ordinateur effectue son premier mouvement vers n'importe quelle cellule libre. Le plus souvent, le jeu se résume à un match nul.

Figure 4.4.

Le programme s'exécute avec succès sur toutes les variantes de test, sans erreur.

CONCLUSION

Nous pouvons affirmer avec certitude que la tâche fixée au début des travaux est terminée. Au cours du développement, un projet de remix du célèbre jeu « Tic Tac Toe » a été planifié et développé. Le jeu répond aux exigences spécifiées et remplit ses fonctions. Mis en œuvre dans le travail Divers types jeux et niveaux de difficulté.

Au cours des travaux, de nouvelles méthodes de programmation ont été maîtrisées dans un environnement de développement intégré. Les anciennes connaissances sur le travail avec le langage C++ ont été consolidées. En préparation du cours, diverses méthodes et algorithmes de mise en œuvre de ce jeu ont été analysés.

Malgré l'apparente simplicité de ce programme, il se heurte à un certain nombre de difficultés qui sont mises en œuvre en utilisant toutes les techniques de base de Visual C++.

Les caractéristiques de ce programme sont :

Algorithme clairement construit ;

Interface intuitive ;

Facile à utiliser;

Manuel d'utilisation assez clair ;

Aucun module complémentaire inutile.

BIBLIOGRAPHIE

1. http://www.pravilaigr.ru/xo.php

2. http://2igroka.com/stuff/sportivnye/krestiki_noliki_3d/15-1-0-14

3. https://www.draw.io/

Http://pol-video.ru/QPW9QHEO2GU/uroki_s_krestiki-noliki_ch1.html

ANNEXE 1

private: int low_level())(// procédure pour un adversaire léger;::Random^ rand = gcnew System::Random();(= rand->Next(0,8);

) tandis que (x[r] != 0);r;

ANNEXE 2

private: bool check(int n)(k = -1;// vérifie toutes les combinaisons et renvoie le bon move(x == n) (((x == n)&&(x == 0)) k =2; ((x == n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =6;((x == n)&&(x == 0)) k =3;((x == n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =7;((x = = n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =4;((x == n)&&(x == 0)) k =6;((x = = n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =5;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =5;((x = = n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =3;((x = = n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =7;

)(x == n) (((x == n)&&(x == 0)) k =6;

)(k!=-1) renvoie vrai ; sinon renvoie faux ;

ANNEXE 3

private: int dif_level())(//ennemi difficile

//return check(2);(x == 0) return (4);(check(2)) return k; sinon (check(1)) renvoie k ; sinon low_level();

APPLICATION 4

private: void CrossZero())(// change la croix en zéro (indicateur de progression)(joueur) (->Visible = true;->Visible = false;

) else (->Visible = vrai;->Visible = faux;

): void checkArray())(// fonction de vérifier s'il y a quelque chose dans une cellule, s'il y en a, alors vous ne pouvez plus cliquer sur cette cellule.(x == 1) (panel1->BackgroundImage = panel11->BackgroundImage ;panel1- >Enabled = false;)(x == 2) (panel1->BackgroundImage = panel10->BackgroundImage;panel1->Enabled = false;)(x == 1) (panel2->BackgroundImage = panel11->BackgroundImage ;panel2- >Enabled = false;)(x == 2) (panel2->BackgroundImage = panel10->BackgroundImage;panel2->Enabled = false;)(x == 1) (panel3->BackgroundImage = panel11->BackgroundImage ;panel3- >Enabled = false;)(x == 2) (panel3->BackgroundImage = panel10->BackgroundImage;panel3->Enabled = false;)(x == 1) (panel4->BackgroundImage = panel11->BackgroundImage ;panel4- >Enabled = false;)(x == 2) (panel4->BackgroundImage = panel10->BackgroundImage;panel4->Enabled = false;)(x == 1) (panel5->BackgroundImage = panel11->BackgroundImage ;panel5- >Enabled = false;)(x == 2) (panel5->BackgroundImage = panel10->BackgroundImage;panel5->Enabled = false;)(x == 1) (panel6->BackgroundImage = panel11->BackgroundImage ;panel6- >Enabled = false;)(x == 2) (panel6->BackgroundImage = panel10->BackgroundImage;panel6->Enabled = false;)(x == 1) (panel7->BackgroundImage = panel11->BackgroundImage ;panel7- >Enabled = false;)(x == 2) (panel7->BackgroundImage = panel10->BackgroundImage;panel7->Enabled = false;)(x == 1) (panel8->BackgroundImage = panel11->BackgroundImage ;panel8- >Enabled = false;)(x == 2) (panel8->BackgroundImage = panel10->BackgroundImage;panel8->Enabled = false;)(x == 1) (panel9->BackgroundImage = panel11->BackgroundImage ;panel9- >Enabled = false;)(x == 2) (panel9->BackgroundImage = panel10->BackgroundImage;panel9->Enabled = false;)

): bool gagnant())(// vérification du gagnant et blocage de toutes les cellules restantes.

//bool flag = false;(((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x = = 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2 )) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)))( (lvl==1) ( PicturePo->Visible = true;)(picturePr->Visible = true;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Activé = faux;->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;true;

)(((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || (( x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x = = x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)))((lvl==1) (imagePx->Visible = vrai;)(imagePobeda->Visible = vrai;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Activé = faux;->Enabled = false;->Enabled = false;->Enabled = false;true;

): void _friend())(fr = true;(int i = 0; i< 9; i++) if (x[i] == 0) {fr = false; break;}(fr) { pictureN->Visible = vrai ;)

): void move(int n)(// fonction de déplacement de l'ordinateur= false;[n] = 1;= !player;();();(winner()) () ((int i = 0; i< 9; i++) if (x[i] == 0) flag = true;(flag){(lvl == 2) = 2; = 2;= !player;();();();

): System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) (// nouveau jeu>Visible = false;>Visible = false;>Visible = false; >Visible = false; >Visible = false; = comboBox1->Text;(typeGame == "")(::Show("Sélectionnez d'abord votre type de jeu!");

) else ((typeGame == "X versus 0") lvl = 1;(typeGame == "1er niveau avec un ordinateur") lvl = 2;(typeGame == "2ème niveau avec un ordinateur") lvl = 3;( ); = vrai;(int i = 0; i< 9; i++) x[i] = 0;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12-> BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = vrai;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true;

): System::Void panel1_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 0;(lvl == 1)((player)( = 1;

)= !joueur;();();();

): System::Void panel2_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 1;(lvl == 1)((player)( = 1;

)= !joueur;();();();

) sinon if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel3_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 2;(lvl == 1)((player)( = 1;

)= !joueur;();();();

) sinon if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel4_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 3;(lvl == 1)((player)( = 1;

)= !joueur;();();();

) sinon if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel5_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 4;(lvl == 1)((player)( = 1;

)= !joueur;();();();

) sinon if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel6_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 5;(lvl == 1) ((player)( = 1;

)= !joueur;();();();

) sinon if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel7_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 6;(lvl == 1) ((player)( = 1;

)= !joueur;();();();

) sinon if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel8_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 7;(lvl == 1) ((player)( = 1;

)= !joueur;();();();

) sinon if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel9_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 8;(lvl == 1) ((player)( = 1;

)= !joueur;();();();

) sinon if ((lvl == 2)||(lvl == 3))((n);

): System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) (();

): System::Void PicturePx_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

) : System::Void picturePo_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

) : System::Void PicturePobeda_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void PicturePr_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void PictureN_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

Attention! Il s'agit d'une version d'introduction de la leçon, dont le matériel peut être incomplet.

Connectez-vous au site en tant qu'étudiant

Connectez-vous en tant qu'étudiant pour accéder au matériel scolaire

Création de configurations 1C : écriture de « Tic Tac Toe » partie 1/3

Nous apprendrons en jouant, et donc notre premier projet sera de créer pour tous
un jeu familier depuis l'enfance - "Tic Tac Toe".

Vous vous demandez peut-être quel est le rapport entre les jeux et 1C, la comptabilité et le trading ? Presque aucun. Mais nous devons commencer progressivement et, avec le temps, nous parviendrons à l’automatisation des entrepôts. Pour l’instant, commençons petit.

Avant de commencer à programmer le jeu Tic-Tac-Toe, réfléchissons-y.

Nous savons déjà que le formulaire comporte des éléments, dont le bouton. Les boutons sont capables d'exécuter des commandes et, en même temps, possèdent des propriétés qui permettent de contrôler leur affichage sur le formulaire (par exemple, un titre).

Par exemple, vous pouvez utiliser un bouton pour créer un champ avec neuf zones actives (ces cellules sur lesquelles nous cliquons et enregistrons l'action, tout en affichant simultanément des inscriptions sous la forme de « O » et de « X »). Le bouton est plus que adapté pour cela.

De quoi avons nous besoin? Évidemment, nous devrons nous souvenir de notre mouvement et du mouvement de l'ordinateur. Il faudra également changer les titres des boutons : quand on clique, le titre du bouton est toujours « O », lorsque l'ordinateur bouge, c'est « X ».

Tout d’abord, nous devrons créer une nouvelle base de données dans laquelle nous créerons notre jeu. Faisons cela.

Étape n°1 : créer une base de données vide

Créons une base de données Tic-Tac-Toe vide.

Des instructions détaillées

Lançons Raccourci 1C pour ouvrir une liste des infobases disponibles sur l'ordinateur. Vous lisez une version d'essai de la leçon, des leçons complètes sont disponibles. Nous avons besoin de création nouvelle base, alors appuyez sur le bouton " Ajouter":

La fenêtre d'ajout s'ouvrira base d'informations, dans lequel vous devez sélectionner le premier élément " Création d'une base d'informations" et cliquez sur le bouton "Suivant" :

Dans la fenêtre suivante, sélectionnez le deuxième élément " Créer une base d'informations sans configuration pour développer une nouvelle configuration..." et cliquez à nouveau sur le bouton "Suivant" :

Dans la fenêtre suivante, il nous est demandé de saisir le nom de la nouvelle base de données, sous laquelle elle sera affichée dans la liste des bases de données. Entrons " Tic Tac Toe" et cliquez sur le bouton "Suivant" :

Dans la fenêtre suivante, vous devez spécifier le chemin d'accès au dossier vide dans lequel notre base de données sera stockée. Dans ce cas, j'ai créé le dossier " Tic Tac Toe" dans le dossier "Bases de données 1C" sur le lecteur D :

Dans la fenêtre suivante, laissez tous les paramètres par défaut et cliquez sur le bouton " Prêt":

Après une courte pause, la base de données a été créée et ajoutée à la liste. Il existe deux modes principaux de travail avec la base de données : 1C : Entreprise Et Configurateur:

En mode configurateur, nous configurons et programmons la base de données, en mode 1C:Enterprise, nous voyons ce qui en résulte.

Étape n°2 : ouvrez le configurateur

Appuyons sur le bouton " Configurateur" pour passer en mode configurateur :

Étape n°3 : ouvrir l'arborescence de configuration

Exécutez la commande de menu " Configuration"->"Ouvrir la configuration":

Un arbre de configuration s'est ouvert devant nous, qui contient diverses sections de configuration. Comme nous n’avons encore rien créé, ces sections sont vides :

Étape n°4 : ajouter le traitement

Pour situer la logique de notre jeu, nous utiliserons la section « Traitement ». Cliquons clic-droit dans la rubrique " Traitements" et sélectionnez la commande "Ajouter" :

Une fenêtre pour créer un nouveau traitement s'est ouverte devant nous. Entrons le nom " Tic Tac Toe". Le synonyme sera inséré tout seul. Cela suffit pour sauvegarder notre traitement (encore vide) dans la base de données. Cliquez sur le bouton "Fermer":

Étape n°5 : premier débogage du programme

Vous pouvez vérifier ce qui s'est passé depuis le mode utilisateur ( 1C : Entreprise). Pour y accéder directement depuis le configurateur, exécutez la commande de menu " Débogage"->"Commencer le débogage":

Puisque nous avons apporté une modification à la base de données, on nous demande si nous acceptons cette modification. Cette question nous sera constamment posée pendant le processus de développement. Nous sommes d'accord (bouton " Oui"):

La base de données a démarré en mode "1C:Entreprise". Vous lisez une version d'essai de la leçon, des leçons complètes sont disponibles. Mais comme nous le voyons, travailler avec est toujours difficile - il n'y a tout simplement rien à choisir. C’est étrange, car nous avons déjà créé le traitement et, en théorie, il devrait apparaître sur le panneau jaune.




Haut