Fixed rendering
+ Cloning support in Board and Piece - Using clones for board operations that interfere with rendering - Fixed repaint calls + Unit test for testing board cloning
This commit is contained in:
parent
31c393150b
commit
8283866d62
@ -7,5 +7,6 @@
|
|||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="lib" path="res"/>
|
<classpathentry kind="lib" path="res"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
@ -14,7 +14,7 @@ import dev.kske.chess.board.Piece.Type;
|
|||||||
* Created: <strong>01.07.2019</strong><br>
|
* Created: <strong>01.07.2019</strong><br>
|
||||||
* Author: <strong>Kai S. K. Engelbart</strong>
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
*/
|
*/
|
||||||
public class Board {
|
public class Board implements Cloneable {
|
||||||
|
|
||||||
private Piece[][] boardArr;
|
private Piece[][] boardArr;
|
||||||
private Map<Color, Position> kingPos;
|
private Map<Color, Position> kingPos;
|
||||||
@ -35,10 +35,7 @@ public class Board {
|
|||||||
Piece piece = getPos(move);
|
Piece piece = getPos(move);
|
||||||
if (piece == null || !piece.isValidMove(move)) return false;
|
if (piece == null || !piece.isValidMove(move)) return false;
|
||||||
else {
|
else {
|
||||||
/*
|
// Move piece
|
||||||
* Move piece
|
|
||||||
* Save destination piece for possible canceling of the move
|
|
||||||
*/
|
|
||||||
Piece capturePiece = move(move);
|
Piece capturePiece = move(move);
|
||||||
|
|
||||||
// Revert move if it caused a check for its team
|
// Revert move if it caused a check for its team
|
||||||
@ -223,6 +220,32 @@ public class Board {
|
|||||||
boardArr[i][j] = null;
|
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) {
|
public Piece get(Position pos) {
|
||||||
return boardArr[pos.x][pos.y];
|
return boardArr[pos.x][pos.y];
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import java.util.List;
|
|||||||
* Created: <strong>01.07.2019</strong><br>
|
* Created: <strong>01.07.2019</strong><br>
|
||||||
* Author: <strong>Kai S. K. Engelbart</strong>
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
*/
|
*/
|
||||||
public abstract class Piece {
|
public abstract class Piece implements Cloneable {
|
||||||
|
|
||||||
protected Color color;
|
protected Color color;
|
||||||
protected Board board;
|
protected Board board;
|
||||||
@ -51,6 +51,17 @@ public abstract class Piece {
|
|||||||
return board.getDest(move) == null || board.getDest(move).getColor() != getColor();
|
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 abstract Type getType();
|
||||||
|
|
||||||
public Color getColor() { return color; }
|
public Color getColor() { return color; }
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package dev.kske.chess.game;
|
package dev.kske.chess.game;
|
||||||
|
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import dev.kske.chess.board.Board;
|
import dev.kske.chess.board.Board;
|
||||||
import dev.kske.chess.board.Move;
|
import dev.kske.chess.board.Move;
|
||||||
import dev.kske.chess.board.Piece;
|
import dev.kske.chess.board.Piece;
|
||||||
@ -13,7 +15,7 @@ import dev.kske.chess.board.Piece.Color;
|
|||||||
*/
|
*/
|
||||||
public class AIPlayer extends Player {
|
public class AIPlayer extends Player {
|
||||||
|
|
||||||
private Move bestMove;
|
private Move bestMove;
|
||||||
private int count;
|
private int count;
|
||||||
|
|
||||||
public AIPlayer(Board board, Color color) {
|
public AIPlayer(Board board, Color color) {
|
||||||
@ -22,10 +24,12 @@ public class AIPlayer extends Player {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestMove() {
|
public void requestMove() {
|
||||||
count = 0;
|
new Thread(() -> {
|
||||||
findBestMove(board, color, 0);
|
count = 0;
|
||||||
System.out.println("Moved processes: " + count);
|
findBestMove((Board) board.clone(), color, 0);
|
||||||
game.onMove(this, bestMove);
|
System.out.println("Moved processes: " + count);
|
||||||
|
SwingUtilities.invokeLater(() -> game.onMove(this, bestMove));
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int findBestMove(Board board, Color color, int depth) {
|
private int findBestMove(Board board, Color color, int depth) {
|
||||||
|
@ -36,8 +36,6 @@ public class Game {
|
|||||||
public void onMove(Player player, Move move) {
|
public void onMove(Player player, Move move) {
|
||||||
if (board.getPos(move).getColor() == player.color && board.attemptMove(move)) {
|
if (board.getPos(move).getColor() == player.color && board.attemptMove(move)) {
|
||||||
System.out.printf("%s: %s%n", player.color, move);
|
System.out.printf("%s: %s%n", player.color, move);
|
||||||
boardPanel.repaint();
|
|
||||||
|
|
||||||
GameState eventType = board.getGameEventType(board.getDest(move).getColor().opposite());
|
GameState eventType = board.getGameEventType(board.getDest(move).getColor().opposite());
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case CHECKMATE:
|
case CHECKMATE:
|
||||||
@ -47,7 +45,9 @@ public class Game {
|
|||||||
case CHECK:
|
case CHECK:
|
||||||
System.out.printf("%s in check!%n", player.color);
|
System.out.printf("%s in check!%n", player.color);
|
||||||
default:
|
default:
|
||||||
|
boardPanel.repaint();
|
||||||
players.get(player.color.opposite()).requestMove();
|
players.get(player.color.opposite()).requestMove();
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.printf("%s: Illegal move!%n", player.getColor());
|
System.out.printf("%s: Illegal move!%n", player.getColor());
|
||||||
|
@ -33,6 +33,7 @@ public class NaturalPlayer extends Player {
|
|||||||
pos = new Position(evt.getPoint().x / boardPanel.getTileSize(),
|
pos = new Position(evt.getPoint().x / boardPanel.getTileSize(),
|
||||||
evt.getPoint().y / boardPanel.getTileSize());
|
evt.getPoint().y / boardPanel.getTileSize());
|
||||||
|
|
||||||
|
Board board = (Board) NaturalPlayer.this.board.clone();
|
||||||
if (board.get(pos) != null && board.get(pos).getColor() == color)
|
if (board.get(pos) != null && board.get(pos).getColor() == color)
|
||||||
boardPanel.displayMoves(board.getMoves(pos));
|
boardPanel.displayMoves(board.getMoves(pos));
|
||||||
else pos = null;
|
else pos = null;
|
||||||
|
44
src/dev/kske/chess/test/BoardCloneTest.java
Normal file
44
src/dev/kske/chess/test/BoardCloneTest.java
Normal file
@ -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: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>BoardCloneTest.java</strong><br>
|
||||||
|
* Created: <strong>08.07.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user