[JAVA] Othello meiner Gedanken [Denkroutine 2]

1. 1. Einführung

Wie ich im vorherigen Artikel geschrieben habe, habe ich GitHub ausprobiert, aber es war ungefähr zu dieser Zeit, als die Zeit verging, ohne zu wissen, wie man es verwendet, selbst wenn ich die Übersetzungsfunktion von Google Chrome voll ausnutzte. Daher werden wir ab diesem Zeitpunkt Bitbucket verwenden, das die gleiche Funktion wie GitHub hat und auch Japanisch unterstützt. Da die Java-Quelle bisher mit Eclipse erstellt wurde, werden wir sie beim Verknüpfen von Eclipse mit Bitbucket codieren. Es tut mir leid GitHub.

Also beschloss ich, eine Denkroutine zu implementieren, die automatisch nach dem Ort sucht, an dem der Othello-Stein platziert werden soll, aber während ich ein wenig vom Codieren entfernt war, __ welche Art von Implementierung hatte ich bisher durchgeführt Ich verstehe überhaupt nicht __. Als ich einen Kommentar erhielt, als ich den Artikel von Thinking Routine 1 veröffentlichte, wurde die Anzahl der Zeilen der OthelloBoard-Klasse lächerlich groß (__460 Zeilen! __) und die Verbindung von __Variablen und Methoden wurde äußerst kompliziert. _war. Daher teilen wir zunächst die OthelloBoard-Klasse in mehrere Klassen auf und schreiben sie neu, damit Sie leichter verstehen, welche Klasse sich auf welche Variable / Methode bezieht.

Die OthelloBoard-Klasse wird jedoch selbst von mir, der sie geschrieben hat, nicht mehr verstanden. Wenn Sie eine Variable in eine andere Klasse verschieben oder einen kleinen Code neu schreiben, gibt Eclipse viele Fehlermeldungen aus. Egal wie viele Fehler Sie zerstören, es gibt kein Anzeichen dafür, dass es überhaupt enden wird ...! OthelloBoard-Klasse "Sei nicht dumm, rasiert. Sei mutig. Nur noch Zehntausende Male."

…… __ Die Bedeutung des Klassendesigns __ Es war ein Wochenende, an dem ich mich verwirrt fühlte.

2. Neues Klassendesign

Also habe ich versucht, die Variablen und Methoden in der OthelloBoard-Klasse auf die folgenden Klassen zu verteilen.

--Konfigurationsklasse zum Einstellen der Größe des Othello-Bretts (die Anzahl der Steine, die auf einer Seite platziert werden können) und der Farbe der Steine auf der Spielerseite zu Beginn des Spiels.

Wenn ich versuche, es von Anfang an neu zu schreiben, wird es außer Kontrolle geraten (es ist geworden), also werde ich es vorerst so lassen, wie es ist.

Konfigurationsklasse (und DiscState-Klasse)

In dieser Klasse können Sie die Größe des Othello-Bretts und die Farbe des Steins auf der Spielerseite über die Eingabeaufforderung eingeben, wenn Sie Othello starten. Wenn wir in Zukunft Elemente hinzufügen, die zu Beginn von Othello eingegeben werden sollen, planen wir, sie in dieser Klasse zu implementieren. In Zukunft möchte ich in der Lage sein, den Schwierigkeitsgrad der Denkroutine auf der feindlichen Seite zu wählen.

Konfigurationsklasse (zum Öffnen klicken)
import java.util.Scanner;

