[JAVA] Othello de mes pensées [Routine de réflexion 2]

1. 1. introduction

Comme je l'ai écrit dans l'article précédent, j'essayais GitHub, mais c'est à cette époque que seul le temps passait sans savoir comment l'utiliser même si j'utilisais pleinement la fonction de traduction de Google Chrome. Par conséquent, à partir de ce moment, nous utiliserons bitbucket, qui a la même fonction que GitHub et prend également en charge le japonais. De plus, comme la source Java a été créée jusqu'à présent avec Eclipse, nous la coderons tout en liant Eclipse à bitbucket. Je suis désolé GitHub.

J'ai donc décidé de mettre en place une routine de réflexion qui recherche automatiquement l'endroit où placer la pierre d'Othello, mais alors que j'étais un peu éloigné du codage __ Quel type d'implémentation avais-je jusqu'à présent? Je ne comprends pas du tout __. Comme j'ai reçu un commentaire lorsque j'ai publié l'article sur la routine de réflexion 1, le nombre de lignes dans la classe OthelloBoard est devenu ridiculement grand (__460 lignes! __), et la connexion entre __ variables et méthodes est devenue extrêmement compliquée. _était. Par conséquent, nous allons commencer par diviser la classe OthelloBoard en plusieurs classes et la réécrire afin qu'il soit un peu plus facile de comprendre quelle classe fait référence à quelle variable / méthode.

Cependant, la classe OthelloBoard n'est plus comprise même par moi qui l'ai écrite. Si vous déplacez une variable dans une autre classe ou réécrivez un peu de code, Eclipse vous donnera beaucoup de messages d'erreur. Peu importe le nombre d'erreurs que vous écrasez, il n'y a aucun signe que cela se terminera du tout ...! Cours d'OthelloBoard "Ne soyez pas stupide, rasé. Soyez courageux. Il ne reste que des dizaines de milliers de fois."

…… __ L'importance de la conception de la classe __ Ce fut un week-end que je me sentais confus.

2. Nouveau design de classe

J'ai donc essayé de distribuer les variables et les méthodes de la classe OthelloBoard aux classes suivantes.

Si j'essaye de le réécrire depuis le début, ce sera hors de contrôle (c'est devenu), donc je vais le laisser tel quel pour le moment.

Classe de configuration (et classe DiscState)

Cette classe vous permet de saisir la taille du plateau d'Othello et la couleur de la pierre côté joueur à partir de l'invite de commande au démarrage d'Othello. Dans le futur, lors de l'ajout d'éléments à saisir au début d'Othello, nous prévoyons de l'implémenter dans cette classe. A l'avenir, j'aimerais pouvoir choisir le niveau de difficulté de la routine de réflexion du côté ennemi.

Classe de configuration (cliquez pour ouvrir)
import java.util.Scanner;

public class Config {
	private final int size;				//Un côté du plateau d'Othello(8, 10, 12, 14, 16)
	private final char playerColor;		//Couleur de la pierre du joueur
	private final char otherColor;		//La couleur de la pierre de l'adversaire

	public Config() {
		this.size = this.askBoardSize();
		this.playerColor = this.askPlayerColor();
		if (this.playerColor == DiscState.BLACK) {
			this.otherColor = DiscState.WHITE;
		} else {
			this.otherColor = DiscState.BLACK;
		}
	}

	public int getSize() {
		return this.size;
	}
	public char getPlayerColor() {
		return this.playerColor;
	}
	public char getOtherColor() {
		return this.otherColor;
	}

	//Accepte les entrées jusqu'à ce que la taille de la carte Othello soit décidée
	private int askBoardSize() {
		while (true) {
			System.out.println("\n Déterminez la longueur d'un côté de la planche Othello.");
			System.out.print("[6, 8, 10, 12, 14,L'un des 16]:");
			Scanner sc = new Scanner(System.in);
			String line = sc.nextLine();
			if ("6".equals(line) || "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 char 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.");
				return DiscState.BLACK;
			} else if ("w".equals(line)) {
				System.out.println("Votre pierre est blanche.");
				return DiscState.WHITE;
			}
			System.out.println("L'entrée est incorrecte.");
		}
	}
}

