diff --git a/.classpath b/.classpath
index 07b86b3..99d9707 100644
--- a/.classpath
+++ b/.classpath
@@ -7,5 +7,6 @@
+
diff --git a/src/dev/kske/chess/board/Board.java b/src/dev/kske/chess/board/Board.java
index b34c68c..b69f5c6 100644
--- a/src/dev/kske/chess/board/Board.java
+++ b/src/dev/kske/chess/board/Board.java
@@ -14,7 +14,7 @@ import dev.kske.chess.board.Piece.Type;
* Created: 01.07.2019
* Author: Kai S. K. Engelbart
*/
-public class Board {
+public class Board implements Cloneable {
private Piece[][] boardArr;
private Map kingPos;
@@ -35,10 +35,7 @@ public class Board {
Piece piece = getPos(move);
if (piece == null || !piece.isValidMove(move)) return false;
else {
- /*
- * Move piece
- * Save destination piece for possible canceling of the move
- */
+ // Move piece
Piece capturePiece = move(move);
// Revert move if it caused a check for its team
@@ -223,6 +220,32 @@ public class Board {
boardArr[i][j] = null;
}
+ /**
+ * @return A new instance of this class with a shallow copy of both
+ * {@code kingPos} and {code boardArr}
+ */
+ @Override
+ public Object clone() {
+ Board board = null;
+ try {
+ board = (Board) super.clone();
+ } catch (CloneNotSupportedException ex) {
+ ex.printStackTrace();
+ }
+ board.boardArr = new Piece[8][8];
+ for (int i = 0; i < 8; i++)
+ for (int j = 0; j < 8; j++) {
+ if (boardArr[i][j] == null) continue;
+ board.boardArr[i][j] = (Piece) boardArr[i][j].clone();
+ board.boardArr[i][j].board = board;
+ }
+
+ board.kingPos = new HashMap<>();
+ board.kingPos.putAll(kingPos);
+
+ return board;
+ }
+
public Piece get(Position pos) {
return boardArr[pos.x][pos.y];
}
diff --git a/src/dev/kske/chess/board/Piece.java b/src/dev/kske/chess/board/Piece.java
index 2ef3db7..fbb8c0c 100644
--- a/src/dev/kske/chess/board/Piece.java
+++ b/src/dev/kske/chess/board/Piece.java
@@ -9,7 +9,7 @@ import java.util.List;
* Created: 01.07.2019
* Author: Kai S. K. Engelbart
*/
-public abstract class Piece {
+public abstract class Piece implements Cloneable {
protected Color color;
protected Board board;
@@ -51,6 +51,17 @@ public abstract class Piece {
return board.getDest(move) == null || board.getDest(move).getColor() != getColor();
}
+ @Override
+ public Object clone() {
+ Piece piece = null;
+ try {
+ piece = (Piece) super.clone();
+ } catch (CloneNotSupportedException ex) {
+ ex.printStackTrace();
+ }
+ return piece;
+ }
+
public abstract Type getType();
public Color getColor() { return color; }
diff --git a/src/dev/kske/chess/game/AIPlayer.java b/src/dev/kske/chess/game/AIPlayer.java
index 4cfc702..75ad70d 100644
--- a/src/dev/kske/chess/game/AIPlayer.java
+++ b/src/dev/kske/chess/game/AIPlayer.java
@@ -1,5 +1,7 @@
package dev.kske.chess.game;
+import javax.swing.SwingUtilities;
+
import dev.kske.chess.board.Board;
import dev.kske.chess.board.Move;
import dev.kske.chess.board.Piece;
@@ -13,7 +15,7 @@ import dev.kske.chess.board.Piece.Color;
*/
public class AIPlayer extends Player {
- private Move bestMove;
+ private Move bestMove;
private int count;
public AIPlayer(Board board, Color color) {
@@ -22,10 +24,12 @@ public class AIPlayer extends Player {
@Override
public void requestMove() {
- count = 0;
- findBestMove(board, color, 0);
- System.out.println("Moved processes: " + count);
- game.onMove(this, bestMove);
+ new Thread(() -> {
+ count = 0;
+ findBestMove((Board) board.clone(), color, 0);
+ System.out.println("Moved processes: " + count);
+ SwingUtilities.invokeLater(() -> game.onMove(this, bestMove));
+ }).start();
}
private int findBestMove(Board board, Color color, int depth) {
diff --git a/src/dev/kske/chess/game/Game.java b/src/dev/kske/chess/game/Game.java
index 2179d64..9953e23 100644
--- a/src/dev/kske/chess/game/Game.java
+++ b/src/dev/kske/chess/game/Game.java
@@ -36,8 +36,6 @@ public class Game {
public void onMove(Player player, Move move) {
if (board.getPos(move).getColor() == player.color && board.attemptMove(move)) {
System.out.printf("%s: %s%n", player.color, move);
- boardPanel.repaint();
-
GameState eventType = board.getGameEventType(board.getDest(move).getColor().opposite());
switch (eventType) {
case CHECKMATE:
@@ -47,7 +45,9 @@ public class Game {
case CHECK:
System.out.printf("%s in check!%n", player.color);
default:
+ boardPanel.repaint();
players.get(player.color.opposite()).requestMove();
+
}
} else {
System.out.printf("%s: Illegal move!%n", player.getColor());
diff --git a/src/dev/kske/chess/game/NaturalPlayer.java b/src/dev/kske/chess/game/NaturalPlayer.java
index b30225d..9229096 100644
--- a/src/dev/kske/chess/game/NaturalPlayer.java
+++ b/src/dev/kske/chess/game/NaturalPlayer.java
@@ -33,6 +33,7 @@ public class NaturalPlayer extends Player {
pos = new Position(evt.getPoint().x / boardPanel.getTileSize(),
evt.getPoint().y / boardPanel.getTileSize());
+ Board board = (Board) NaturalPlayer.this.board.clone();
if (board.get(pos) != null && board.get(pos).getColor() == color)
boardPanel.displayMoves(board.getMoves(pos));
else pos = null;
diff --git a/src/dev/kske/chess/test/BoardCloneTest.java b/src/dev/kske/chess/test/BoardCloneTest.java
new file mode 100644
index 0000000..5c7df20
--- /dev/null
+++ b/src/dev/kske/chess/test/BoardCloneTest.java
@@ -0,0 +1,44 @@
+package dev.kske.chess.test;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotSame;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import dev.kske.chess.board.Board;
+import dev.kske.chess.board.Piece.Color;
+import dev.kske.chess.board.Queen;
+
+/**
+ * Project: Chess
+ * File: BoardCloneTest.java
+ * Created: 08.07.2019
+ * Author: Kai S. K. Engelbart
+ */
+class BoardCloneTest {
+
+ Board board;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @BeforeEach
+ void setUp() throws Exception {
+ board = new Board();
+ }
+
+ /**
+ * Test method for {@link dev.kske.chess.board.Board#clone()}.
+ */
+ @Test
+ void testClone() {
+ Board clone = (Board) board.clone();
+ assertNotSame(clone, board);
+ assertNotSame(clone.getBoardArr(), board.getBoardArr());
+
+ clone.getBoardArr()[0][0] = new Queen(Color.BLACK, clone);
+ assertNotEquals(clone.getBoardArr()[0][0], board.getBoardArr()[0][0]);
+ }
+
+}