Comment écrire un programme Tic-Tac-Toe en Java

Introduction:

Tic-Tac-Toe est un jeu très commun qui est assez facile à jouer. Les règles du jeu sont simples et bien connues. À cause de ces choses, Tic-Tac-Toe est assez facile à coder. Dans ce tutoriel, nous verrons comment coder un jeu fonctionnel de Tic-Tac-Toe en Java. Ce didacticiel suppose que vous avez une connaissance de la syntaxe de base de Java et un accès à un compilateur Java fonctionnel. Ce didacticiel utilisera l'IDE Eclipse.

Plan général:

Il existe de nombreuses façons d'implémenter un jeu de Tic-Tac-Toe en Java, donc avant de commencer le codage, nous devons réfléchir à la façon dont nous allons implémenter le jeu spécifiquement. Pour ce didacticiel, nous allons coder une version textuelle de Tic-Tac-Toe. Notre Tic-Tac-Toe commencera par imprimer le tableau, puis en demandant la contribution du premier joueur qui spécifiera où sur le tableau pour placer la marque de ce joueur. Après avoir placé la marque, nous imprimerons à nouveau l'état du plateau, puis demanderons à l'autre joueur son mouvement. Ce processus se poursuivra jusqu'à ce qu'un joueur gagne ou que le plateau soit rempli (indiquant qu'une égalité s'est produite). L'entrée qui sera prise pour spécifier où placer une marque sera au format de deux entiers, qui spécifient la ligne et la colonne où la marque doit être placée. Vous trouverez ci-dessous un exemple de ce à quoi un jeu se déroulera.

Étape 1: Création de votre projet

La première étape du codage est de créer un nouveau projet! Dans votre IDE, créez un nouveau projet Java nommé TicTacToe. Dans cet Instructable, le package par défaut est ce qui sera utilisé. À l'intérieur de votre package de projet, créez deux classes: Main.java et TTT.java. Main.java hébergera la méthode principale et sera utilisé pour exécuter le code dans TTT.java. TTT.java contiendra un objet Tic-Tac-Toe qui contient l'état du plateau et les méthodes pour manipuler le jeu.

Étape 2: démarrage de la classe TTT

Avant de pouvoir créer du code pour exécuter notre objet TTT, nous devons créer un objet TTT fonctionnel. Puisqu'un objet TTT est représentatif d'un jeu de Tic-Tac-Toe, il doit contenir deux variables membres. Vous trouverez ci-dessous les variables membres qui doivent être placées dans la classe TTT, suivies d'une description des raisons pour lesquelles elles sont nécessaires.

tableau de char privé [] [];

Cette variable est un tableau 2D de caractères qui sera représentatif du plateau trois par trois d'un jeu de Tic-Tac-Toe. Il conservera l'état du jeu à l'intérieur de l'objet TTT à tout moment.

caractère privé currentPlayerMark;

Cette variable contiendra un «x» ou un «o», représentant le tour du joueur auquel il appartient à un moment donné. Les méthodes de la classe TTT s'en serviront lors du marquage du tableau pour déterminer quel type de marque sera placé.

Étape 3: initialisation des prototypes de méthodes dans la classe TTT

Ce qui suit est une configuration générale du programme. Vous trouverez ci-dessous tous les en-têtes de méthode pour les méthodes appartenant à la classe TTT. Ces méthodes agiront sur les variables membres de la classe TTT pour rendre le jeu de Tic-Tac-Toe mutable. Chacun a une brève description de ce que la méthode fera en dessous. Ces comportements sont nécessaires pour jouer à un jeu complet de Tic-Tac-Toe.

TTT public ()

Ceci est le constructeur. Il sera chargé de s'assurer que le plateau est correctement initialisé et de définir qui sera le premier joueur.

public void initializeBoard ()

Cette méthode initialisera la variable de la carte de sorte que tous les emplacements soient vides.

public void printBoard ()

Cette méthode imprime la carte Tic-Tac-Toe sur la sortie standard.

public boolean isBoardFull ()

Cette méthode vérifiera si la carte est pleine ou non. Il retournera vrai si la carte est pleine et faux sinon.

chèque booléen publicForWin ()