public class Config {
	private final int size;				//Eine Seite des Othello-Boards(8, 10, 12, 14, 16)
	private final char playerColor;		//Spieler Steinfarbe
	private final char otherColor;		//Die Farbe des Steins des Gegners

	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;
	}

	//Akzeptiert Eingaben, bis die Größe des Othello-Boards festgelegt ist
	private int askBoardSize() {
		while (true) {
			System.out.println("\n Bestimmen Sie die Länge einer Seite der Othello-Platte.");
			System.out.print("[6, 8, 10, 12, 14,Jeder von 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("Die Länge einer Seite des Othello-Bretts beträgt" + line + "ist.");
				return Integer.parseInt(line);
			}
			System.out.println("Die Eingabe ist falsch.");
		}
	}

	//Akzeptiere die Eingabe, bis die Farbe des Spielers festgelegt ist
	private char askPlayerColor() {
		while (true) {
			System.out.println("\n Entscheide dich für deinen Stein.");
			System.out.println("[b (schwarz), w (Weiß)Irgendein von]:");
			Scanner sc = new Scanner(System.in);
			String line = sc.nextLine();
			if ("b".equals(line)) {
				System.out.println("Dein Stein ist schwarz.");
				return DiscState.BLACK;
			} else if ("w".equals(line)) {
				System.out.println("Dein Stein ist weiß.");
				return DiscState.WHITE;
			}
			System.out.println("Die Eingabe ist falsch.");
		}
	}
}

Im vorherigen Code wurden 'B', 'W', das die Farbe des Steins angibt, und 'N', das angibt, dass der Stein nicht platziert wurde, __direkt __ geschrieben, aber dies sind __ magische Zahlen __ Es heißt __not good __ Existenz (in dem unwahrscheinlichen Fall, dass ein anderes Zeichen zugewiesen wird, muss der gesamte Code neu geschrieben werden, damit es leicht zu einer Brutstätte für Fehler und Bugs wird). Daher haben wir die DiscState-Klasse vorbereitet, die die Farbe und Anordnung der Steine darstellt, und den Zeichenkonstanten BLACK, WHITE bzw. NONE zugewiesen.

DiscState-Klasse (zum Öffnen klicken)
//Verwalten Sie Zeichenkonstanten, um die Farbe und Platzierung von Steinen auf dem Othello-Brett darzustellen
public final class DiscState {
	public static final char BLACK = 'B';		//Kuroishi ist platziert
	public static final char WHITE = 'W';		//Shiraishi ist platziert
	public static final char NONE = 'N';		//Es werden keine Steine gelegt

	private DiscState() {
	}
}

Endlich habe ich das Gefühl, die Verwendung von statisch und endgültig zu erkennen.

Board Klasse

Es ist eine Klasse, die den Zustand der Steine verwaltet, die auf jedem Quadrat der Othello-Tafel platziert sind, und wenn sie platziert sind, ob es sich um schwarze oder weiße Steine handelt. Außerdem wird die Anzahl der schwarzen und weißen Steine aktualisiert, wenn das Othello-Brett zu Beginn des Spiels initialisiert wird (Steine werden nur in den zentralen 4 Feldern platziert) und der Status der Steinplatzierung aktualisiert wird. Insbesondere aus dem zweiten Grund ist die Aktualisierung des Steinplatzierungsstatus auf die putDisc-Methode und die flipAllDiscs-Methode __ nur __ beschränkt, und die Nummer wird bei beiden Methoden gleichzeitig __ aktualisiert. Außerdem wird davon ausgegangen, dass die Größe des Othello-Boards von der Config-Klasse empfangen wird. Als ich anfing, das Othello-Programm zu erstellen, wurden die Koordinaten, die die Position des Steins darstellen, durch die Variablen vom Typ int x und y dargestellt, aber von der Mitte aus habe ich meine eigenen Klassenkoordinaten erstellt, um die Koordinaten darzustellen, und sie verwendet. Dieses Mal habe ich jedoch erfahren, dass es in der Java-Bibliothek (Point-Klasse) eine Klasse gibt, die Koordinaten vom Typ int darstellt, daher werde ich diese in Zukunft verwenden.

Board-Klasse (zum Öffnen klicken)
import java.awt.Point;
import java.util.ArrayList;