Dans le code précédent, 'B', 'W', qui indique la couleur de la pierre, et 'N', qui indique que la pierre n'a pas été placée, étaient écrits __directement __, mais ce sont __ nombres magiques __ On l'appelle __not good __ existence (dans le cas peu probable où un autre caractère serait attribué, il sera nécessaire de réécrire tout le code, il est donc facile de devenir un foyer d'erreurs et de bogues). Par conséquent, nous avons préparé la classe DiscState qui représente la couleur et la disposition des pierres, et affecté les constantes de caractère NOIR, BLANC et AUCUN, respectivement.

Classe DiscState (cliquez pour ouvrir)
//Gérez les constantes de caractère pour représenter la couleur et le placement des pierres sur le plateau d'Othello
public final class DiscState {
	public static final char BLACK = 'B';		//Kuroishi est placé
	public static final char WHITE = 'W';		//Shiraishi est placé
	public static final char NONE = 'N';		//Aucune pierre n'est placée

	private DiscState() {
	}
}

Enfin, je sens que j'en suis venu à réaliser l'usage du statique et du final.

Classe de conseil

C'est une classe qui gère l'état des pierres placées sur chaque case du plateau d'Othello, et si elles sont placées, qu'il s'agisse de pierres noires ou de pierres blanches. De plus, le nombre de pierres noires et blanches sera mis à jour à chaque fois que le plateau Othello est initialisé au début de la partie (les pierres sont placées uniquement dans les 4 cases centrales) et le statut de placement des pierres est mis à jour. Surtout pour la deuxième raison, la mise à jour de l'état de placement des pierres est limitée à la méthode putDisc et à la méthode flipAllDiscs __ uniquement __, et le nombre est mis à jour __ en même temps dans les deux méthodes. De plus, il est supposé que la taille de la carte Othello sera reçue de la classe Config. Quand j'ai commencé à créer le programme Othello, les coordonnées représentant la position de la pierre étaient représentées par les variables de type int x et y, mais à partir du milieu, j'ai créé ma propre classe Coordinates pour représenter les coordonnées et je l'ai utilisée. Cependant, cette fois, j'ai appris qu'il existe une classe qui représente les coordonnées de type int dans la bibliothèque Java (classe Point), je vais donc l'utiliser à l'avenir.

Classe du tableau (cliquez pour ouvrir)
import java.awt.Point;
import java.util.ArrayList;

public class Board {
	private final int size;					//Un côté du plateau d'Othello(8, 10, 12, 14, 16)
	private char[][] squares;				//Indique la présence ou l'absence de pierres dans chaque carré, et la couleur s'il y a des pierres
	private int blackCounter;				//Nombre de pierres noires
	private int whiteCounter;				//Nombre de Shiraishi

	public Board(int size) {
		this.size = size;
		this.squares = new char[this.size][this.size];
		this.blackCounter = 0;
		this.whiteCounter = 0;
	}

	public int getSize() {
		return this.size;
	}
	public char[][] getSquares() {
		return this.squares;
	}
	public char getSquareState(Point p) {
		return this.squares[p.y][p.x];
	}
	public int getCounter(char color) {
		if (color == DiscState.BLACK) {
			return this.blackCounter;
		} else if (color == DiscState.WHITE) {
			return this.whiteCounter;
		} else {
			return this.size*this.size - this.blackCounter - this.whiteCounter;
		}
	}

	//Mettez le plateau d'Othello dans l'état au début du jeu
	public 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(DiscState.BLACK, new Point(this.size/2 - 1, this.size/2 - 1));
		this.putDisc(DiscState.BLACK, new Point(this.size/2, this.size/2));
		this.putDisc(DiscState.WHITE, new Point(this.size/2, this.size/2 - 1));
		this.putDisc(DiscState.WHITE, new Point(this.size/2 - 1, this.size/2));
	}

	//Placez les pierres aux coordonnées spécifiées sur le plateau Othello et mettez à jour le nombre de pierres en même temps
	public void putDisc(char color, Point p) {
		this.squares[p.y][p.x] = color;
		if (color == DiscState.BLACK) {
			this.blackCounter ++;
		} else if (color == DiscState.WHITE) {
			this.whiteCounter ++;
		}
	}

	//Retournez les pierres aux coordonnées spécifiées sur le plateau d'Othello et mettez à jour le nombre de pierres en même temps.
	public void flipAllDiscs(ArrayList<Point> discs) {
		for (Point disc : discs) {
			this.flipDisc(disc);
		}
	}

	//Retournez les pierres aux coordonnées spécifiées sur le plateau d'Othello et mettez à jour le nombre de pierres en même temps.
	private void flipDisc(Point p) {
		if (this.squares[p.y][p.x] == DiscState.BLACK) {
			this.squares[p.y][p.x] = DiscState.WHITE;
			this.blackCounter --;
			this.whiteCounter ++;
		} else if (this.squares[p.y][p.x] == DiscState.WHITE) {
			this.squares[p.y][p.x] = DiscState.BLACK;
			this.blackCounter ++;
			this.whiteCounter --;
		}
	}
}

