Quand j'étais lycéen, j'étais un peu inscrit au club Go Shogi à l'école. Je ne jouais pas au Go ou au Shogi depuis longtemps, mais j'étais intéressé à être influencé par les mangas. En conséquence, je n'étais pas vraiment bon dans ce domaine et je voulais la position la plus faible du club. Donc, pour une raison quelconque, il y avait aussi un tableau d'Othello dans la salle du club du club Go Shogi, et après avoir été foiré par d'autres membres avec Shogi, je faisais aussi Othello pour changer. Othello a des règles plus simples que Go et Shogi, donc il y a bien sûr des difficultés, mais je ne sais pas où utiliser les morceaux pris avec Shogi, ou quand Go est considéré comme la fin. Pour moi, c'était un événement vraiment facile. Eh bien, c'était encore cahoteux. À propos, il semble qu'il y ait des gens féroces dans le monde qui peuvent tirer le codage d'Othello dans une plage de 7 lignes $ × 79 $ caractères, mais je ne peux pas le faire même avec 700 lignes, et encore moins 70 lignes, soit 10 fois plus. Comme il fonctionne comme un corps, j'ai décidé de contester l'implémentation d'Othello cette fois sans limiter le nombre de personnages. En fait, je visais le programme Othello le plus puissant comme le suggère le titre en concevant un algorithme pour déterminer où il est préférable de placer la pierre, mais comme je m'y attendais, je vais en faire une situation où Othello peut être fait normalement en premier lieu. C'était tout ce que je pouvais faire. Donc, cette fois, en tant que [Préparation], j'écrirai sur le processus jusqu'à ce qu'Othello devienne capable de jouer pour le moment.
Cette fois, ce serait bien si Othello pouvait être fait! Je vais le dire. Cependant, je ne peux pas faire quelque chose qui fonctionne sur le navigateur pour le moment, donc je vais faire quelque chose qui fonctionne sur la console familière à chaque fois. Alors, veuillez pardonner __pas __ pour quelque chose que vous pouvez faire et jouer.
En gros, tous les traitements d'Othello que nous allons implémenter seront écrits dans une classe appelée OthelloBoard. OthelloBoard a les variables et tableaux suivants comme membres:
class OthelloBoard {
private int size; //Un côté du plateau d'Othello(8, 10, 12, 14, 16)
private char[][] squares; //État de chaque masse(B:noir, W:blanc, N:Pas de pierre)
private char playerColor; //Couleur de la pierre du joueur
private char otherColor; //La couleur de la pierre de l'adversaire
private int turnCounter; //Comptez le nombre de tours
private final String alphabets = "abcdefghijklmnop";
}
La taille variable de type int représente le nombre de pierres qui peuvent être placées sur un côté de la planche Othello. Dans le constructeur décrit plus loin, le général 8 est attribué, mais si vous jouez avec, vous pouvez jouer avec la taille de madness de 16 carrés $ × 16 $ carrés. J'ai essayé, mais j'ai été frustré au début. ~~ Je suis fou ~~ Hmmm, ce sentiment de désespoir.
…… Renvoyez l'histoire. Les carrés de tableau à deux dimensions de type char sont un tableau qui représente l'état de chaque cellule. Vous pouvez voir s'il y a une pierre dans le carré, et si c'est le cas, s'il s'agit d'une pierre noire ou blanche, ou la mettre à jour. Les variables de type char suivantes playerColor et otherColor contiendront soit "B" soit "W" lorsque le joueur sélectionne Kuroishi ou Shiraishi au début de la partie. La dernière chaîne, alphabets, contient des alphabets qui représentent les coordonnées horizontales utilisées pour afficher le tableau Othello. This.alphabets.charAt (x) lorsque vous voulez faire référence à l'alphabet $ x $ th, et inversement, cela lorsque vous voulez savoir quel est le nombre de la lettre y (vous voulez connaître les coordonnées horizontales sous forme de valeur numérique). Vous pouvez faire quelque chose comme .alphabets.indexOf ("y"). De plus, comme cette chaîne ne devrait pas être modifiée à l'avenir, le modificateur final est ajouté. Pour ce domaine, je me suis référé aux commentaires que j'ai reçus dans les articles précédents. Merci à tous ceux qui ont fait des commentaires.
Maintenant, d'ici, je vais vous expliquer la partie qui affiche le tableau d'Othello.
//Affichez la carte Othello sur la console
private void printBoard() {
this.printBoardAlphabetLine(); //Ligne alphabet
this.printBoardOtherLine("┏", "┳", "┓"); //Bord supérieur
for (int y = 0; y < this.size - 1; y ++) {
this.printBoardDiscLine(y); //Ligne affichant des pierres
this.printBoardOtherLine("┣", "╋", "┫"); //Interligne
}
this.printBoardDiscLine(this.size - 1); //Ligne affichant des pierres
this.printBoardOtherLine("┗", "┻", "┛"); //Bas de gamme
}
//Afficher l'alphabet indiquant la ligne du plateau Othello
private void printBoardAlphabetLine() {
String buf = " ";
for (int x = 0; x < this.size; x ++) {
buf += " " + this.alphabets.charAt(x);
}
System.out.println(buf);
}
//Afficher une ligne avec des pierres sur le plateau Othello
private void printBoardDiscLine(int y) {
String buf = String.format("%2d┃", y+1);
for (int x = 0; x < this.size; x ++) {
if (this.squares[y][x] == 'B') {
buf += "●┃";
} else if (this.squares[y][x] == 'W') {
buf += "○┃";
} else {
buf += " ┃";
}
}
System.out.println(buf);
}
//Afficher une ligne de lignes réglées représentant le cadre du plateau Othello
private void printBoardOtherLine(String left, String middle, String right) {
String buf = " " + left;
for (int x = 0; x < this.size - 1; x ++) {
buf += "━" + middle;
}
System.out.println(buf + "━" + right);
}
Si vous souhaitez afficher la carte Othello sur la console, appelez la première méthode printBoard. Afin d'afficher le plateau Othello, il est nécessaire d'afficher des cercles noirs et des cercles blancs qui représentent des pierres, des lignes de règle qui représentent le cadre du plateau, etc. Les pièces avec le même flux sont assemblées dans différentes méthodes printBoardAlphabetLine, printBoardDiscLine et printBoardOtherLine, et elles sont appelées. En passant, lorsque vous exécutez la méthode ci-dessus, vous verrez quelque chose comme ceci (la taille est de 8 carrés $ x 8 $ carrés).
Les alphabets ou les nombres représentant les coordonnées sont affichés en haut et à gauche du tableau Othello. Lorsque le joueur saisit l'endroit où placer la pierre, par exemple, saisissez alphabet + espace demi-largeur + nombre tel que "un 1".
Ensuite, nous vous montrerons comment gérer les entrées des joueurs. Comme je l'ai écrit plus tôt, l'endroit où placer la pierre est de saisir "alphabet + espace demi-largeur + nombre", mais vous devez vous assurer que l'entrée est correcte. Les contenus qui doivent être confirmés sont les suivants pour le moment.
Le code suivant implémente le processus pour les vérifier.
//Acceptez l'entrée jusqu'à ce que l'endroit où placer la pierre soit décidé
private void askNewCoordinates(char myColor, char enemyColor) {
while (true) {
//contribution
System.out.println("\n Décidez où placer la pierre.");
System.out.println("[coordonnée x coordonnée y](Exemplea1):");
Scanner sc = new Scanner(System.in);
//Déterminez s'il est à portée de la planche Othello
Coordinates newDisc = this.checkCoordinatesRange(sc.nextLine());
if (newDisc.equals(-1, -1)) {
//Si les coordonnées sont incorrectes, ressaisissez
System.out.println("L'entrée est incorrecte.");
continue;
}
if (this.squares[newDisc.y][newDisc.x] != 'N') {
//Si une pierre a déjà été placée, la faire entrer
System.out.println("J'ai déjà une pierre.");
continue;
}
//Déterminez si la pierre de l'adversaire peut être retournée
ArrayList<Coordinates> discs = this.checkDiscsTurnedOverAllLine(
myColor, enemyColor, newDisc, this.size*this.size);
if (! discs.isEmpty()) {
//S'il y a une pierre qui peut être retournée, retournez la pierre
this.putDisc(myColor, newDisc);
this.turnOverDiscs(discs);
this.printDiscsTurnedOver(discs);
return;
}
System.out.println("Je ne peux pas retourner la pierre de l'adversaire.");
}
}
//Déterminez si les coordonnées saisies par le joueur sont à portée du plateau Othello
//Si le jugement réussit, les coordonnées sont utilisées, et si le jugement échoue, les coordonnées sont utilisées.(-1, -1)rends le
private Coordinates checkCoordinatesRange(String line) {
String[] tokens = line.split(" ");
//Lire les coordonnées horizontales de la première lettre de l'alphabet
int x = this.alphabets.indexOf(tokens[0]);
if (tokens[0].length() != 1 || x < 0 || this.size <= x) {
return new Coordinates(-1, -1);
}
//Lire les coordonnées verticales des caractères restants
int y;
try {
y = Integer.parseInt(tokens[1]);
if (y <= 0 || this.size < y) {
return new Coordinates(-1, -1);
}
} catch (NumberFormatException e) {
return new Coordinates(-1, -1);
}
return new Coordinates(x, y - 1);
}
Si vous souhaitez que le joueur entre l'emplacement de la pierre que vous souhaitez placer, appelez la première méthode askNewCoordinates. En utilisant l'instruction while, le lecteur continue de taper encore et encore jusqu'à ce qu'il puisse être traité comme une entrée correcte (c'est un peu effrayant à dire). Le premier des bulletins ci-dessus est jugé par la méthode checkCoordinatesRange. Puisque le lecteur relie l'alphabet des coordonnées horizontales et le nombre de coordonnées verticales avec un espace demi-largeur, commencez par le diviser avec la méthode de fractionnement. Pour les coordonnées verticales, la méthode parseInt est utilisée pour convertir la chaîne de caractères en une valeur numérique, mais en fait, si cette méthode, la conversion __ échoue, une exception appelée NumberFormatException sera levée et l'ensemble du programme sera interrompu de force __ Il est. Par conséquent, utilisez ~~ __ Exception Handling __ que vous venez d'étudier afin qu'il ne soit pas interrompu de force même si une telle exception se produit. Comme dans le code ci-dessus, placez la partie où l'exception peut se produire dans le bloc __try __ et écrivez le traitement après avoir intercepté l'exception dans le bloc __catch __ après le bloc try. Le bloc try est comme placer un réseau dans un endroit où le traitement des exceptions peut se produire, et il semble que le traitement à appliquer à l'exception sur le net est écrit dans le bloc catch (si vous faites une erreur, il serait utile que vous puissiez commenter). ). La deuxième puce peut être facilement déterminée en se référant aux carrés du tableau de type char. La troisième balle, mais c'est ennuyeux. Que la pierre de l'adversaire puisse être retournée ou non, c'est exactement le processus qui peut être considéré comme la base d'Othello. La méthode checkDiscsTurnedOverAllLine appelée dans le code ci-dessus est décrite en détail dans la section suivante.
Tout d'abord, je vais expliquer la classe Coordinates qui apparaîtra souvent dans les traitements futurs. Cette classe Coordinates est simplement une classe qui stocke les coordonnées x et y de la carte Othello sous forme de valeurs numériques. Les variables membres x et y sont rendues publiques pour éviter les problèmes d'écriture de code. À proprement parler, il doit être privé et une méthode publique dédiée doit être préparée pour référence et affectation, mais cette fois j'ai donné la priorité au plaisir. Je suis désolé. Il existe également une méthode de copie qui copie d'autres coordonnées et une méthode d'égalité qui détermine si les coordonnées sont égales aux coordonnées données.
class Coordinates {
public int x;
public int y;
Coordinates(int x, int y) {
this.x = x;
this.y = y;
}
Coordinates(Coordinates c) {
this.x = c.x;
this.y = c.y;
}
public void copy(Coordinates c) {
this.x = c.x;
this.y = c.y;
}
public boolean equals(int x, int y) {
if (this.x == x && this.y == y) {
return true;
} else {
return false;
}
}
}
Maintenant, parlons de la partie la plus désagréable de ce programme, le jugement de savoir si la pierre de l'adversaire peut être retournée ou non. Tout d'abord, voyons comment nous déterminons si nous pouvons retourner la pierre de l'adversaire lorsque nous jouons réellement avec Othello.
Je suis désolé, c'est difficile à comprendre, mais en mots, ça ressemble à ça. Ainsi, le code suivant est celui qui a essayé d'implémenter un tel processus.
//Déterminez si la pierre aux coordonnées saisies peut retourner la pierre de l'adversaire
//Renvoie les coordonnées de la pierre qui peut être retournée comme Arraylist
//Étant donné que la valeur maximale du nombre pouvant être retournée peut être déterminée par l'argument countMax,
//1 suffit pour juger si une pierre peut être placée à cette coordonnée
//Taille pour renvoyer toutes les coordonnées d'une pierre qui peut être retournée*à la taille
private ArrayList<Coordinates> checkDiscsTurnedOverAllLine(
char myColor, char enemyColor, Coordinates myCoordinates, int countMax)
{
ArrayList<Coordinates> discs = new ArrayList<Coordinates>();
//Scannez dans chaque direction
for (int d = 0; d < 8; d ++) {
discs.addAll(this.checkDiscsTurnedOverOneLine(myColor, enemyColor, myCoordinates, d));
//Si la valeur maximale de la pierre pouvant être retournée est dépassée, le traitement sera arrêté.
if (discs.size() > countMax) {
break;
}
}
return discs;
}
//Déterminez si la pierre aux coordonnées saisies peut retourner la pierre de l'adversaire
//La direction de balayage change en fonction de la direction de l'argument
// 0:0 degrés, 1:45 degrés, 2:90 degrés, 3:135 degrés, 4:180 degrés, 5:225 degrés, 6:270 degrés, 7:315 degrés
private ArrayList<Coordinates> checkDiscsTurnedOverOneLine(
char myColor, char enemyColor, Coordinates myCoordinates, int direction)
{
//Scannez une pierre qui peut être retournée
Coordinates currentCoordinates = new Coordinates(myCoordinates);
ArrayList<Coordinates> discs = new ArrayList<Coordinates>();
//Continuez à scanner à côté de vous pendant que les pierres de votre adversaire continuent
while (true) {
//Trouvez les coordonnées de la prochaine pierre
Coordinates nextDisc = this.getNextDiscCoordinates(currentCoordinates, direction);
if (nextDisc.equals(-1, -1)) {
//Renvoie une liste vide s'il n'y a pas de pierres à retourner
discs.clear();
break;
}
if (this.squares[nextDisc.y][nextDisc.x] == enemyColor) {
//S'il y a une pierre adverse à côté de vous, enregistrez-la temporairement dans la flip list
discs.add(nextDisc);
} else if (this.squares[nextDisc.y][nextDisc.x] == myColor) {
//Si vous avez votre propre pierre à côté, renvoyez la liste
break;
} else {
//S'il n'y a pas de pierre à côté, retournez une liste vide
discs.clear();
break;
}
//Passez à la pierre suivante
currentCoordinates.copy(nextDisc);
}
return discs;
}
//à côté de(Dépend de la direction)Renvoie les coordonnées de la pierre en
//Si les coordonnées sont hors de portée(-1, -1)rends le
private Coordinates getNextDiscCoordinates(Coordinates myDisc, int direction) {
//coordonnée x
int x = myDisc.x;
if (direction == 0 || direction == 1 || direction == 7) {
x ++; //0 degrés,45 degrés,315 degrés
} else if (direction == 3 || direction == 4 || direction == 5) {
x --; //135 degrés,180 degrés,225 degrés
}
//coordonnée y
int y = myDisc.y;
if (direction == 1 || direction == 2 || direction == 3) {
y --; //45 degrés,90 degrés,135 degrés
} else if (direction == 5 || direction == 6 || direction == 7) {
y ++; //225 degrés,270 degrés,315 degrés
}
if (x < 0 || this.size <= x || y < 0 || this.size <= y) {
//Lorsque les coordonnées sont hors de portée
return new Coordinates(-1, -1);
}
return new Coordinates(x, y);
}
Si vous voulez savoir si vous pouvez retourner la pierre de votre adversaire, appelez d'abord la méthode checkDiscsTurnedOverAllLine. Je vais examiner les huit directions comme AllLine, mais je voulais résumer le traitement de pièces similaires, j'ai donc décidé d'appeler la méthode checkDiscsTurnedOverOneLine pour chaque direction. Cette méthode checkDiscsTurnedOverOneLine ne traite qu'une seule direction spécifiée par la direction de l'argument, comme dans OneLine. Pour une certaine direction, les coordonnées de la pierre suivante sont obtenues en continu à partir de la méthode getNextDiscCoordinates (les coordonnées x et y sont incrémentées, décrémentées ou inchangées de 1 en spécifiant la direction). Dans la déclaration while, si les pierres de l'adversaire sont continues à côté du carré d'intérêt, __temporairement enregistrez __ dans la liste des disques de pierres qui peuvent les retourner. Si vous n'avez pas votre propre pierre après la pierre de l'adversaire que vous pourriez être en mesure de retourner, ou si vous sortez de la portée du plateau Othello, supprimez toutes les listes temporairement enregistrées. Au final, les coordonnées contenues dans la liste retournée par la méthode checkDiscsTurnedOverAllLine introduite au début sont la liste des pierres qui peuvent vraiment être retournées.
Enfin, je présenterai brièvement la partie qui décrit le déroulement du jeu Othello.
//Démarrez Othello
public void start() {
//Décidez de la pierre du joueur
this.askPlayerColor();
//Mettez la carte Othello en état immédiatement après le départ
this.initializeBoard();
this.printBoard();
this.turnCounter = 1;
int turnCounterMax = this.size*this.size - 4;
int skipCounter = 0;
//Le premier mouvement décide lequel
boolean isPlayerTurn = true;
if (this.playerColor == 'W') {
isPlayerTurn = false;
}
//Traitement de chaque tour
System.out.println("Démarrez Othello.");
int playerDiscNum;
int otherDiscNum;
while (this.turnCounter <= turnCounterMax) {
//Afficher le nombre de pierres pour le moment
playerDiscNum = this.countDisc(this.playerColor);
otherDiscNum = this.countDisc(this.otherColor);
System.out.print("tu= " + playerDiscNum + " ");
System.out.println("Adversaire= " + otherDiscNum);
if (isPlayerTurn) {
//Tour du joueur
//Déterminez si le joueur peut poser une pierre
if (! this.checkSquaresForNewDisc(this.playerColor, this.otherColor)) {
//Les tours des joueurs sont sautés
System.out.println("Votre tour a été sauté.");
if (skipCounter == 1) {
//Si le tour de l'adversaire a déjà été sauté, la partie se termine
break;
}
isPlayerTurn = !isPlayerTurn;
skipCounter ++;
continue;
}
System.out.println("Turn " + turnCounter + ":C'est ton tour.");
skipCounter = 0;
this.askNewCoordinates(this.playerColor, this.otherColor);
} else {
//Tour de l'adversaire
//Déterminez si l'adversaire peut mettre une pierre
if (! this.checkSquaresForNewDisc(this.otherColor, this.playerColor)) {
//Les tours des joueurs sont sautés
System.out.println("Le tour de l'adversaire a été sauté.");
if (skipCounter == 1) {
//Si le tour du joueur a déjà été sauté, le jeu se termine
break;
}
isPlayerTurn = !isPlayerTurn;
skipCounter ++;
continue;
}
//Tour de l'adversaire
System.out.println("Turn " + turnCounter + ":C'est au tour de votre adversaire.");
skipCounter = 0;
this.askNewCoordinates(this.otherColor, this.playerColor);
}
this.printBoard();
//Traitement pour le prochain tour
this.turnCounter ++;
isPlayerTurn = !isPlayerTurn;
}
//Jugement de victoire ou de défaite
playerDiscNum = this.countDisc(this.playerColor);
otherDiscNum = this.countDisc(this.otherColor);
System.out.print("tu= " + playerDiscNum + " ");
System.out.println("Adversaire= " + otherDiscNum);
if (playerDiscNum > otherDiscNum) {
System.out.println("Vous gagnez.");
} else if (playerDiscNum == otherDiscNum) {
System.out.println("C'est un tirage au sort.");
} else {
System.out.println("Tu as perdu.");
}
}
En passant, il n'est pas bon d'écrire 80 lignes dans une méthode comme la méthode de démarrage ci-dessus. Vous devez écrire un code facile à lire en regroupant des processus similaires en différentes méthodes ou en séparant certaines parties en différentes méthodes. __ est __, je n'ai pas eu assez de temps cette fois. Veuillez me pardonner car je l'améliorerai la prochaine fois que je le montrerai.
Maintenant, pour contrôler le déroulement du jeu, il y a une chose importante: __ Si vous ne pouvez pas du tout poser votre propre pierre, ce sera une passe et ce sera le tour de votre adversaire __. De plus, il ne faut pas oublier que si ni vous ni votre adversaire ne pouvez placer une pierre, le jeu se terminera __. Par conséquent, dans le code ci-dessus, une variable de type int skipCounter est créée et 1 est ajouté si l'un de vous ou l'autre partie est en situation de réussite, et si une pierre peut être placée, elle est réinitialisée à 0. Ensuite, le jeu se termine lorsque vous et votre adversaire passez successivement (skipCounter == 2).
Le reste du processus est plus simple que le contenu jusqu'à présent, je vais donc omettre l'explication. L'ensemble du programme mis en œuvre cette fois est décrit ci-dessous.
<détails> Puisque le plateau d'Othello est affiché à chaque fois que vous entrez une coordonnée, nous n'introduirons qu'un seul écran au lieu d'afficher le jeu entier paresseusement.
À la toute fin, vous et votre adversaire avez réussi, le jeu s'est donc terminé. Ce qui est difficile, c'est que nous n'avons pas encore implémenté le traitement de l'autre partie (PC), donc pour le moment nous devons entrer les coordonnées jusqu'à la pierre de l'autre partie __. Ce sentiment triste __ auto-fait __. Que fais-je depuis dimanche jour ……… Pour le moment, je suis maintenant dans un état où je peux au moins Othello, donc je vais mettre en œuvre la routine de réflexion de l'autre partie à l'avenir. Au début, on a l'impression de choisir au hasard à partir de l'endroit où vous pouvez poser la pierre, mais par exemple, au début du jeu, ne prenez pas trop de pierre, visez un coin collant dans la partie médiane, et laissez la vitesse de calcul vous parler dans la partie finale Je voudrais créer un algorithme __ qui n'a pas de lacunes dans les étapes précoces, intermédiaires et tardives, comme la pré-lecture. Je suis désolé que l'explication soit devenue redondante en raison du code source long cette fois. Encore merci à tous ceux qui ont lu jusqu'ici.import java.util.ArrayList;
import java.util.Scanner;
class OthelloBoardTest {
public static void main(String args[]) {
OthelloBoard ob = new OthelloBoard();
ob.start();
}
}
class OthelloBoard {
private int size; //Un côté du plateau d'Othello(8, 10, 12, 14, 16)
private char[][] squares; //État de chaque masse(B:noir, W:blanc, N:Pas de pierre)
private char playerColor; //Couleur de la pierre du joueur
private char otherColor; //La couleur de la pierre de l'adversaire
private int turnCounter; //Comptez le nombre de tours
private final String alphabets = "abcdefghijklmnop";
//Alphabet montrant les coordonnées horizontales
//constructeur
public OthelloBoard() {
this.size = 8;
// this.size = askBoardSize();
this.squares = new char[this.size][this.size];
}
//Démarrez Othello
public void start() {
//Décidez de la pierre du joueur
this.askPlayerColor();
//Mettez la carte Othello en état immédiatement après le départ
this.initializeBoard();
this.printBoard();
this.turnCounter = 1;
int turnCounterMax = this.size*this.size - 4;
int skipCounter = 0;
//Le premier mouvement décide lequel
boolean isPlayerTurn = true;
if (this.playerColor == 'W') {
isPlayerTurn = false;
}
//Traitement de chaque tour
System.out.println("Démarrez Othello.");
int playerDiscNum;
int otherDiscNum;
while (this.turnCounter <= turnCounterMax) {
//Afficher le nombre de pierres pour le moment
playerDiscNum = this.countDisc(this.playerColor);
otherDiscNum = this.countDisc(this.otherColor);
System.out.print("tu= " + playerDiscNum + " ");
System.out.println("Adversaire= " + otherDiscNum);
if (isPlayerTurn) {
//Tour du joueur
//Déterminez si le joueur peut poser une pierre
if (! this.checkSquaresForNewDisc(this.playerColor, this.otherColor)) {
//Les tours des joueurs sont sautés
System.out.println("Votre tour a été sauté.");
if (skipCounter == 1) {
//Si le tour de l'adversaire a déjà été sauté, la partie se termine
break;
}
isPlayerTurn = !isPlayerTurn;
skipCounter ++;
continue;
}
System.out.println("Turn " + turnCounter + ":C'est ton tour.");
skipCounter = 0;
this.askNewCoordinates(this.playerColor, this.otherColor);
} else {
//Tour de l'adversaire
//Déterminez si l'adversaire peut mettre une pierre
if (! this.checkSquaresForNewDisc(this.otherColor, this.playerColor)) {
//Les tours des joueurs sont sautés
System.out.println("Le tour de l'adversaire a été sauté.");
if (skipCounter == 1) {
//Si le tour du joueur a déjà été sauté, le jeu se termine
break;
}
isPlayerTurn = !isPlayerTurn;
skipCounter ++;
continue;
}
//Tour de l'adversaire
System.out.println("Turn " + turnCounter + ":C'est au tour de votre adversaire.");
skipCounter = 0;
this.askNewCoordinates(this.otherColor, this.playerColor);
}
this.printBoard();
//Traitement pour le prochain tour
this.turnCounter ++;
isPlayerTurn = !isPlayerTurn;
}
//Jugement de victoire ou de défaite
playerDiscNum = this.countDisc(this.playerColor);
otherDiscNum = this.countDisc(this.otherColor);
System.out.print("tu= " + playerDiscNum + " ");
System.out.println("Adversaire= " + otherDiscNum);
if (playerDiscNum > otherDiscNum) {
System.out.println("Vous gagnez.");
} else if (playerDiscNum == otherDiscNum) {
System.out.println("C'est un tirage au sort.");
} else {
System.out.println("Tu as perdu.");
}
}
//Retourne la pierre
public void turnOverDiscs(ArrayList<Coordinates> discs) {
for (int i = 0; i < discs.size(); i ++) {
int x = discs.get(i).x;
int y = discs.get(i).y;
if (this.squares[y][x] == 'B') {
this.squares[y][x] = 'W';
} else if (this.squares[y][x] == 'W') {
this.squares[y][x] = 'B';
}
}
}
//Endroit pour mettre des pierres(Un endroit où vous pouvez retourner d'autres pierres)Déterminez s'il y a
private boolean checkSquaresForNewDisc(char myColor, char enemyColor) {
for (int y = 0; y < this.size; y ++) {
for (int x = 0; x < this.size; x ++) {
if (this.squares[y][x] != 'N') {
continue;
}
ArrayList<Coordinates> discs = this.checkDiscsTurnedOverAllLine(
myColor, enemyColor, new Coordinates(x, y), 1);
if (discs.size() >= 1) {
return true;
}
}
}
return false;
}
//Acceptez l'entrée jusqu'à ce que l'endroit où placer la pierre soit décidé
private void askNewCoordinates(char myColor, char enemyColor) {
while (true) {
//contribution
System.out.println("\n Décidez où placer la pierre.");
System.out.println("[coordonnée x coordonnée y](Exemplea1):");
Scanner sc = new Scanner(System.in);
//Déterminez s'il est à portée de la planche Othello
Coordinates newDisc = this.checkCoordinatesRange(sc.nextLine());
if (newDisc.equals(-1, -1)) {
//Si les coordonnées sont incorrectes, ressaisissez
System.out.println("L'entrée est incorrecte.");
continue;
}
if (this.squares[newDisc.y][newDisc.x] != 'N') {
//Si une pierre a déjà été placée, la faire entrer
System.out.println("J'ai déjà une pierre.");
continue;
}
//Déterminez si la pierre de l'adversaire peut être retournée
ArrayList<Coordinates> discs = this.checkDiscsTurnedOverAllLine(
myColor, enemyColor, newDisc, this.size*this.size);
if (! discs.isEmpty()) {
//S'il y a une pierre qui peut être retournée, retournez la pierre
this.putDisc(myColor, newDisc);
this.turnOverDiscs(discs);
this.printDiscsTurnedOver(discs);
return;
}
System.out.println("Je ne peux pas retourner la pierre de l'adversaire.");
}
}
//Déterminez si les coordonnées saisies par le joueur sont à portée du plateau Othello
//Si le jugement réussit, les coordonnées sont utilisées, et si le jugement échoue, les coordonnées sont utilisées.(-1, -1)rends le
private Coordinates checkCoordinatesRange(String line) {
String[] tokens = line.split(" ");
//Lire les coordonnées horizontales de la première lettre de l'alphabet
int x = this.alphabets.indexOf(tokens[0]);
if (tokens[0].length() != 1 || x < 0 || this.size <= x) {
return new Coordinates(-1, -1);
}
//Lire les coordonnées verticales des caractères restants
int y;
try {
y = Integer.parseInt(tokens[1]);
if (y <= 0 || this.size < y) {
return new Coordinates(-1, -1);
}
} catch (NumberFormatException e) {
return new Coordinates(-1, -1);
}
return new Coordinates(x, y - 1);
}
//Déterminez si la pierre aux coordonnées saisies peut retourner la pierre de l'adversaire
//Renvoie les coordonnées de la pierre qui peut être retournée comme Arraylist
//Étant donné que la valeur maximale du nombre pouvant être retournée peut être déterminée par l'argument countMax,
//1 suffit pour juger si une pierre peut être placée à cette coordonnée
//Taille pour renvoyer toutes les coordonnées d'une pierre qui peut être retournée*à la taille
private ArrayList<Coordinates> checkDiscsTurnedOverAllLine(
char myColor, char enemyColor, Coordinates myCoordinates, int countMax)
{
ArrayList<Coordinates> discs = new ArrayList<Coordinates>();
//Scannez dans chaque direction
for (int d = 0; d < 8; d ++) {
discs.addAll(this.checkDiscsTurnedOverOneLine(myColor, enemyColor, myCoordinates, d));
//Si la valeur maximale de la pierre pouvant être retournée est dépassée, le traitement sera arrêté.
if (discs.size() > countMax) {
break;
}
}
return discs;
}
//Déterminez si la pierre aux coordonnées saisies peut retourner la pierre de l'adversaire
//La direction de balayage change en fonction de la direction de l'argument
// 0:0 degrés, 1:45 degrés, 2:90 degrés, 3:135 degrés, 4:180 degrés, 5:225 degrés, 6:270 degrés, 7:315 degrés
private ArrayList<Coordinates> checkDiscsTurnedOverOneLine(
char myColor, char enemyColor, Coordinates myCoordinates, int direction)
{
//Scannez une pierre qui peut être retournée
Coordinates currentCoordinates = new Coordinates(myCoordinates);
ArrayList<Coordinates> discs = new ArrayList<Coordinates>();
//Continuez à scanner à côté de vous pendant que les pierres de votre adversaire continuent
while (true) {
//Trouvez les coordonnées de la prochaine pierre
Coordinates nextDisc = this.getNextDiscCoordinates(currentCoordinates, direction);
if (nextDisc.equals(-1, -1)) {
//Renvoie une liste vide s'il n'y a pas de pierres à retourner
discs.clear();
break;
}
if (this.squares[nextDisc.y][nextDisc.x] == enemyColor) {
//S'il y a une pierre adverse à côté de vous, enregistrez-la temporairement dans la flip list
discs.add(nextDisc);
} else if (this.squares[nextDisc.y][nextDisc.x] == myColor) {
//Si vous avez votre propre pierre à côté, renvoyez la liste
break;
} else {
//S'il n'y a pas de pierre à côté, retournez une liste vide
discs.clear();
break;
}
//Passez à la pierre suivante
currentCoordinates.copy(nextDisc);
}
return discs;
}
//à côté de(Dépend de la direction)Renvoie les coordonnées de la pierre en
//Si les coordonnées sont hors de portée(-1, -1)rends le
private Coordinates getNextDiscCoordinates(Coordinates myDisc, int direction) {
//coordonnée x
int x = myDisc.x;
if (direction == 0 || direction == 1 || direction == 7) {
x ++; //0 degrés,45 degrés,315 degrés
} else if (direction == 3 || direction == 4 || direction == 5) {
x --; //135 degrés,180 degrés,225 degrés
}
//coordonnée y
int y = myDisc.y;
if (direction == 1 || direction == 2 || direction == 3) {
y --; //45 degrés,90 degrés,135 degrés
} else if (direction == 5 || direction == 6 || direction == 7) {
y ++; //225 degrés,270 degrés,315 degrés
}
if (x < 0 || this.size <= x || y < 0 || this.size <= y) {
//Lorsque les coordonnées sont hors de portée
return new Coordinates(-1, -1);
}
return new Coordinates(x, y);
}
//Accepte les entrées jusqu'à ce que la taille de la carte Othello soit décidée
//Cette méthode est le constructeur de ce.Si vous le collez sur le côté droit de la taille,
//Vous pouvez ajouter un processus pour entrer la taille du tableau Othello
private int askBoardSize() {
while (true) {
System.out.println("");
System.out.println("Veuillez décider de la longueur d'un côté de la planche Othello.");
System.out.print("[8, 10, 12, 14,L'un des 16]:");
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
if ("8".equals(line) || "10".equals(line) || "12".equals(line) ||
"14".equals(line) || "16".equals(line)) {
System.out.println("La longueur d'un côté de la planche Othello est" + line + "est.");
return Integer.parseInt(line);
}
System.out.println("L'entrée est incorrecte.");
}
}
//Acceptez l'entrée jusqu'à ce que la couleur de la pierre du joueur soit décidée
private void askPlayerColor() {
while (true) {
System.out.println("\n Choisissez votre pierre.");
System.out.println("[b (noir), w (blanc)N'importe quel]:");
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
if ("b".equals(line)) {
System.out.println("Votre pierre est noire.");
this.playerColor = 'B';
this.otherColor = 'W';
return;
} else if ("w".equals(line)) {
System.out.println("Votre pierre est blanche.");
this.playerColor = 'W';
this.otherColor = 'B';
return;
}
System.out.println("L'entrée est incorrecte.");
}
}
//Compter les pierres de la couleur spécifiée
private int countDisc(char myColor) {
int count = 0;
for (int y = 0; y < this.size; y ++) {
for (int x = 0; x < this.size; x ++) {
if (this.squares[y][x] == myColor) {
count ++;
}
}
}
return count;
}
//Mettez la carte Othello en état immédiatement après le départ
private void initializeBoard() {
for (int y = 0; y < this.size; y ++) {
for (int x = 0; x < this.size; x ++) {
squares[y][x] = 'N';
}
}
//Placez les pierres uniquement dans les 4 cases centrales
this.putDisc('B', this.size/2 - 1, this.size/2 - 1);
this.putDisc('B', this.size/2, this.size/2);
this.putDisc('W', this.size/2, this.size/2 - 1);
this.putDisc('W', this.size/2 - 1, this.size/2);
}
//Placez une pierre aux coordonnées spécifiées sur le plateau d'Othello
private void putDisc(char discColor, int x, int y) {
this.squares[y][x] = discColor;
}
private void putDisc(char discColor, Coordinates c) {
this.putDisc(discColor, c.x, c.y);
}
//Afficher toutes les coordonnées des pierres retournées
private void printDiscsTurnedOver(ArrayList<Coordinates> discs) {
System.out.println("J'ai retourné la pierre suivante.");
int count = 0;
for (int i = 0; i < discs.size(); i ++) {
System.out.print(this.alphabets.substring(discs.get(i).x, discs.get(i).x + 1) +
(discs.get(i).y + 1) + " ");
count ++;
if (count == 8) {
System.out.println("");
count = 0;
}
}
System.out.println("");
}
//Affichez la carte Othello sur la console
private void printBoard() {
this.printBoardAlphabetLine(); //Ligne alphabet
this.printBoardOtherLine("┏", "┳", "┓"); //Bord supérieur
for (int y = 0; y < this.size - 1; y ++) {
this.printBoardDiscLine(y); //Ligne affichant des pierres
this.printBoardOtherLine("┣", "╋", "┫"); //Interligne
}
this.printBoardDiscLine(this.size - 1); //Ligne affichant des pierres
this.printBoardOtherLine("┗", "┻", "┛"); //Bas de gamme
}
//Afficher l'alphabet indiquant la ligne du plateau Othello
private void printBoardAlphabetLine() {
String buf = " ";
for (int x = 0; x < this.size; x ++) {
buf += " " + this.alphabets.charAt(x);
}
System.out.println(buf);
}
//Afficher une ligne avec des pierres sur le plateau Othello
private void printBoardDiscLine(int y) {
String buf = String.format("%2d┃", y+1);
for (int x = 0; x < this.size; x ++) {
if (this.squares[y][x] == 'B') {
buf += "●┃";
} else if (this.squares[y][x] == 'W') {
buf += "○┃";
} else {
buf += " ┃";
}
}
System.out.println(buf);
}
//Afficher une ligne de lignes réglées représentant le cadre du plateau Othello
private void printBoardOtherLine(String left, String middle, String right) {
String buf = " " + left;
for (int x = 0; x < this.size - 1; x ++) {
buf += "━" + middle;
}
System.out.println(buf + "━" + right);
}
}
class Coordinates {
public int x;
public int y;
Coordinates(int x, int y) {
this.x = x;
this.y = y;
}
Coordinates(Coordinates c) {
this.x = c.x;
this.y = c.y;
}
public void copy(Coordinates c) {
this.x = c.x;
this.y = c.y;
}
public boolean equals(int x, int y) {
if (this.x == x && this.y == y) {
return true;
} else {
return false;
}
}
}
8. Essayez de courir
9. Tâches futures