public class Board {
	private final int size;					//Eine Seite des Othello-Boards(8, 10, 12, 14, 16)
	private char[][] squares;				//Zeigt das Vorhandensein oder Fehlen von Steinen in jedem Quadrat und die Farbe an, wenn Steine vorhanden sind
	private int blackCounter;				//Anzahl der schwarzen Steine
	private int whiteCounter;				//Anzahl der 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;
		}
	}

	//Bringe das Othello-Brett zu Beginn des Spiels in den Zustand
	public void initializeBoard() {
		for (int y = 0; y < this.size; y ++) {
			for (int x = 0; x < this.size; x ++) {
				squares[y][x] = 'N';
			}
		}
		//Legen Sie Steine nur in die zentralen 4 Felder
		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));
	}

	//Platziere Steine an den angegebenen Koordinaten auf dem Othello-Brett und aktualisiere gleichzeitig die Anzahl der Steine
	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 ++;
		}
	}

	//Drehen Sie die Steine an den angegebenen Koordinaten auf dem Othello-Brett um und aktualisieren Sie gleichzeitig die Anzahl der Steine.
	public void flipAllDiscs(ArrayList<Point> discs) {
		for (Point disc : discs) {
			this.flipDisc(disc);
		}
	}

	//Drehen Sie die Steine an den angegebenen Koordinaten auf dem Othello-Brett um und aktualisieren Sie gleichzeitig die Anzahl der Steine.
	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 --;
		}
	}
}

Klasse drucken

Die Othello-Karte wird an der Eingabeaufforderung angezeigt, indem die Linien vollständig genutzt werden. Empfängt Variablen und Arrays für Board-Klassenmitglieder.

Druckklasse (zum Öffnen klicken)
import java.awt.Point;
import java.util.ArrayList;

public class Print {
	private Board board;										//Bundesstaat Othello Vorstand
	private final String alphabets = "abcdefghijklmnop";		//Alphabet mit horizontalen Koordinaten

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

	//Zeigen Sie die Othello-Karte auf der Konsole an
	public void printBoard() {
		this.printBoardAlphabetLine();							//Alphabetzeile
		this.printBoardOtherLine("┏", "┳", "┓");					//Oberkante
		for (int y = 0; y < this.board.getSize() - 1; y ++) {
			this.printBoardDiscLine(y);							//Linie, die Steine anzeigt
			this.printBoardOtherLine("┣", "╋", "┫");			//Zeilenabstand
		}
		this.printBoardDiscLine(this.board.getSize() - 1);		//Linie, die Steine anzeigt
		this.printBoardOtherLine("┗", "┻", "┛");				//unteres Ende
	}

	//Zeigen Sie die Anzahl der Steine des Spielers und des Gegners an
	public void printDiscNumber(char playerColor) {
		if (playerColor == DiscState.BLACK) {
			System.out.print("Sie= " + this.board.getCounter(DiscState.BLACK) + "  ");
			System.out.println("Gegner= " + this.board.getCounter(DiscState.WHITE));
		} else if (playerColor == DiscState.WHITE) {
			System.out.print("Sie= " + this.board.getCounter(DiscState.WHITE) + "  ");
			System.out.println("Gegner= " + this.board.getCounter(DiscState.BLACK));
		}
	}

	//Zeige alle Koordinaten der umgedrehten Steine
	public void printAllFlippedDiscs(ArrayList<Point> discs) {
		System.out.println("Ich drehte den nächsten Stein um.");
		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("");
	}

	//Zeigen Sie das Alphabet an, das die Zeile der Othello-Tafel angibt
	private void printBoardAlphabetLine() {
		String buf = "  ";
		for (int x = 0; x < this.board.getSize(); x ++) {
			buf += "   " + this.alphabets.charAt(x);
		}
		System.out.println(buf);
	}

	//Zeigen Sie eine Linie mit Steinen auf dem Othello-Brett an
	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);
	}

	//Zeigen Sie eine Linie von Linien an, die den Rahmen der Othello-Tafel darstellen
	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 Klasse

Angenommen, Sie haben einen Stein auf das angegebene Feld gelegt, bestimmen Sie, ob Sie den Stein des Gegners umdrehen können. Sie erhalten Informationen über die Mitgliedsvariablen / Arrays der Board-Klasse und darüber, wo und welche Farbe Stein in der nächsten Runde setzen soll. Um festzustellen, ob der Stein des Gegners umgedreht werden kann, habe ich versucht, ihn viel leichter als den vorherigen Code zu machen. Insbesondere für den Teil, der nach Steinen sucht, die in acht Richtungen (vertikal, horizontal und diagonal) gedreht werden können, haben wir zuerst die Directions-Klasse als Vektor für das Vorrücken eines Quadrats in jede Richtung vorbereitet.

