public void TestUnMakeMove() { //arrange Move simpleMove = new Move(12, 28, PieceType.Empty); UnMakeInfo unMakeMove = new UnMakeInfo(); Position startPosition = FENConverter.convertFENToPosition(FENConverter.startPosition); //act startPosition.makeMove(simpleMove, unMakeMove); String fenString = "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1"; //assert Assert.AreEqual(fenString, FENConverter.convertPositionToFEN(startPosition)); //act startPosition.unMakeMove(simpleMove, unMakeMove); //assert Assert.AreEqual(FENConverter.startPosition, FENConverter.convertPositionToFEN(startPosition)); }
public void TestMakeMove() { //arrange Move simpleMove = new Move(12, 28, PieceType.Empty); //e2e4 UnMakeInfo unMakeMove = new UnMakeInfo(); Position startPosition = FENConverter.convertFENToPosition(FENConverter.startPosition); //act startPosition.makeMove(simpleMove, unMakeMove); /* * This following string is technically incorrect as in FEN it should indicate e3 as * the en passant square. However, our implementation does not set the en passant square * if it cannot be used. */ String fenString = "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1"; //assert Assert.AreEqual(fenString, FENConverter.convertPositionToFEN(startPosition)); }
/* * Removes illegal moves from the given move list * The move list contains psuedo-legal moves * This removes the moves that don't defend from check positions */ public static ArrayList removeIllegalMoves(Position position, ArrayList moveList) { ArrayList finalList = new ArrayList(); UnMakeInfo moveInfo = new UnMakeInfo(); int moveListCount = moveList.Count; for (int i = 0; i < moveListCount; i++) { Move move = (Move)moveList[i]; position.makeMove(move, moveInfo); position.setWhiteMove(!position.whiteMove); if (!inCheck(position)) { finalList.Add(move); } position.setWhiteMove(!position.whiteMove); position.unMakeMove(move, moveInfo); } return finalList; }
/* * Converts a move object into a UCI move string (long algebraic * notation), a move list can be supplied to search through. */ public static String moveObjectToString(Move move, Position position, ArrayList moves) { if ((move == null) || move.Equals(new Move(0, 0, 0))) { return "--"; } StringBuilder moveString = new StringBuilder(); int whiteKingOrigin = Position.getSquare(4, 0); int blackKingOrigin = Position.getSquare(4, 7); if ((move.origin == whiteKingOrigin) && (position.getPiece(whiteKingOrigin) == PieceType.K)) { //Check white castle if (move.destination == Position.getSquare(6, 0)) { moveString.Append("O-O"); } else if (move.destination == Position.getSquare(2, 0)) { moveString.Append("O-O-O"); } } else if ((move.origin == blackKingOrigin) && (position.getPiece(blackKingOrigin) == PieceType.k)) { //Check black castle if (move.destination == Position.getSquare(6, 7)) { moveString.Append("O-O"); } else if (move.destination == Position.getSquare(2, 7)) { moveString.Append("O-O-O"); } } if (moveString.Length == 0) { PieceType piece = position.getPiece(move.origin); moveString.Append("" + piece); int originFile = Position.getRank(move.origin); int originRank = Position.getFile(move.origin); int destinationFile = Position.getRank(move.destination); int destinationRank = Position.getFile(move.destination); //Long Algebraic Notation----- moveString.Append((char)(originFile + 'a')); moveString.Append((char)(originRank + '1')); moveString.Append(isMoveCapture(move, position) ? 'x' : '-'); //---------------------------- moveString.Append((char)(destinationFile + 'a')); moveString.Append((char)(destinationRank + '1')); if (move.promoteTo != PieceType.Empty) { moveString.Append("" + piece); } } UnMakeInfo unMake = new UnMakeInfo(); position.makeMove(move, unMake); Boolean inCheck = MoveGenerator.inCheck(position); if (inCheck) { ArrayList nextMoves = MoveGenerator.mgInstance.legalMoves(position); if (nextMoves.Count == 0) { moveString.Append('#'); } else { moveString.Append('+'); } } position.unMakeMove(move, unMake); return moveString.ToString(); }
private void GameInit() { currentPosition = FENConverter.convertFENToPosition(FENConverter.startPosition); unMakeInfo = new UnMakeInfo(); gameFinished = false; undoMove = false; }
/* * Unmake a move to the current position */ public void unMakeMove(Move move, UnMakeInfo moveInfo) { if (!sameActiveColor) { setWhiteMove(!whiteMove); } PieceType piece = pieceLayout[move.destination]; setPiece(move.origin, piece); setPiece(move.destination, moveInfo.getCapturedPiece()); setCastleMask(moveInfo.getCastleRights()); setEpSquare(moveInfo.getEPSquare()); halfMoveClock = moveInfo.getHalfMoveClock(); Boolean whiteToMove = whiteMove; if (move.promoteTo != PieceType.Empty) { piece = whiteToMove ? PieceType.P : PieceType.p; setPiece(move.origin, piece); } if (!whiteToMove) { fullMoveCounter--; } //Handle Castling PieceType king = whiteToMove ? PieceType.K : PieceType.k; int kingOrigin = move.origin; if (piece == king) { if (move.destination == kingOrigin + 2) { setPiece(kingOrigin + 3, pieceLayout[kingOrigin + 1]); setPiece(kingOrigin + 1, PieceType.Empty); } else if (move.destination == kingOrigin - 2) { setPiece(kingOrigin - 4, pieceLayout[kingOrigin - 1]); setPiece(kingOrigin - 1, PieceType.Empty); } } //Handle En Passant if (move.destination == epSquare) { if (piece == PieceType.P) { setPiece(move.destination - 8, PieceType.p); } else if (piece == PieceType.p) { setPiece(move.destination + 8, PieceType.P); } } }
//-----------------Move Methods--------------------------- /* * Apply a move to the current position */ public void makeMove(Move move, UnMakeInfo moveInfo) { //Store info to undo move if needed moveInfo.setCapturedPiece(pieceLayout[move.destination]); moveInfo.setCastleRights(castleMask); moveInfo.setEPSquare(epSquare); moveInfo.setHalfMoveClock(halfMoveClock); Boolean whiteToMove = whiteMove; PieceType piece = pieceLayout[move.origin]; PieceType capturedPiece = pieceLayout[move.destination]; Boolean nullMove = (move.origin == 0) && (move.destination == 0); if (nullMove || (capturedPiece != PieceType.Empty) || (piece == (whiteToMove ? PieceType.P : PieceType.p))) { halfMoveClock = 0; } else { halfMoveClock++; } if (!whiteToMove) { fullMoveCounter++; } //Handle Castling PieceType king = whiteToMove ? PieceType.K : PieceType.k; int kingOrigin = move.origin; if (piece == king) { if (move.destination == kingOrigin + 2) { setPiece(kingOrigin + 1, pieceLayout[kingOrigin + 3]); setPiece(kingOrigin + 3, PieceType.Empty); } else if (move.destination == kingOrigin - 2) { setPiece(kingOrigin - 1, pieceLayout[kingOrigin - 4]); setPiece(kingOrigin - 4, PieceType.Empty); } if (whiteToMove) { setCastleMask(castleMask & ~(1 << Position.A1_CASTLE)); setCastleMask(castleMask & ~(1 << Position.H1_CASTLE)); } else { setCastleMask(castleMask & ~(1 << Position.A8_CASTLE)); setCastleMask(castleMask & ~(1 << Position.H8_CASTLE)); } } if (!nullMove) { PieceType rook = whiteToMove ? PieceType.R : PieceType.r; if (piece == rook) { removeCastleRights(move.origin); } PieceType opppositeRook = whiteToMove ? PieceType.r : PieceType.R; if (capturedPiece == opppositeRook) { removeCastleRights(move.destination); } } //Handle En Passant int prevEpSquare = epSquare; setEpSquare(-1); if (piece == PieceType.P) { if (move.destination - move.origin == 2 * 8) { int file = Position.getFile(move.destination); if (((file > 0) && (pieceLayout[move.destination - 1] == PieceType.p)) || ((file < 7) && (pieceLayout[move.destination + 1] == PieceType.p))) { setEpSquare(move.origin + 8); } } else if (move.destination == prevEpSquare) { setPiece(move.destination - 8, PieceType.Empty); } } else if (piece == PieceType.p) { if (move.destination - move.origin == -2 * 8) { int file = Position.getFile(move.destination); if (((file > 0) && (pieceLayout[move.destination - 1] == PieceType.P)) || ((file < 7) && (pieceLayout[move.destination + 1] == PieceType.P))) { setEpSquare(move.origin - 8); } } else if (move.destination == prevEpSquare) { setPiece(move.destination + 8, PieceType.Empty); } } //Perform Move setPiece(move.origin, PieceType.Empty); //Handle Promotion if (move.promoteTo != PieceType.Empty) { setPiece(move.destination, move.promoteTo); } else { setPiece(move.destination, piece); } if (!sameActiveColor) { setWhiteMove(!whiteToMove); } }