Classe d'impression

Le tableau Othello est affiché sur l'invite de commande en utilisant pleinement les lignes réglées. Reçoit les variables et tableaux des membres de la classe de la carte.

Classe d'impression (cliquez pour ouvrir)
import java.awt.Point;
import java.util.ArrayList;

public class Print {
	private Board board;										//Carte State of Othello
	private final String alphabets = "abcdefghijklmnop";		//Alphabet montrant les coordonnées horizontales

	public Print(Board board) {
		this.board = board;
	}

	//Affichez la carte Othello sur la console
	public void printBoard() {
		this.printBoardAlphabetLine();							//Ligne alphabet
		this.printBoardOtherLine("┏", "┳", "┓");					//Bord supérieur
		for (int y = 0; y < this.board.getSize() - 1; y ++) {
			this.printBoardDiscLine(y);							//Ligne affichant des pierres
			this.printBoardOtherLine("┣", "╋", "┫");			//Interligne
		}
		this.printBoardDiscLine(this.board.getSize() - 1);		//Ligne affichant des pierres
		this.printBoardOtherLine("┗", "┻", "┛");				//Bas de gamme
	}

	//Afficher le nombre de pierres du joueur et de l'adversaire
	public void printDiscNumber(char playerColor) {
		if (playerColor == DiscState.BLACK) {
			System.out.print("tu= " + this.board.getCounter(DiscState.BLACK) + "  ");
			System.out.println("Adversaire= " + this.board.getCounter(DiscState.WHITE));
		} else if (playerColor == DiscState.WHITE) {
			System.out.print("tu= " + this.board.getCounter(DiscState.WHITE) + "  ");
			System.out.println("Adversaire= " + this.board.getCounter(DiscState.BLACK));
		}
	}

	//Afficher toutes les coordonnées des pierres retournées
	public void printAllFlippedDiscs(ArrayList<Point> discs) {
		System.out.println("J'ai retourné la pierre suivante.");
		int count = 0;
		for (Point disc : discs) {
			System.out.print(alphabets.substring(disc.x, disc.x + 1) + (disc.y + 1) + " ");
			count ++;
			if (count == 8) {
				System.out.println("");
				count = 0;
			}
		}
		System.out.println("");
	}

	//Afficher l'alphabet indiquant la ligne du plateau Othello
	private void printBoardAlphabetLine() {
		String buf = "  ";
		for (int x = 0; x < this.board.getSize(); 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.board.getSize(); x ++) {
			if (this.board.getSquareState(new Point(x, y)) == DiscState.BLACK) {
				buf += "●┃";
			} else if (this.board.getSquareState(new Point(x, y)) == DiscState.WHITE) {
				buf += "○┃";
			} else {
				buf += " ┃";
			}
		}
		System.out.println(buf);
	}

	//Afficher une ligne de lignes réglées représentant le cadre du plateau d'Othello
	private void printBoardOtherLine(String left, String middle, String right) {
		String buf = "  " + left;
		for (int x = 0; x < this.board.getSize() - 1; x ++) {
			buf += "━" + middle;
		}
		System.out.println(buf + "━" + right);
	}
}

Flip classe

En supposant que vous avez placé une pierre sur la case spécifiée, déterminez si vous pouvez retourner la pierre de l'adversaire. Vous recevrez des informations sur les variables membres / tableaux de la classe Board et où et quelle pierre de couleur mettre au tour suivant. Quant à déterminer si la pierre de l'adversaire peut être retournée, j'ai essayé de la rendre beaucoup plus légère que le code précédent. En particulier, pour la partie qui recherche des pierres pouvant être retournées dans huit directions (verticale, horizontale et diagonale), nous avons d'abord préparé la classe Directions comme vecteur pour avancer d'un carré dans chaque direction.