Cette méthode vérifiera si un joueur a gagné et si c'est le cas, elle reviendra vraie.

checkRowsForWin () booléen privé

Cette méthode vérifiera spécifiquement les lignes pour une victoire.

chèque privé booléenColumnsForWin ()

Cette méthode vérifiera spécifiquement les colonnes pour une victoire.

chèque privé booléenDiagonalsForWin ()

Cette méthode vérifiera spécifiquement les diagonales pour une victoire.

checkRowCol booléen privé (char c1, char c2, char c3)

Cette méthode vérifie les trois caractères spécifiés pris pour voir si tous les trois sont la même lettre «x» ou «o». Si c'est le cas, cela reviendra vrai.

Remarque : Si vous codez des stubs de méthode pour tous les en-têtes de méthode dans votre classe TTT, votre compilateur vous informera probablement que votre code contient des erreurs. C'est normal. Le compilateur attend simplement qu'une valeur soit renvoyée pour toutes les méthodes non-void.

Étape 4: initialiser la carte

public void initializeBoard ()

Cela mettra la carte à toutes les valeurs vides. À l'intérieur de cette méthode, vous devez créer 2 boucles pour les unes à l'intérieur des autres qui parcourront toutes les lignes et colonnes en définissant chaque espace sur «-». Pour parcourir les lignes, créez une boucle for et un entier, dans ce cas nommé i, pour représenter la ligne que nous observons actuellement.

pour (int i = 0; i <3; i ++) {}

À l'intérieur de cette boucle for, nous allons créer une seconde boucle for avec un entier j pour représenter la colonne que nous observons actuellement.

pour (int j = 0; j <3; j ++) {}

À l'intérieur de la seconde boucle for, nous avons défini l'emplacement de la carte sur «-». Avec les deux boucles terminées et imbriquées correctement, nous pouvons parcourir chaque endroit à l'intérieur du tableau 2D de la carte.

board [i] [j] = '-';

À cette étape se trouve une image montrant une implémentation possible de la méthode initializeBoard ().

Étape 5: Impression de la carte

La carte imprimée initiale ressemblera à la première image.

Il sera géré dans la méthode public void printBoard (), qui se trouve dans la classe TTT. Pour imprimer la carte, nous devons accéder à chaque endroit du tableau 2D nommé board dans notre classe TTT. Parce que nous avons affaire à un tableau 2D, cela sera géré avec des boucles imbriquées.

Tout d'abord, il suffit d'imprimer une ligne de tirets (13 d'entre eux dans ce cas) désignant le haut du tableau. En dessous, nous avons besoin d'une boucle for qui parcourra chacune des trois lignes. Cette boucle contiendra un appel pour imprimer un '|', une autre boucle pour parcourir les colonnes et un appel à la fonction System.out.println () pour imprimer une nouvelle ligne et les 13 tirets suivants à l'écran.

Notre boucle for interne ne bouclera également que sur trois colonnes. Puisque notre boucle for externe a déjà imprimé le premier | caractère de chaque ligne du tableau, nous pouvons aller de l'avant pour imprimer le caractère qui appartient à la boîte. Pour ce faire, nous allons imprimer le caractère sur cette ligne et cette colonne en utilisant la planche [i] [j] (i étant la variable utilisée pour la boucle for externe, qui était la ligne, et j étant la variable utilisée pour la boucle interne, qui est la colonne.) Cette instruction d'impression contiendra également un | pour séparer les cases.

Il ne reste plus qu'à imprimer le dernier appel pour imprimer la nouvelle ligne pour séparer chaque ligne, suivi des 13 tirets. La deuxième image jointe montre un exemple de ce à quoi pourrait ressembler la fonction d'impression décrite.

Étape 6: Recherche d'un gagnant (partie 1)

Il existe trois fonctions différentes pour vérifier une victoire: les lignes, les colonnes et les diagonales. Les ordinateurs doivent les séparer dans des conditions différentes car ils sont tous différents en termes de tableaux. checkForWin () sera notre fonction principale pour tester les 3 de ces fonctions pour chaque scénario que l'entrée utilisateur a affecté.

Pour la méthode checkForWin (): Vous avez simplement besoin d'une instruction return qui appelle les trois fonctions différentes. Si la vérification des lignes pour win ne renvoie pas true, vérifiez les colonnes pour win, etc. L'intérieur de l'instruction return devrait ressembler à: checkRowsForWin () || checkColumnsForWin () || checkDiagonalsForWin ()

Pour la méthode checkRowsForWin (): Nous parcourons les lignes pour voir s'il y a des gagnants. Cela nécessitera une boucle for avec une instruction if à l'intérieur. La boucle for sera incrémentée à travers l'entier i afin de vérifier chaque ligne. for (int i = 0; i <3; i ++) L'instruction if compare chaque espace de la ligne les uns aux autres et donne une valeur «vraie» s'ils sont tous égaux. Par exemple, si la ligne avait trois x d'affilée, la méthode retournerait true. if (checkRowCol (board [i] [0], board [i] [1], board [i] [2]) == true) Donc, à l'intérieur de cette instruction if, il devrait y avoir un: return true; Et après la boucle for, si la méthode ne s'est jamais arrêtée, alors la méthode doit retourner que cette ligne n'a pas eu trois symboles correspondants consécutifs. Par conséquent, juste avant de fermer la méthode avec son '}' final, nous écrirons: return false; Satisfaire le besoin de retourner un booléen.