Richtungsklasse (zum Öffnen klicken)
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 Grad
		directions.add(new Point(1, 1));		//45 Grad
		directions.add(new Point(0, 1));		//90 Grad
		directions.add(new Point(-1, 1));		//135 Grad
		directions.add(new Point(-1, 0));		//180 Grad
		directions.add(new Point(-1, -1));		//225 Grad
		directions.add(new Point(0, -1));		//270 Grad
		directions.add(new Point(1, -1));		//315 Grad
	}
}

Die Flip-Klasse bietet eine isAvailableSquare-Methode, die prüft, ob der Stein des Gegners umgedreht werden kann, indem ein Stein auf dem angegebenen Quadrat platziert wird, und eine getAllFlippedDiscs-Methode, die eine Liste der Koordinaten des umdrehbaren Steins abruft. Durch die Verwendung der Directions-Klasse und die Aufteilung der ähnlichen Verarbeitung in neue Methoden ist sie meiner Meinung nach viel sauberer als die vorherige.

Flip-Klasse (zum Öffnen klicken)
import java.awt.Point;
import java.util.ArrayList;

public class Flip {
	private Board board;					//Bundesstaat Othello Vorstand
	private char nextColor;					//Die Farbe des Steins, den Sie platzieren möchten
	private Point nextMove;					//Das Quadrat, auf dem der Stein platziert werden soll

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

	//Bestimmen Sie, ob das angegebene Quadrat den Stein des Gegners umdrehen kann
	public boolean isAvailableSquare() {
		//Finden Sie heraus, ob bereits Steine platziert sind
		if (!this.isEmptySquare(this.nextMove)) {
			return false;
		}
		//Finden Sie heraus, ob es Steine gibt, die in jede Richtung gedreht werden können
		for (Point direction : Directions.directions) {
			if (this.searchFlippedDiscs(this.nextMove, direction).size() > 0) {
				//Wenn es einen Stein gibt, der umgedreht werden kann
				return true;
			}
		}
		//Wenn es keinen Stein gibt, der in eine beliebige Richtung gedreht werden kann
		return false;
	}

	//Gibt eine Liste der Koordinaten des umgedrehten Steins zurück
	public ArrayList<Point> getAllFlippedDiscs() {
		ArrayList<Point> allFlippedDiscs = new ArrayList<Point>();
		for (Point direction : Directions.directions) {
			allFlippedDiscs.addAll(this.searchFlippedDiscs(this.nextMove, direction));
		}
		return allFlippedDiscs;
	}

	//Stellen Sie fest, ob sich Steine auf dem angegebenen Quadrat befinden
	private boolean isEmptySquare(Point square) {
		if (this.board.getSquareState(square) == DiscState.NONE) {
			return true;
		} else {
			return false;
		}
	}

	//Rufen Sie eine Liste der Koordinaten von Steinen ab, die in vertikaler, horizontaler und diagonaler Richtung gedreht werden können.
	//Registrieren Sie sich vorübergehend in der Liste, während die Steine des Gegners ununterbrochen sind, und geben Sie die Liste zurück, wenn Ihr eigener Stein unmittelbar danach kommt
	//Aber es gibt kein Quadrat daneben(Außerhalb der Tafel)Oder wenn es keine Steine gibt, löschen Sie die Liste und kehren Sie zurück(= Kann nicht umdrehen)
	private ArrayList<Point> searchFlippedDiscs(Point square, Point direction) {
		Point currentSquare = new Point(square);
		ArrayList<Point> flippedDiscs = new ArrayList<Point>();

		while(true) {
			//Finden Sie die Koordinaten des nächsten Quadrats
			Point nextSquare = this.getNextSquare(currentSquare, direction);
			//Beim Verlassen der Schleife abhängig von der Situation des angrenzenden Quadrats
			if (!this.isSquareInRange(nextSquare)) {
				//Wenn es kein Quadrat daneben gibt
				flippedDiscs.clear();
				break;
			} else if (board.getSquareState(nextSquare) == DiscState.NONE) {
				//Wenn es auf dem nächsten Platz keinen Stein gibt
				flippedDiscs.clear();
				break;
			} else if (board.getSquareState(nextSquare) == this.nextColor) {
				//Wenn Sie Ihren eigenen Stein auf dem nächsten Platz haben
				break;
			}
			//Wenn sich auf dem nächsten Feld ein Stein eines Gegners befindet, fahren Sie mit dem nächsten Feld fort
			flippedDiscs.add(nextSquare);
			currentSquare.setLocation(nextSquare);
		}
		return flippedDiscs;
	}

