CastlingBits CanCastleSwitch(int fromPosition) { CastlingBits castling = CastlingBits.CAN_ALL; switch (fromPosition) { case BoardStateOffset.A1: castling = castling & CastlingBits.CAN_NOT_BQ; break; case BoardStateOffset.E1: castling = castling & CastlingBits.CAN_NOT_B; break; case BoardStateOffset.H1: castling = castling & CastlingBits.CAN_NOT_BK; break; case BoardStateOffset.A8: castling = castling & CastlingBits.CAN_NOT_WQ; break; case BoardStateOffset.E8: castling = castling & CastlingBits.CAN_NOT_W; break; case BoardStateOffset.H8: castling = castling & CastlingBits.CAN_NOT_WK; break; } return(castling); }
CastlingBits CanCastleIf(int fromPosition) { CastlingBits castling = CastlingBits.CAN_ALL; if (fromPosition == BoardStateOffset.A1) { castling = castling & CastlingBits.CAN_NOT_BQ; } else if (fromPosition == BoardStateOffset.E1) { castling = castling & CastlingBits.CAN_NOT_B; } else if (fromPosition == BoardStateOffset.H1) { castling = castling & CastlingBits.CAN_NOT_BK; } else if (fromPosition == BoardStateOffset.A8) { castling = castling & CastlingBits.CAN_NOT_WQ; } else if (fromPosition == BoardStateOffset.E8) { castling = castling & CastlingBits.CAN_NOT_W; } else if (fromPosition == BoardStateOffset.H8) { castling = castling & CastlingBits.CAN_NOT_WK; } return(castling); }
CastlingBits CanCastleLookup(int fromPosition) { CastlingBits castleBits = CastlingBits.CAN_ALL; castleBits = (CastlingBits)((int)castleBits & (int)CastlingHelper.castleLookup[fromPosition]); return(castleBits); }
public bool CanCastleKingSide() { CastlingBits castlingBits = CastlingBits; // TODO bitshift optimize? if (IsWhiteTurnBool) { return((castlingBits & CastlingBits.WHITE_KING_SIDE_CASTLE) == CastlingBits.WHITE_KING_SIDE_CASTLE); } else { return((castlingBits & CastlingBits.BLACK_KING_SIDE_CASTLE) == CastlingBits.BLACK_KING_SIDE_CASTLE); } }
public bool CanICastleQueenSide() { CastlingBits castlingBits = CastlingBits; // TODO bitshift optimize? if (IsWhiteTurnBool) { return((castlingBits & CastlingBits.WHITE_QUEEN_SIDE_CASTLE) == CastlingBits.WHITE_QUEEN_SIDE_CASTLE); } else { return((castlingBits & CastlingBits.BLACK_QUEEN_SIDE_CASTLE) == CastlingBits.BLACK_QUEEN_SIDE_CASTLE); } }
public void BlackCannotCastleQueenSideAfterH8Moves() { CastlingBits castling = CastlingBits.CAN_ALL; castling = castling & CastlingHelper.castleLookup[BoardStateOffset.H8]; Assert.IsTrue((castling & CastlingBits.BLACK_QUEEN_SIDE_CASTLE) == CastlingBits.BLACK_QUEEN_SIDE_CASTLE, "Black can still castle queen side after h8 moves"); Assert.IsFalse((castling & CastlingBits.BLACK_KING_SIDE_CASTLE) == CastlingBits.BLACK_KING_SIDE_CASTLE, "Black cannot castle king side after h8 moves"); Assert.IsTrue((castling & CastlingBits.WHITE_KING_SIDE_CASTLE) == CastlingBits.WHITE_KING_SIDE_CASTLE, "White can still castle"); Assert.IsTrue((castling & CastlingBits.WHITE_QUEEN_SIDE_CASTLE) == CastlingBits.WHITE_QUEEN_SIDE_CASTLE, "White can still castle"); }
public static String BoardToFen(Board board, int move = 0) { StringBuilder fen = new StringBuilder(); for (int row = 7; row >= 0; row--) { int count = 0; for (int column = 0; column < 8; column++) { var position = row * BoardStateOffset.ROW_OFFSET + column; var piece = board.GetPiece(position); //var piece = Board.GetPiece(board, position); char c = PieceParser.ToChar(piece); if (c == '_') { count++; } else { if (count != 0) { fen.Append(count); count = 0; } fen.Append(c); } } if (count != 0) { fen.Append(count); } if (row != 0) { fen.Append("/"); } } fen.Append(" "); fen.Append(board.IsWhiteTurnBool ? "w" : "b"); fen.Append(" "); CastlingBits castlingBits = board.CastlingBits; if (castlingBits == CastlingBits.EMPTY) { fen.Append("-"); } else { if ((castlingBits & CastlingBits.WHITE_KING_SIDE_CASTLE) != CastlingBits.EMPTY) { fen.Append("K"); } if ((castlingBits & CastlingBits.WHITE_QUEEN_SIDE_CASTLE) != CastlingBits.EMPTY) { fen.Append("Q"); } if ((castlingBits & CastlingBits.BLACK_KING_SIDE_CASTLE) != CastlingBits.EMPTY) { fen.Append("k"); } if ((castlingBits & CastlingBits.BLACK_QUEEN_SIDE_CASTLE) != CastlingBits.EMPTY) { fen.Append("q"); } } fen.Append(" "); fen.Append(board.EnPassantTarget != EnPassant.NO_ENPASSANT ? BoardPosition.ReadablePosition(board.EnPassantTarget) : "-"); fen.Append(" "); fen.Append(board.HalfTurnCounter); fen.Append(" "); fen.Append(move); return(fen.ToString()); }
public void UndoMove(Move move) { int targetPosition = move.targetPosition; int fromPosition = move.fromPosition; int theirColor = IsWhiteTurn; int ourColor = IsWhiteTurn ^ 1; bytes[fromPosition] = bytes[targetPosition]; bytes[targetPosition] = move.capturedPiece; Piece movedPiece = GetPiece(fromPosition); CastlingBits previous = (CastlingBits)move.previousCastlingBits; bytes[BoardStateOffset.HALF_TURN_COUNTER] = move.previousHalfMove; bytes[BoardStateOffset.CASTLING] = move.previousCastlingBits; bytes[BoardStateOffset.EN_PASSANT_FIELD] = move.previousEnpassant; MoveFlags moveFlags = (MoveFlags)move.moveFlags; if ((moveFlags & MoveFlags.ENPASSANT) == MoveFlags.ENPASSANT) { // when undoing a enpassant move spawn their pawn back // we abuse that isWhite is a integer which is 1 on whites turn and 0 and blacks turn // if it was black move then we have to spawn it one row above // if it was whites move we spawn it one move below // keep in mind the IsWhiteTurn is currently opposite of who made the move int enpassantSpawnPosition = targetPosition - BoardStateOffset.ROW_OFFSET + 2 * BoardStateOffset.ROW_OFFSET * IsWhiteTurn; SetPiece(enpassantSpawnPosition, Piece.PAWN | (Piece)theirColor); // when capturing with enpassant don't place the captured piece back since it was taken from another square bytes[targetPosition] = (byte)Piece.EMPTY; } if (move.promotion != 0) { bytes[fromPosition] = (byte)(Piece.PAWN | (Piece)ourColor); } // if black made a move decrement the turn counter // we abuse that isWhite is a integer which is 1 on whites turn and 0 and blacks turn //TurnCounter -= IsWhiteTurn; if ((movedPiece & Piece.PIECE_MASK) == Piece.KING) { if ((moveFlags & MoveFlags.CASTLING) == MoveFlags.CASTLING) { // if the target move is less than the kingsposition it is queenside castling, // otherwise it is kingside castle if (targetPosition < fromPosition) { // copy the rook back to its starting position bytes[fromPosition - 4] = bytes[fromPosition - 1]; bytes[fromPosition - 1] = 0; } else { bytes[fromPosition + 3] = bytes[fromPosition + 1]; bytes[fromPosition + 1] = 0; } } SetKingPosition(ourColor, (byte)fromPosition); } // switch turn back to whites turn IsWhiteTurn = (byte)ourColor; }