Pour la méthode checkColumnsForWin (): copiez et collez le contenu de la méthode checkRowsForWin (). Le seul changement sera à l'intérieur de l'instruction if. Au lieu d'incrémenter les lignes, nous allons incrémenter les colonnes. Donc, dans checkRowsForWin a une instruction if qui dit: if (checkRowCol (board [i] [0], board [i] [1], board [i] [2]) == true) checkColumnsForWin () aura un if instruction qui dit: if (checkRowCol (board [0] [i], board [1] [i], board [2] [i]) == true) À part cela, tout le reste de la méthode reste le même.

Pour la méthode checkDiagonalsForWin (): tout ce qui est écrit peut être contenu entre les parenthèses d'une instruction return (). La première vérification que nous effectuerons se fera sur la diagonale du coin supérieur gauche au coin inférieur droit. Pour ce faire, nous vérifions tous les espaces qui seraient inclus dans cette section. checkRowCol (board [0] [0], board [1] [1], board [2] [2]) == true) Ensuite, nous aurons une autre instruction, mais nous les séparerons par un symbole OU: ' || » La deuxième déclaration sera vérifiée du coin supérieur droit au coin inférieur gauche. checkRowCol (board [0] [2], board [1] [1], board [2] [0]) == true) Ainsi, votre produit final de la méthode checkDiagonalsForWin () devrait être un return (), et à l'intérieur doit contenir la première instruction OU la deuxième instruction.

Étape 7: Recherchez un gagnant (partie 2)

Maintenant, nous devons nous assurer que si un joueur en obtient trois d'affilée, il gagne. checkRowCol () sera une fonction qui comparera les trois lettres les unes aux autres, et si elles correspondent, retourne true.

Pour la méthode checkRowCol (): Cette méthode est utilisée par les autres méthodes pour envoyer trois valeurs. Nous vérifions d'abord pour nous assurer que la première valeur n'est pas vide telle que «-». Ensuite, nous comparons la première valeur à la seconde et la seconde à la troisième, et si et seulement si les trois valeurs sont les mêmes ET qu'elles ne sont pas des instructions vides, cette méthode retournera true. Donc, à l'intérieur d'une instruction return (), notre première instruction vérifiera qu'il ne s'agit pas d'un «-». (c1! = '-') Séparez les première et deuxième instructions par un '&&' La deuxième instruction verra si la première valeur est égale à la deuxième valeur. (c1 == c2) Séparez les deuxième et troisième instructions par un '&&'. La troisième instruction verra si la deuxième valeur est égale à la troisième. (c2 == c3) Votre méthode checkRowCol () finale sera donc un retour () contenant la première instruction && la deuxième instruction && la troisième instruction.

Étape 8: Changement entre les joueurs (x et O)

public void changePlayer ()

La méthode changePlayer () permutera la variable currentPlayerMark entre x et o. Pour ce faire, vérifiez simplement ce que la variable contient actuellement. Si la variable contient un «x», remplacez-la par un «o». Sinon, remplacez-le par un «x».

