Position { public final void makeMove(Move move, UndoInfo ui) { ui.capturedPiece = squares[move.to]; ui.castleMask = castleMask; ui.epSquare = epSquare; ui.halfMoveClock = halfMoveClock; boolean wtm = whiteMove; final int p = squares[move.from]; int capP = squares[move.to]; long fromMask = 1L << move.from; int prevEpSquare = epSquare; setEpSquare(-1); if ((capP != Piece.EMPTY) || (((pieceTypeBB[Piece.WPAWN] | pieceTypeBB[Piece.BPAWN]) & fromMask) != 0)) { halfMoveClock = 0; if (p == Piece.WPAWN) { if (move.to - move.from == 2 * 8) { int x = Position.getX(move.to); if ( ((x > 0) && (squares[move.to - 1] == Piece.BPAWN)) || ((x < 7) && (squares[move.to + 1] == Piece.BPAWN))) { setEpSquare(move.from + 8); } } else if (move.to == prevEpSquare) { setPiece(move.to - 8, Piece.EMPTY); } } else if (p == Piece.BPAWN) { if (move.to - move.from == -2 * 8) { int x = Position.getX(move.to); if ( ((x > 0) && (squares[move.to - 1] == Piece.WPAWN)) || ((x < 7) && (squares[move.to + 1] == Piece.WPAWN))) { setEpSquare(move.from - 8); } } else if (move.to == prevEpSquare) { setPiece(move.to + 8, Piece.EMPTY); } } if (((pieceTypeBB[Piece.WKING] | pieceTypeBB[Piece.BKING]) & fromMask) != 0) { if (wtm) { 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)); } } setPiece(move.from, Piece.EMPTY); if (move.promoteTo != Piece.EMPTY) { setPiece(move.to, move.promoteTo); } else { setPiece(move.to, p); } } else { halfMoveClock++; if (((pieceTypeBB[Piece.WKING] | pieceTypeBB[Piece.BKING]) & fromMask) != 0) { int k0 = move.from; if (move.to == k0 + 2) { movePieceNotPawn(k0 + 3, k0 + 1); } else if (move.to == k0 - 2) { movePieceNotPawn(k0 - 4, k0 - 1); } if (wtm) { 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)); } } movePieceNotPawn(move.from, move.to); } if (wtm) { if ((BitBoard.maskCorners & fromMask) != 0) { if (p == Piece.WROOK) removeCastleRights(move.from); } if ((BitBoard.maskCorners & (1L << move.to)) != 0) { if (capP == Piece.BROOK) removeCastleRights(move.to); } } else { fullMoveCounter++; if ((BitBoard.maskCorners & fromMask) != 0) { if (p == Piece.BROOK) removeCastleRights(move.from); } if ((BitBoard.maskCorners & (1L << move.to)) != 0) { if (capP == Piece.WROOK) removeCastleRights(move.to); } } hashKey ^= whiteHashKey; whiteMove = !wtm; } Position();  Position(Position other); @Override boolean equals(Object o); @Override int hashCode(); final long zobristHash(); final long pawnZobristHash(); final long kingZobristHash(); final long historyHash(); final boolean drawRuleEquals(Position other); final void setWhiteMove(boolean whiteMove); static int getSquare(int x, int y); static int getX(int square); static int getY(int square); static boolean darkSquare(int x, int y); final int getPiece(int square); final void setPiece(int square, int piece); final boolean a1Castle(); final boolean h1Castle(); final boolean a8Castle(); final boolean h8Castle(); final int getCastleMask(); final void setCastleMask(int castleMask); final int getEpSquare(); final void setEpSquare(int epSquare); final int getKingSq(boolean white); final void makeMove(Move move, UndoInfo ui); final void unMakeMove(Move move, UndoInfo ui); final void makeSEEMove(Move move, UndoInfo ui); final void unMakeSEEMove(Move move, UndoInfo ui); final String toString(); public int[] squares; public long[] pieceTypeBB; public long whiteBB; public short[] psScore1; public boolean whiteMove; static final int A1_CASTLE; static final int H1_CASTLE; static final int A8_CASTLE; static final int H8_CASTLE; public int fullMoveCounter; public int wKingSq; public int wMtrl; public int bMtrl; public int wMtrlPawns; public int bMtrlPawns; }
@Test public void testMakeMove() throws ChessParseError { System.out.println("makeMove"); Position pos = TextIO.readFEN(TextIO.startPosFEN); Position origPos = new Position(pos); assertTrue(pos.equals(origPos)); Move move = new Move(Position.getSquare(4,1), Position.getSquare(4,3), Piece.EMPTY); UndoInfo ui = new UndoInfo(); pos.makeMove(move, ui); assertEquals(pos.whiteMove, false); assertEquals(-1, pos.getEpSquare()); assertEquals(Piece.EMPTY, pos.getPiece(Position.getSquare(4,1))); assertEquals(Piece.WPAWN, pos.getPiece(Position.getSquare(4,3))); assertTrue(!pos.equals(origPos)); int castleMask = (1 << Position.A1_CASTLE) | (1 << Position.H1_CASTLE) | (1 << Position.A8_CASTLE) | (1 << Position.H8_CASTLE); assertEquals(castleMask,pos.getCastleMask()); pos.unMakeMove(move, ui); assertEquals(pos.whiteMove, true); assertEquals(Piece.WPAWN, pos.getPiece(Position.getSquare(4,1))); assertEquals(Piece.EMPTY, pos.getPiece(Position.getSquare(4,3))); assertTrue(pos.equals(origPos)); String fen = "r1bqk2r/2ppbppp/p1n2n2/1pP1p3/B3P3/5N2/PP1P1PPP/RNBQK2R w KQkq b6 0 2"; pos = TextIO.readFEN(fen); assertEquals(fen, TextIO.toFEN(pos)); origPos = new Position(pos); assertEquals(Position.getSquare(1,5), pos.getEpSquare()); move = new Move(Position.getSquare(0, 3), Position.getSquare(1,4), Piece.EMPTY); pos.makeMove(move, ui); assertEquals(-1, pos.getEpSquare()); assertEquals(Piece.WBISHOP, pos.getPiece(Position.getSquare(1,4))); assertEquals(Piece.EMPTY, pos.getPiece(Position.getSquare(0,3))); pos.unMakeMove(move, ui); assertTrue(pos.equals(origPos)); move = new Move(Position.getSquare(4, 0), Position.getSquare(6,0), Piece.EMPTY); pos.makeMove(move, ui); assertEquals(Piece.WROOK, pos.getPiece(Position.getSquare(5,0))); assertEquals(Piece.EMPTY, pos.getPiece(Position.getSquare(7,0))); castleMask = (1 << Position.A8_CASTLE) | (1 << Position.H8_CASTLE); assertEquals(castleMask,pos.getCastleMask()); assertEquals(-1, pos.getEpSquare()); pos.unMakeMove(move, ui); assertTrue(pos.equals(origPos)); move = new Move(Position.getSquare(4, 0), Position.getSquare(4,1), Piece.EMPTY); pos.makeMove(move, ui); castleMask = (1 << Position.A8_CASTLE) | (1 << Position.H8_CASTLE); assertEquals(castleMask,pos.getCastleMask()); assertEquals(-1, pos.getEpSquare()); pos.unMakeMove(move, ui); assertTrue(pos.equals(origPos)); move = new Move(Position.getSquare(7, 0), Position.getSquare(6,0), Piece.EMPTY); pos.makeMove(move, ui); castleMask = (1 << Position.A1_CASTLE) | (1 << Position.A8_CASTLE) | (1 << Position.H8_CASTLE); assertEquals(castleMask,pos.getCastleMask()); assertEquals(-1, pos.getEpSquare()); pos.unMakeMove(move, ui); assertTrue(pos.equals(origPos)); move = new Move(Position.getSquare(2, 4), Position.getSquare(1,5), Piece.EMPTY); pos.makeMove(move, ui); assertEquals(Piece.WPAWN, pos.getPiece(Position.getSquare(1,5))); assertEquals(Piece.EMPTY, pos.getPiece(Position.getSquare(2,4))); assertEquals(Piece.EMPTY, pos.getPiece(Position.getSquare(1,4))); pos.unMakeMove(move, ui); assertTrue(pos.equals(origPos)); pos.setPiece(Position.getSquare(6,2), Piece.BKNIGHT); pos.setWhiteMove(false); Position origPos2 = new Position(pos); move = new Move(Position.getSquare(6,2), Position.getSquare(7,0), Piece.EMPTY); pos.makeMove(move, ui); castleMask = (1 << Position.A1_CASTLE) | (1 << Position.A8_CASTLE) | (1 << Position.H8_CASTLE); assertEquals(castleMask,pos.getCastleMask()); assertEquals(-1, pos.getEpSquare()); pos.unMakeMove(move, ui); assertTrue(pos.equals(origPos2)); }