Classe Directions (cliquez pour ouvrir)
import java.awt.Point;
import java.util.ArrayList;

public class Directions {
	public static final ArrayList<Point> directions;

	static {
		directions = new ArrayList<Point>();
		directions.add(new Point(1, 0));		//0 degrés
		directions.add(new Point(1, 1));		//45 degrés
		directions.add(new Point(0, 1));		//90 degrés
		directions.add(new Point(-1, 1));		//135 degrés
		directions.add(new Point(-1, 0));		//180 degrés
		directions.add(new Point(-1, -1));		//225 degrés
		directions.add(new Point(0, -1));		//270 degrés
		directions.add(new Point(1, -1));		//315 degrés
	}
}

La classe Flip fournit une méthode isAvailableSquare qui vérifie si la pierre de l'adversaire peut être retournée en plaçant une pierre dans le carré spécifié, et une méthode getAllFlippedDiscs qui obtient une liste des coordonnées de la pierre qui peut être retournée. De plus, en utilisant la classe Directions et en séparant le traitement similaire en de nouvelles méthodes, je pense qu'elle est beaucoup plus propre que la précédente.

Flip class (cliquez pour ouvrir)
import java.awt.Point;
import java.util.ArrayList;

public class Flip {
	private Board board;					//Carte State of Othello
	private char nextColor;					//La couleur de la pierre que vous essayez de placer
	private Point nextMove;					//La place où la pierre va être placée

	public Flip(Board board, char nextColor, Point nextMove) {
		this.board = board;
		this.nextColor = nextColor;
		this.nextMove = nextMove;
	}

	//Déterminez si la case spécifiée peut retourner la pierre de l'adversaire
	public boolean isAvailableSquare() {
		//Découvrez s'il y a des pierres déjà placées
		if (!this.isEmptySquare(this.nextMove)) {
			return false;
		}
		//Découvrez s'il y a des pierres qui peuvent être retournées dans chaque direction
		for (Point direction : Directions.directions) {
			if (this.searchFlippedDiscs(this.nextMove, direction).size() > 0) {
				//S'il y a une pierre qui peut être retournée
				return true;
			}
		}
		//S'il n'y a pas de pierre qui peut être retournée dans n'importe quelle direction
		return false;
	}

	//Renvoie une liste des coordonnées de la pierre à retourner
	public ArrayList<Point> getAllFlippedDiscs() {
		ArrayList<Point> allFlippedDiscs = new ArrayList<Point>();
		for (Point direction : Directions.directions) {
			allFlippedDiscs.addAll(this.searchFlippedDiscs(this.nextMove, direction));
		}
		return allFlippedDiscs;
	}

	//Déterminez s'il y a des pierres dans le carré spécifié
	private boolean isEmptySquare(Point square) {
		if (this.board.getSquareState(square) == DiscState.NONE) {
			return true;
		} else {
			return false;
		}
	}

	//Obtenez une liste des coordonnées des pierres qui peuvent être retournées dans l'une des directions verticale, horizontale et diagonale.
	//Inscrivez-vous temporairement dans la liste pendant que les pierres de l'adversaire sont continues, et renvoyez la liste lorsque votre propre pierre vient immédiatement après cela
	//Mais il n'y a pas de carré à côté(En dehors du plateau)Ou s'il n'y a pas de pierres, effacez la liste et revenez(= Impossible de retourner)
	private ArrayList<Point> searchFlippedDiscs(Point square, Point direction) {
		Point currentSquare = new Point(square);
		ArrayList<Point> flippedDiscs = new ArrayList<Point>();

		while(true) {
			//Trouvez les coordonnées du carré suivant
			Point nextSquare = this.getNextSquare(currentSquare, direction);
			//A la sortie de la boucle en fonction de la situation de la place adjacente
			if (!this.isSquareInRange(nextSquare)) {
				//S'il n'y a pas de carré à côté
				flippedDiscs.clear();
				break;
			} else if (board.getSquareState(nextSquare) == DiscState.NONE) {
				//S'il n'y a pas de pierre dans la case suivante
				flippedDiscs.clear();
				break;
			} else if (board.getSquareState(nextSquare) == this.nextColor) {
				//Si vous avez votre propre pierre sur la place suivante
				break;
			}
			//S'il y a une pierre adverse dans la case suivante, passez à la case suivante
			flippedDiscs.add(nextSquare);
			currentSquare.setLocation(nextSquare);
		}
		return flippedDiscs;
	}