	//Finden Sie die Koordinaten des nächsten Quadrats in Bezug auf die angegebene Ausrichtung
	private Point getNextSquare(Point currentSquare, Point direction) {
		Point nextSquare = new Point(currentSquare.x, currentSquare.y);
		nextSquare.translate(direction.x, direction.y);
		return nextSquare;
	}

	//Überprüfen Sie, ob sich das angegebene Quadrat auf der Othello-Tafel befindet
	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;
		}
	}
}

Beachten Sie, dass die Flip-Klasse nur bestimmt, ob sie gespiegelt werden kann oder nicht, und dass die flipAllDiscs-Methode in der Board-Klasse den Flip-Prozess tatsächlich ausführt. In diesem Sinne wäre es möglicherweise besser gewesen, die Flip-Klasse als CheckFlip-Klasse zu bezeichnen.

Strategieklasse

Es ist eine Klasse, die beurteilt, ob es ein Quadrat gibt, auf das Sie einen Stein legen können, und wenn ja, wählt sie das Quadrat aus, auf das der Stein gelegt werden soll. Empfängt Variablen und Arrays für Board-Klassenmitglieder. Es wurde gegenüber dem vorherigen Code aufgrund der Verarbeitung (hauptsächlich Protokoll) geändert, die in Zukunft in Betracht gezogen wird. Zuerst habe ich eine Kandidatenklasse erstellt, die die Punktklasse erbt, damit ich dem Kandidaten des Quadrats, auf dem der Stein als nächstes platziert werden soll, einen Bewertungswert zuweisen und ein Flag setzen kann, wenn eine Bedingung erfüllt ist. Im Moment habe ich die Koordinaten des Steins, die umgedreht werden können, wenn ich einen Stein auf dieses Quadrat lege. Abhängig davon, ob er an der Ecke platziert werden kann und wie viele Umdrehungen es bisher gibt, nehme ich weniger oder mehr Steine usw. Wir planen, die Verarbeitung hinzuzufügen.

Kandidatenklasse (zum Öffnen klicken)
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;
	}
}

Als nächstes kommt die Strategieklasse.

Strategieklasse (zum Öffnen klicken)
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;

public class Strategy {
	private Config config;						//Grundeinstellung
	private Board board;						//Bundesstaat Othello Vorstand
	private char nextColor;						//Die Farbe des Steins, den Sie platzieren möchten
	ArrayList<Candidate> candidates;			//Platziere einen Stein(= Du kannst den Stein des Gegners umdrehen)Liste der Massen

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

	//Bestimmen Sie als Nächstes, ob ein Platz zum Aufsetzen eines Steins vorhanden ist
	public boolean hasCandidates() {
		this.searchCandidates();
		if (this.candidates.size() > 0) {
			return true;
		} else {
			return false;
		}
	}


	//Als nächstes wählen Sie ein Quadrat, auf das Sie den Stein legen möchten
	public Candidate getNextMove() {
		return this.getNextMoveRandom();
	}

	//Wähle zufällig ein Quadrat aus, um den Stein als nächstes zu platzieren
	private Candidate getNextMoveRandom() {
		return this.candidates.get(new Random().nextInt(this.candidates.size()));
	}

	//Platziere einen Stein(= Du kannst den Stein des Gegners umdrehen)Erkunde die 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()));
				}
			}
		}
	}
}

Nach dem letzten Mal ist die Denkroutine auf der feindlichen Seite so einfach wie die zufällige Auswahl einer an der Stelle, an der der Stein platziert werden kann. Das nächste Mal planen wir, diese Klasse noch erfüllender zu gestalten.

