Chess/src/Player.java

248 lines
6 KiB
Java

import java.util.*;
/**
* Player class
*/
public class Player {
/**
* Player's chessboard
*/
private Chessboard chessboard;
/**
* Player's piece color
*/
private PieceColor color;
/**
* Player's start position
*/
private StartPosition startPosition;
/**
* King piece
*/
private King king;
/**
* Active CPU mode
*/
private CPUMode cpu;
/**
* Waiting for CPU move
*/
private boolean isPlaying = false;
/**
* Delays between player's moves
*/
private ArrayList<Integer> delays = new ArrayList<>();
/**
* Player's constructor
* @param chessboard player's chessboard
* @param startPosition player's start position
* @param color player's color
*/
public Player(Chessboard chessboard, StartPosition startPosition, PieceColor color) {
this.chessboard = chessboard;
this.color = color;
this.startPosition = startPosition;
}
/**
* Detects if player is in check
* @return true, if in check
*/
public boolean inCheck() {
return king.isEndangered();
}
/**
* Detects if player has no possible moves
* @return true, if no possible moves
*/
public boolean hasNoPossibleMove() {
for (APiece piece : getPieces()) {
boolean[][] possibleMoves = piece.getPossibleMoves();
for (int y = 0; y < possibleMoves.length; y++) {
for (int x = 0; x < possibleMoves[y].length; x++) {
if(possibleMoves[y][x]) return false;
}
}
}
return true;
}
/**
* Play automatically as CPU
*/
public void play() {
if(cpu == null) return;
isPlaying = true;
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
if (cpu != null) {
if (cpu == CPUMode.RANDOM) randomMove();
if (cpu == CPUMode.SMART) smartMove();
}
isPlaying = false;
t.cancel();
}
}, 1000);
}
/**
* Select random piece and move it randomly
* @return true, if piece was moved
*/
public boolean randomMove() {
ArrayList<APiece> myPieces = getPieces();
while(myPieces.size() != 0) {
Random r = new Random();
APiece selectedPiece = myPieces.get(r.nextInt(myPieces.size()));
ArrayList<PiecePosition> possibleMoves = new ArrayList<>();
myPieces.remove(selectedPiece);
boolean[][] possibleMoveMap = selectedPiece.getPossibleMoves();
for (int y = 0; y < possibleMoveMap.length; y++) {
for (int x = 0; x < possibleMoveMap[y].length; x++) {
if(possibleMoveMap[y][x]) {
possibleMoves.add(new PiecePosition(x, y));
}
}
}
int moveCount = possibleMoves.size();
if(moveCount == 0) {
continue;
}
PiecePosition randomMove = possibleMoves.get(r.nextInt(moveCount));
selectedPiece.move(randomMove.x, randomMove.y, true);
chessboard.changeActivePlayer();
return true;
}
return false;
}
/**
* Move piece according to the stockfish engine
* @return true, if piece was moved
*/
public boolean smartMove() {
Stockfish stockfish = Stockfish.getInstance();
if(stockfish == null) return false;
String fen = chessboard.toFEN();
String bestMove = stockfish.getBestMove(fen, 0, 500);
if(bestMove == null) return false;
PiecePosition fromPos = PiecePosition.fromString(bestMove.substring(0, 2));
PiecePosition toPos = PiecePosition.fromString(bestMove.substring(2, 4));
if(fromPos == null || toPos == null) return false;
APiece piece = chessboard.getPiece(fromPos.x, fromPos.y);
piece.move(toPos.x, toPos.y);
chessboard.changeActivePlayer();
return true;
}
/**
* Get player's chessboard
* @return chessboard
*/
public Chessboard getChessboard() {
return chessboard;
}
/**
* Get player's piece color
* @return piece color
*/
public PieceColor getColor() {
return color;
}
/**
* Get player's start position
* @return start position
*/
public StartPosition getStartPosition() {
return startPosition;
}
/**
* Get player's King piece
* @return King
*/
public King getKing() {
return king;
}
/**
* Set player's King piece
* @param king new King
*/
public void setKing(King king) {
this.king = king;
}
/**
* Get all player's pieces
* @return player's pieces
*/
public ArrayList<APiece> getPieces() {
ArrayList<APiece> myPieces = new ArrayList<>();
for (APiece[] pieces : chessboard.pieces) {
for (APiece piece : pieces) {
if(piece != null && piece.getPlayer() == this) {
myPieces.add(piece);
}
}
}
return myPieces;
}
/**
* Set player's CPU mode
* @param cpu CPU mode
*/
public void setCPU(CPUMode cpu) {
// TODO: use enums
this.cpu = cpu;
if(chessboard.getActivePlayer() == this && !isPlaying) play();
}
/**
* Get player's CPU mode
* @return CPU mode
*/
public CPUMode getCPU() {
return cpu;
}
/**
* Add new delay before last move
* @param delay delay in ms
*/
public void addDelay(int delay) {
delays.add(delay);
}
/**
* Get all delays between moves
* @return delays list
*/
public List<Integer> getDelays() {
return delays;
}
}
enum CPUMode {
RANDOM, SMART;
}