	//Trouvez les coordonnées du carré suivant par rapport à l'orientation spécifiée
	private Point getNextSquare(Point currentSquare, Point direction) {
		Point nextSquare = new Point(currentSquare.x, currentSquare.y);
		nextSquare.translate(direction.x, direction.y);
		return nextSquare;
	}

	//Vérifiez si le carré spécifié est dans le tableau Othello
	private boolean isSquareInRange(Point square) {
		if (0 <= square.x && square.x < this.board.getSize() &&
			0 <= square.y && square.y < this.board.getSize()) {
			return true;
		} else {
			return false;
		}
	}
}

Notez que la classe Flip détermine uniquement si elle peut être retournée ou non, et c'est la méthode flipAllDiscs de la classe Board qui exécute réellement le processus de retournement. En ce sens, il aurait peut-être été préférable de nommer la classe Flip comme la classe CheckFlip.

Classe de stratégie

C'est une classe qui juge s'il y a une case où une pierre peut être placée, et si c'est le cas, sélectionne sur quelle case placer la pierre. Reçoit les variables et tableaux des membres de la classe de la carte. Il a été modifié par rapport au code précédent en raison du traitement (principalement le journal) envisagé à l'avenir. Tout d'abord, j'ai créé une classe Candidate qui hérite de la classe Point afin que je puisse attribuer une valeur d'évaluation au candidat du carré où la pierre doit être placée ensuite, ou définir un drapeau lorsqu'une condition est remplie. En ce moment, je garde les coordonnées de la pierre qui peut être retournée lorsque je pose une pierre sur cette case, mais par exemple, selon qu'elle peut être placée au coin et le nombre de tours jusqu'à présent, je prendrai moins ou plus de pierres, etc. Nous prévoyons d'ajouter un traitement.

<détails>

Classe de candidat (cliquez pour ouvrir) </ summary>

import java.awt.Point;
import java.util.ArrayList;

public class Candidate extends Point {
	private ArrayList<Point> allFlippedDiscs;

	public Candidate(Point point) {
		super(point);
	}
	public Candidate(Point point, ArrayList<Point> allFlippedDiscs) {
		super(point);
		this.allFlippedDiscs = allFlippedDiscs;
	}
	public void setAllFlippedDiscs(ArrayList<Point> allFlippedDiscs) {
		this.allFlippedDiscs = allFlippedDiscs;
	}
	public ArrayList<Point> getAllFlippedDiscs() {
		return this.allFlippedDiscs;
	}
}

Vient ensuite la classe de stratégie.

<détails>

Classe de stratégie (cliquez pour ouvrir) </ summary>

import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;

public class Strategy {
	private Config config;						//Réglage initial
	private Board board;						//Carte State of Othello
	private char nextColor;						//La couleur de la pierre que vous essayez de placer
	ArrayList<Candidate> candidates;			//Placez une pierre(= Vous pouvez retourner la pierre de l'adversaire)Liste des messes

	public Strategy(Config config, Board board, char nextColor) {
		this.config = config;
		this.board = board;
		this.nextColor = nextColor;
		this.candidates = new ArrayList<Candidate>();
	}

	//Ensuite, déterminez s'il y a un espace sur lequel poser une pierre
	public boolean hasCandidates() {
		this.searchCandidates();
		if (this.candidates.size() > 0) {
			return true;
		} else {
			return false;
		}
	}


	//Ensuite, choisissez un carré sur lequel poser la pierre
	public Candidate getNextMove() {
		return this.getNextMoveRandom();
	}

	//Choisissez au hasard une case pour mettre la pierre à côté
	private Candidate getNextMoveRandom() {
		return this.candidates.get(new Random().nextInt(this.candidates.size()));
	}