Spielerklasse

Dies ist eine Klasse, in der der Spieler eingeben kann, wo er den nächsten Stein platzieren soll. Es bestimmt, ob sich andere Steine im Quadrat der eingegebenen Koordinaten befinden, ob der Stein des Gegners umgedreht werden kann und ob die eingegebene Zeichenfolge als Koordinaten überhaupt korrekt ist. Ich bedauere, dass die Benennung der Klasse einfach war.

Spielerklasse (zum Öffnen klicken)
import java.awt.Point;
import java.util.Scanner;

public class Player {
	private Board board;									//Bundesstaat Othello Vorstand
	private char nextColor;								//Die Farbe des Steins, den Sie platzieren möchten

	private Candidate nextMove;							//Nächster Platz, um den Stein zu legen
	private Flip flip;										//Informationen zu Steinen, die umgedreht werden können

	private final String alphabets = "abcdefghijklmnop";	//Alphabet mit horizontalen Koordinaten

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

	//Akzeptieren Sie die Eingabe, bis der nächste Ort für das Ablegen des Steins festgelegt ist
	public Candidate askNextMove() {
		Scanner sc = new Scanner(System.in);
		while (true) {
			//Eingang
			System.out.println("\n Entscheiden Sie, wo der Stein abgelegt werden soll.");
			System.out.print("[x-Koordinate y-Koordinate](Beispiela1):");
			String line = sc.nextLine();
			//Stellen Sie fest, ob die vom Spieler eingegebenen Koordinaten im Bereich des Othello-Bretts liegen
			if (!this.checkCoordinatesRange(line)) {
				//Wenn die Koordinaten falsch sind, geben Sie sie erneut ein
				System.out.println("Die Eingabe ist falsch.");
				continue;
			}
			//Platziere einen Stein(= Du kannst den Stein des Gegners umdrehen)Bestimmen Sie, ob es sich um eine Masse handelt
			this.flip = new Flip(this.board, this.nextColor, this.nextMove);
			if (!this.flip.isAvailableSquare()) {
				System.out.println("Sie können keinen Stein auf dieses Quadrat legen.");
				continue;
			}
			this.nextMove.setAllFlippedDiscs(this.flip.getAllFlippedDiscs());
			return this.nextMove;
		}
	}

	//Stellen Sie fest, ob die vom Spieler eingegebenen Koordinaten im Bereich des Othello-Bretts liegen
	private boolean checkCoordinatesRange(String line) {
		String[] tokens = line.split(" ");
		//Lesen Sie die horizontalen Koordinaten aus dem ersten Buchstaben des Alphabets
		int x = this.alphabets.indexOf(tokens[0]);
		if (tokens[0].length() != 1 || x < 0 || x >= this.board.getSize()) {
			return false;
		}
		//Lesen Sie die vertikalen Koordinaten der verbleibenden Zeichen
		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;
	}
}

OthelloBoard Klasse

Diese Klasse behandelt den Fortschritt von Othellos Zügen. Ich denke, dass es viel einfacher wurde zu lesen, indem verschiedene andere Prozesse als separate Klassen getrennt wurden. Natürlich müssen wir noch daran arbeiten, aber ...

OthelloBoard-Klasse (zum Öffnen klicken)
public class OthelloBoard {
	private Config config;										//Grundeinstellung
	private Board board;										//Bundesstaat Othello Vorstand
	private int turnCountMax;									//Maximale Anzahl von Windungen(1 Seite*1 Seite-4)

	private int turnCounter;									//Aktuelle Anzahl der Umdrehungen
	private int skipCounter;									//Anzahl aufeinanderfolgender Sprünge(Othello endet, wenn es 2 wird)
	private boolean isPlayerTurn;								//True, wenn der Spieler an der Reihe ist
	private char nextColor;									//Welche Farbe an der Reihe ist, ist die aktuelle

	//Konstrukteur
	public OthelloBoard() {
		System.out.println("Starten Sie Othello.");
		//Grundeinstellung
		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());