public boolean placeMark (int row, int col)

La méthode placeMark () placera la lettre correcte sur la ligne et le col spécifiés dans la variable board (prise en paramètre). Il reviendra vrai s'il s'agissait d'un emplacement valide. Sinon, aucune modification ne sera apportée à la variable du plateau et le joueur devra essayer de placer sa lettre à un endroit différent, car un emplacement non valide a été sélectionné ou un emplacement où un joueur ayant déjà placé sa lettre a été sélectionné. Pour accomplir ce comportement, quelques éléments doivent être vérifiés. Tout d'abord, assurez-vous (à l'aide d'une instruction if) que l'argument de ligne était compris entre 0 et 2. Ensuite, vérifiez que l'argument col était compris entre 0 et 2. Enfin, vérifiez que l'emplacement en question contient actuellement un '- », ce qui signifie qu'aucun payeur n'a encore marqué cet endroit. Si ces trois conditions sont vérifiées, placez une marque (dont le type est spécifié par la variable de classe currentPlayerMark) à l'emplacement spécifié par row et col, puis retournez true. Si l'une des trois conditions n'est pas remplie, il convient de noter et de renvoyer false.

À cette étape sont attachées des images montrant les implémentations possibles des méthodes mentionnées ci-dessus.

Étape 9: entrée du joueur et jeu

Maintenant que la classe TTT et toutes ses méthodes sont terminées, une méthode principale qui traverse un jeu entier de Tic-Tac-Toe utilisant un objet TTT doit être créée. La méthode principale doit faire pas mal de choses pour exécuter un jeu complet de Tic-Tac-Toe.

Tout d'abord, il doit créer un objet Scanner pour recevoir les entrées de System.in. En outre, il doit instancier un objet TTT pour jouer au jeu Tic-Tac-Toe. Après ces choses, il doit initialiser la carte de l'objet TTT en appelant sa méthode initializeBoard ().

Une fois ces étapes terminées, le jeu réel doit être pris en compte. Pour effectuer des virages, une boucle do while est requise. La boucle devrait éclater lorsque le jeu est terminé, c'est-à-dire chaque fois que le plateau de l'objet TTT est plein ou a un gagnant. À l'intérieur de la boucle, l'état actuel du plateau doit être imprimé avant chaque tour afin de montrer au joueur quels espaces sont disponibles et quels espaces sont pris. Ensuite, deux entrées doivent être prises en signifiant la ligne et la colonne pour placer une marque pour le tour. Une fois cette entrée saisie, la marque doit être placée en utilisant la méthode de l'objet TTT, et le lecteur doit également être changé en utilisant la méthode de l'objet TTT.

En dessous de la boucle while qui gère tous les tours jusqu'à la fin de la partie, il sera nécessaire de déclarer qui est le vainqueur de la partie (ou si la partie était à égalité). Pour ce faire, vérifiez d'abord si le match était à égalité en vérifiant si le plateau était plein et s'il n'y avait pas de gagnant. Si ces choses sont le cas, imprimez que le jeu était à égalité. Sinon, imprimez qui a gagné en imprimant l'opposé de l'état actuel de la variable currentPlayerMark de l'objet TTT. Cela peut être accompli en appelant d'abord la méthode changePlayer () de l'objet TTT, puis en utilisant la méthode getCurrentPlayerMark () de l'objet TTT pour obtenir l'état de la variable currentPlayerMark. Il peut également être utile d'imprimer le tableau une fois de plus pour montrer l'état final du tableau.

Un exemple de méthode principale a été joint en tant qu'image.

Étape 10: utiliser classe, compiler et exécuter

Une fois que vous êtes arrivé à ce point, votre projet doit être suffisamment complet pour être exécuté. S'il y a des erreurs ou des parenthèses ou des points-virgules manquants, il serait temps de les trouver et de les corriger. Si vous ne savez pas du tout à quoi devrait ressembler votre projet, nous avons inclus un fichier téléchargeable pour comparer votre code à un produit final fonctionnel. Allez-y et compilez votre projet. Dans Eclipse, il y a un bouton de lecture qui ressemble à l'image attachée à cette étape.

Pièces jointes

  • Working Final Product.zip Télécharger

Articles Connexes