	//Placez une pierre(= Vous pouvez retourner la pierre de l'adversaire)Explorez la masse
	private void searchCandidates() {
		for (int y = 0; y < this.board.getSize(); y ++) {
			for (int x = 0; x < this.board.getSize(); x ++) {
				Point currentSquare = new Point(x, y);
				Flip flip = new Flip(this.board, this.nextColor, currentSquare);
				if (flip.isAvailableSquare()) {
					this.candidates.add(new Candidate(currentSquare, flip.getAllFlippedDiscs()));
				}
			}
		}
	}
}

Dans la continuité de la dernière fois, la routine de réflexion du côté ennemi est aussi simple que d'en choisir une au hasard à partir de l'endroit où la pierre peut être placée. La prochaine fois, nous prévoyons de rendre ce cours encore plus épanouissant.

Classe de joueur

C'est une classe qui permet au joueur d'entrer où placer la pierre suivante. Il détermine s'il y a d'autres pierres dans le carré des coordonnées entrées, si la pierre de l'adversaire peut être retournée et si la chaîne de caractères saisie est correcte en tant que coordonnées en premier lieu. Je regrette que la dénomination de la classe ait été facile.

<détails>

Classe de joueur (cliquez pour ouvrir) </ summary>

import java.awt.Point;
import java.util.Scanner;

public class Player {
	private Board board;									//Carte State of Othello
	private char nextColor;								//La couleur de la pierre que vous essayez de placer

	private Candidate nextMove;							//Endroit suivant pour mettre la pierre
	private Flip flip;										//Informations sur les pierres qui peuvent être retournées

	private final String alphabets = "abcdefghijklmnop";	//Alphabet montrant les coordonnées horizontales

	public Player(Board board, char nextColor) {
		this.board = board;
		this.nextColor = nextColor;
		this.nextMove = new Candidate(new Point(0, 0));
	}

	//Acceptez l'entrée jusqu'à ce que le prochain endroit pour poser la pierre soit décidé
	public Candidate askNextMove() {
		Scanner sc = new Scanner(System.in);
		while (true) {
			//contribution
			System.out.println("\n Décidez où placer la pierre.");
			System.out.print("[coordonnée x coordonnée y](Exemplea1):");
			String line = sc.nextLine();
			//Déterminez si les coordonnées saisies par le joueur sont à portée du plateau Othello
			if (!this.checkCoordinatesRange(line)) {
				//Si les coordonnées sont incorrectes, ressaisissez
				System.out.println("L'entrée est incorrecte.");
				continue;
			}
			//Placez une pierre(= Vous pouvez retourner la pierre de l'adversaire)Déterminez s'il s'agit d'une masse
			this.flip = new Flip(this.board, this.nextColor, this.nextMove);
			if (!this.flip.isAvailableSquare()) {
				System.out.println("Vous ne pouvez pas mettre une pierre sur cette case.");
				continue;
			}
			this.nextMove.setAllFlippedDiscs(this.flip.getAllFlippedDiscs());
			return this.nextMove;
		}
	}

	//Déterminez si les coordonnées saisies par le joueur sont à portée du plateau Othello
	private boolean 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 || x >= this.board.getSize()) {
			return false;
		}
		//Lire les coordonnées verticales des caractères restants
		int y;
		try {
			y = Integer.parseInt(tokens[1]);
		} catch (NumberFormatException e) {
			return false;
		}
		if (y <= 0 || y > this.board.getSize()) {
			return false;
		}

		this.nextMove.setLocation(x, y - 1);
		return true;
	}
}

Cours d'OthelloBoard

Cette classe gère la progression des tours d'Othello. Je pense que c'est devenu beaucoup plus facile à lire en séparant divers autres processus en classes séparées. Bien sûr, nous devons encore y travailler, mais ...

Classe OthelloBoard (cliquez pour ouvrir)
public class OthelloBoard {
	private Config config;										//Réglage initial
	private Board board;										//Carte State of Othello
	private int turnCountMax;									//Nombre maximum de tours(1 côté*1 côté-4)

	private int turnCounter;									//Nombre actuel de tours
	private int skipCounter;									//Nombre de sauts consécutifs(Quand il devient 2, Othello se termine)
	private boolean isPlayerTurn;								//Vrai si le tour actuel est le tour du joueur
	private char nextColor;									//Le tour de quelle couleur est le tour actuel