		//Verarbeitung nur für die erste Runde
		this.turnCounter = 1;
		this.skipCounter = 0;
		this.isPlayerTurn = this.getFirstMove();
		this.nextColor = this.getNextColor();
	}

	//Starten Sie Othello
	public void start() {
		//Verarbeitung in jeder Runde
		while (this.turnCounter <= this.turnCountMax) {
			//Bestimmen Sie, ob Sie die Runde überspringen möchten
			Strategy strategy = new Strategy(this.config, this.board, this.nextColor);
			if (!strategy.hasCandidates()) {
				//Übertragen Sie die aktuelle Runde auf die feindliche Seite
				System.out.println("Die Wende wurde übersprungen.");
				this.skipCounter ++;
				if (this.skipCounter == 2) {
					System.out.println("Die Runde wird in einer Reihe übersprungen, also endet Othello.");
					break;
				}
				this.isPlayerTurn = !this.isPlayerTurn;
				this.nextColor = this.getNextColor();
				continue;
			}
			//Unten, wenn Sie die Kurve nicht überspringen
			//Entscheide, wo der Stein als nächstes abgelegt werden soll
			this.skipCounter = 0;
			Candidate nextMove;
			if (this.isPlayerTurn) {
				//Spieler an der Reihe
				System.out.println("\nTurn " + this.turnCounter + ":Du bist dran.");
				Player player = new Player(this.board, this.nextColor);
				nextMove = player.askNextMove();
			} else {
				//Der Gegner ist an der Reihe
				System.out.println("\nTurn " + this.turnCounter + ":Ihr Gegner ist an der Reihe.");
				nextMove = strategy.getNextMove();
			}
			//Zeigen Sie die Karte nach dem Umdrehen an
			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());
			//Verarbeitung für die nächste Runde
			this.turnCounter ++;
			this.isPlayerTurn = !this.isPlayerTurn;
			if (this.isPlayerTurn) {
				this.nextColor = this.config.getPlayerColor();
			} else {
				this.nextColor = this.config.getOtherColor();
			}
		}
		//Urteil über Sieg oder Niederlage
		this.printResult();
	}

	//Zeigen Sie das Ergebnis des Spiels
	private void printResult() {
		if (this.board.getCounter(DiscState.BLACK) > this.board.getCounter(DiscState.WHITE)) {
			System.out.println("Kuroishi gewinnt.");
		} else {
			System.out.println("Shiraishi gewinnt.");
		}
	}

	//Bestimmen Sie, welche Farbe an der Reihe ist
	private char getNextColor() {
		if (this.isPlayerTurn) {
			return this.config.getPlayerColor();
		} else {
			return this.config.getOtherColor();
		}
	}

	//Der erste Zug entscheidet, welcher
	//Wenn der Spieler Kuroishi ist, ist der Spieler der Erste und wenn Shiraishi der Gegner der Erste ist.
	private boolean getFirstMove() {
		if (this.config.getPlayerColor() == DiscState.BLACK) {
			return true;
		} else {
			return false;
		}
	}
}

OthelloBoardTest-Klasse

Es ist nur eine Klasse, die die OthelloBoard-Klasse aufruft.

OthelloBoardTest-Klasse (zum Öffnen klicken)
public class OthelloBoardTest {
	public static void main(String args[]) {
		OthelloBoard ob = new OthelloBoard();
		ob.start();
	}
}

3. 3. (Vorerst) Abgeschlossen ⇒ Festschreiben

Ich habe den zuvor erwähnten Quellcode an Bitbucket übergeben. ⇒ Mein Othello

Ich würde gerne eine Weile verschiedene Dinge mit Bitbucket ausprobieren und mich irgendwann an GitHub rächen. Darüber hinaus scheint die Methode zum Verknüpfen mit Eclipse für GitHub fast dieselbe zu sein.

Danke fürs Lesen!

Recommended Posts

Othello meiner Gedanken [Denkroutine 2]
Othello meiner Gedanken [Denkroutine 1]
Meine Gedanken zur Zukunft [Vorbereitung]
Meine Gedanken zur Equals-Methode (Java)
Meine Gedanken zur Zukunft [Gradle App Version ①]