diff --git a/src/suicideChess/Board.java b/src/suicideChess/Board.java index f162993..82b5420 100644 --- a/src/suicideChess/Board.java +++ b/src/suicideChess/Board.java @@ -210,8 +210,21 @@ public class Board { } } } - boardValue = getBoardValue(); + + if (numberOfBlackPieces == 0) { + boardValue = BLACK_WINS; + } else if (numberOfWhitePieces == 0){ + boardValue = WHITE_WINS; + } else if (!Rules.isThereALegalMovesForPlayer(this)) { + if (currentPlayer==Piece.WHITE) { + boardValue = WHITE_WINS; + } else { + boardValue = BLACK_WINS; + } + } else { + boardValue = getBoardValue(); + } } @@ -493,6 +506,7 @@ public class Board { } private void evaluateNewBoardValue (Move move) throws NotAValidSquare { + if (move.isCaptureMove()) { if (move.getCapturedPiece().getColor()==Piece.BLACK) { numberOfBlackPieces--; @@ -508,7 +522,7 @@ public class Board { boardValue = numberOfBlackPieces - numberOfWhitePieces; } } - if (Rules.isThereALegalMovesForPlayer(this)) { + if (!Rules.isThereALegalMovesForPlayer(this)) { if (currentPlayer==Piece.WHITE) { boardValue = WHITE_WINS; } else { diff --git a/src/suicideChess/ComputerPlayer.java b/src/suicideChess/ComputerPlayer.java index 70d60f5..298d3ac 100644 --- a/src/suicideChess/ComputerPlayer.java +++ b/src/suicideChess/ComputerPlayer.java @@ -80,7 +80,7 @@ public class ComputerPlayer { return Board.WHITE_WINS; } } else { - int bestMoveIndex=0; + ArrayList bestMoveIndex=new ArrayList(); int currentScore; int bestScoreSoFar; if (bitboard.getCurrentPlayer()==Piece.BLACK) { @@ -89,9 +89,12 @@ public class ComputerPlayer { Board boardCopy = new Board(bitboard); boardCopy.doMove(allLegalMoves.get(i)); currentScore=MinMax(boardCopy,currentDepth+1); - if (currentScore < bestScoreSoFar) { //black tries to minimise his score - bestScoreSoFar = currentScore; - bestMoveIndex = i; + if (currentScore <= bestScoreSoFar) { //black tries to minimise his score + if (currentScore bestScoreSoFar) { //white tries to maximise his score - bestScoreSoFar = currentScore; - bestMoveIndex = i; + if (currentScore >= bestScoreSoFar) { //white tries to maximise his score + if (currentScore>bestScoreSoFar) { + bestScoreSoFar = currentScore; + bestMoveIndex.clear(); + } + bestMoveIndex.add(i); } } } - bestMove = allLegalMoves.get(bestMoveIndex); + + //select one of the best moves randomly + Random generator = new Random(); + bestMove = allLegalMoves.get(bestMoveIndex.get(generator.nextInt(bestMoveIndex.size()))); + return bestScoreSoFar; } } diff --git a/src/suicideChess/Rules.java b/src/suicideChess/Rules.java index 1649ab5..3afa290 100644 --- a/src/suicideChess/Rules.java +++ b/src/suicideChess/Rules.java @@ -66,14 +66,14 @@ public class Rules { public static boolean isThereALegalMovesForPlayer(Board board) throws NotAValidSquare { legalMovesNonCapture = new ArrayList(); legalMovesCapture = new ArrayList(); - Square square; for(int squareNb = 0; squareNb < Board.NB_OF_SQUARES; squareNb++) { square = new Square(squareNb); if (board.isEmpty(square, new Piece(board.getCurrentPlayer()))) { continue; } - if ((legalMovesNonCapture.size()!=0)||(legalMovesCapture.size()!=0)) { + legalMovesFromSquare(square,board); + if ((legalMovesCapture.size()!=0)||(legalMovesNonCapture.size()!=0)) { return true; //found a legal move } } diff --git a/src/suicideChess/SuicideChess.java b/src/suicideChess/SuicideChess.java index e5276e4..eeea6ee 100644 --- a/src/suicideChess/SuicideChess.java +++ b/src/suicideChess/SuicideChess.java @@ -33,7 +33,7 @@ public class SuicideChess { /** * The name to be displayed */ - public static final String NAME = "djib's SuicideChess v0.4.1"; + public static final String NAME = "djib's SuShi (Suicide Chess) v0.4.3"; /** * Displays informations in the console. @@ -197,7 +197,7 @@ public class SuicideChess { } //if XBoard did not accept usermove command we try and interpret every unknown command //as a move. - case XBoardProtocol.MOVE: + case XBoardProtocol.MOVE: Move theMove; if (acceptedUsermove) { theMove = new Move(whatMove.substring(9), bitboard); @@ -205,6 +205,13 @@ public class SuicideChess { theMove = new Move(whatMove, bitboard); } + if (testWinningPosition(bitboard)) { + //if board was set in an illegal position + System.out.println("Illegal move: "+theMove.toString()); + break; + } + + boolean needToCapture = false; int foundMoveIndex = -1; if(theMove.getMovingPiece().getColor() == bitboard.getCurrentPlayer()) { @@ -258,9 +265,16 @@ public class SuicideChess { case XBoardProtocol.GO: //this is not really nice but it avoids having to write twice the code //I check if I did really receive a XBoardProtocol.GO or it I just got there - //because there is no break statement. + //because there is no break statement. if (xBoardCommand==XBoardProtocol.GO) computerPlaying = true; + + if (testWinningPosition(bitboard)) { + //in case an illegal position have been sent + computerPlaying=false; + break; + } + if (computerPlaying) { Move computerMove = ComputerPlayer.doMinMaxMove(bitboard); bitboard.doMove(computerMove); @@ -272,6 +286,7 @@ public class SuicideChess { bitboard.display(); } } + if (testWinningPosition(bitboard)) { computerPlaying=false; } diff --git a/src/suicideChess/XBoardProtocol.java b/src/suicideChess/XBoardProtocol.java index aec8542..8c05cfc 100644 --- a/src/suicideChess/XBoardProtocol.java +++ b/src/suicideChess/XBoardProtocol.java @@ -99,7 +99,7 @@ public class XBoardProtocol { public static void initialise() throws IOException { //done=1 is here to tell that the program has finish requesting features System.out.println("feature usermove=1"); //sends moves like 'usermove e2e4' - System.out.println("feature myname=\"djib's Suicide Chess\""); + System.out.println("feature myname=\""+SuicideChess.NAME+"\""); System.out.println("feature sigint=0 sigterm=0"); //do not interrupt me System.out.println("feature variants=\"suicide\""); System.out.println("feature ping=1 setboard=1");