	//constructeur
	public OthelloBoard() {
		System.out.println("Démarrez Othello.");
		//Réglage initial
		this.config = new Config();
		this.board = new Board(this.config.getSize());
		this.board.initializeBoard();
		this.turnCountMax = this.config.getSize()*this.config.getSize() - 4;
		Print print = new Print(this.board);
		print.printBoard();
		print.printDiscNumber(this.config.getPlayerColor());

		//Traitement uniquement pour le premier tour
		this.turnCounter = 1;
		this.skipCounter = 0;
		this.isPlayerTurn = this.getFirstMove();
		this.nextColor = this.getNextColor();
	}

	//Démarrez Othello
	public void start() {
		//Traitement à chaque tour
		while (this.turnCounter <= this.turnCountMax) {
			//Déterminez s'il faut sauter le virage
			Strategy strategy = new Strategy(this.config, this.board, this.nextColor);
			if (!strategy.hasCandidates()) {
				//Transférer le tour actuel du côté ennemi
				System.out.println("Le virage a été sauté.");
				this.skipCounter ++;
				if (this.skipCounter == 2) {
					System.out.println("Termine Othello car les virages ont été sautés d'affilée.");
					break;
				}
				this.isPlayerTurn = !this.isPlayerTurn;
				this.nextColor = this.getNextColor();
				continue;
			}
			//Ci-dessous, si vous ne sautez pas le virage
			//Décidez où mettre la pierre ensuite
			this.skipCounter = 0;
			Candidate nextMove;
			if (this.isPlayerTurn) {
				//Tour du joueur
				System.out.println("\nTurn " + this.turnCounter + ":C'est ton tour.");
				Player player = new Player(this.board, this.nextColor);
				nextMove = player.askNextMove();
			} else {
				//Tour de l'adversaire
				System.out.println("\nTurn " + this.turnCounter + ":C'est au tour de votre adversaire.");
				nextMove = strategy.getNextMove();
			}
			//Affichez le tableau après l'avoir retourné
			this.board.putDisc(this.nextColor, nextMove);
			this.board.flipAllDiscs(nextMove.getAllFlippedDiscs());
			Print print = new Print(this.board);
			print.printBoard();
			print.printDiscNumber(this.config.getPlayerColor());
			print.printAllFlippedDiscs(nextMove.getAllFlippedDiscs());
			//Traitement pour le prochain tour
			this.turnCounter ++;
			this.isPlayerTurn = !this.isPlayerTurn;
			if (this.isPlayerTurn) {
				this.nextColor = this.config.getPlayerColor();
			} else {
				this.nextColor = this.config.getOtherColor();
			}
		}
		//Jugement de victoire ou de défaite
		this.printResult();
	}

	//Montrez le résultat du jeu
	private void printResult() {
		if (this.board.getCounter(DiscState.BLACK) > this.board.getCounter(DiscState.WHITE)) {
			System.out.println("Kuroishi gagne.");
		} else {
			System.out.println("Shiraishi gagne.");
		}
	}

	//Déterminez le tour de couleur du tour actuel
	private char getNextColor() {
		if (this.isPlayerTurn) {
			return this.config.getPlayerColor();
		} else {
			return this.config.getOtherColor();
		}
	}

	//Le premier mouvement décide lequel
	//Si le joueur est Kuroishi, le joueur est le premier, et si Shiraishi, l'adversaire est le premier.
	private boolean getFirstMove() {
		if (this.config.getPlayerColor() == DiscState.BLACK) {
			return true;
		} else {
			return false;
		}
	}
}

OthelloBoardTest classe

C'est juste une classe qui appelle la classe OthelloBoard.

<détails>

Classe OthelloBoardTest (cliquez pour ouvrir) </ summary>

public class OthelloBoardTest {
	public static void main(String args[]) {
		OthelloBoard ob = new OthelloBoard();
		ob.start();
	}
}

3. 3. (Pour le moment) Terminé ⇒ Valider

J'ai commis le code source que j'ai mentionné plus tôt sur Bitbucket. ⇒ Mon Othello

J'aimerais essayer diverses choses avec Bitbucket pendant un moment et me venger sur GitHub à un moment donné. De plus, la méthode de liaison avec eclipse semble être presque la même pour GitHub.

Merci pour la lecture!