public ChessBoard(ulong WP, ulong WN, ulong WB, ulong WQ, ulong WR, ulong WK, ulong BP, ulong BN, ulong BB, ulong BQ, ulong BR, ulong BK, Move move , bool MKC, bool MQC, bool PKC, bool PQC, bool PC_DONE, bool MC_DONE) { this.WP = WP; this.WN = WN; this.WB = WB; this.WQ = WQ; this.WR = WR; this.WK = WK; this.BP = BP; this.BN = BN; this.BB = BB; this.BQ = BQ; this.BR = BR; this.BK = BK; this.move = move; this.MKC = MKC; this.MQC = MQC; this.PKC = PKC; this.PQC = PQC; this.PC_DONE = PC_DONE; this.MC_DONE = MC_DONE; createUsefullBitboards(); }
public static List<ChessBoard> generateChessBoards(bool min_max, ulong B_P, ulong B_R, ulong B_N, ulong B_B, ulong B_Q, ulong B_K, ulong W_P, ulong W_R, ulong W_N, ulong W_B, ulong W_Q, ulong W_K, Move history_move=null, bool MKC=true, bool MQC=true, bool PKC=true, bool PQC=true) { List<ChessBoard> theList = new List<ChessBoard>(); if (min_max) // if it is an ai max node { //Console.WriteLine("---------------"); setCurrentBitboards(B_P, B_R, B_N, B_B, B_Q, B_K, W_P, W_R, W_N, W_B, W_Q, W_K); setCurrentBitboardsHistoryMove(history_move); setCurrentCastlingCondition(MKC, MQC, PKC, PQC); ArrayList moves = PossibleMovesMachine(); Move last_time_best=null; if (best_move_queue.Count!=0) { last_time_best = best_move_queue.Dequeue(); //Console.WriteLine("Best Move is " + last_time_best.from_rank + " " + last_time_best.from_file + " " + last_time_best.to_rank + " " + last_time_best.to_file); } //Console.WriteLine("Best move is " + last_time_best.from_rank + last_time_best.from_file + last_time_best.to_rank + last_time_best.to_file); moves.Sort(new MoveCompare(last_time_best)); // else // { //Move last_best = best_move_queue.Dequeue(); // moves.Sort(new MoveCompare()); //move ordering //moves.Sort(new MoveCompare(last_best)); //} //foreach (Move move in moves) //{ // Console.WriteLine("Move is " + move.from_rank + " " + move.from_file + " " + move.to_rank + " " + move.to_file); //} foreach (Move move in moves) { ulong BP = B_P; ulong WP = W_P; ulong BR = B_R; ulong WR = W_R; ulong BN = B_N; ulong WN = W_N; ulong BQ = B_Q; ulong WQ = W_Q; ulong BB = B_B; ulong WB = W_B; ulong BK = B_K; ulong WK = W_K; bool M_K_C = MKC; bool M_Q_C = MQC; bool P_K_C = PKC; bool P_Q_C = PQC; //process_time = DateTime.Now; //if (DateTime.Compare(process_time, end_time) > 0) // break; //castling move. if (move.MQC) // if move is a machine queen side castling { int king_index = move.from_rank * 8 + move.from_file; if(player_color) { BK = (BK >> 2); BR &= ~((ulong)0x0100000000000000); BR |= (ulong)0x0800000000000000; //Console.WriteLine("BK is " + Convert.ToString((long)(BR+BK), 2)); } else { WK = (WK << 2); WR &= ~((ulong)0x8000000000000000); WR |= (ulong)0x0100000000000000; } M_Q_C = false; M_K_C = false; ChessBoard castling_b = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C); theList.Add(castling_b); continue; } if (move.MKC) // if the move is a machine king side castling { int king_index = move.from_rank * 8 + move.from_file; if (player_color) { BK = (BK << 2); BR &= ~((ulong)0x8000000000000000); BR |= (ulong)0x2000000000000000; } else { WK = (WK >> 2); WR &= ~((ulong)0x0100000000000000); WR |= (ulong)0x0400000000000000; } M_Q_C = false; M_K_C = false; ChessBoard castling_b = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C); theList.Add(castling_b); continue; } //normal moves are following switch (move.cap_type) { case PieceType.King: if (player_color) //if player play black then ai updates the white piece WK &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BK &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Queen: if (player_color) WQ &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BQ &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Rook: if (player_color) WR &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BR &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Knight: if (player_color) WN &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BN &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Bishop: if (player_color) WB &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BB &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Pawn: if (player_color) WP &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BP &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; default: break; } switch (move.moved_type) { case PieceType.King: if (player_color) { BK |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BK &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { WK |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WK &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } M_K_C = false; M_Q_C = false; break; case PieceType.Queen: if (player_color) { BQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BQ &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { WQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WQ &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Rook: if (player_color) { BR |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BR &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.from_file == 0) M_Q_C = false; if (move.from_file == 7) M_K_C = false; } else { WR |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WR &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.from_file == 0) M_K_C = false; if (move.from_file == 7) M_Q_C = false; } break; case PieceType.Knight: if (player_color) { BN |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BN &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { WN |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WN &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Bishop: if (player_color) { BB |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BB &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { WB |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WB &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Pawn: if (player_color) { BP |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BP &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { WP |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WP &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; default: break; } // Switch case for special events! promotion, enpassant etc. ChessBoard cb = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C); theList.Add(cb); } } // if it is a player min node else { setCurrentBitboards(B_P, B_R, B_N, B_B, B_Q, B_K, W_P, W_R, W_N, W_B, W_Q, W_K); setCurrentBitboardsHistoryMove(history_move); setCurrentCastlingCondition(MKC, MQC, PKC, PQC); ArrayList moves = PossibleMovesPlayer(); Move last_time_best = null; if (best_move_queue.Count != 0) { last_time_best = best_move_queue.Dequeue(); } //Console.WriteLine("Best move is " + last_time_best.from_rank + last_time_best.from_file + last_time_best.to_rank + last_time_best.to_file); moves.Sort(new MoveCompare(last_time_best)); foreach (Move move in moves) { ulong BP = B_P; ulong WP = W_P; ulong BR = B_R; ulong WR = W_R; ulong BN = B_N; ulong WN = W_N; ulong BQ = B_Q; ulong WQ = W_Q; ulong BB = B_B; ulong WB = W_B; ulong BK = B_K; ulong WK = W_K; bool M_K_C = MKC; bool M_Q_C = MQC; bool P_K_C = PKC; bool P_Q_C = PQC; //process_time = DateTime.Now; //if (DateTime.Compare(process_time, end_time) > 0) // break; //process_time = DateTime.Now; //if (DateTime.Compare(process_time, end_time) >= 0) // break; if (move.PQC) // if move is a player queen side castling { if (player_color) { WK = (WK >> 2); WR &= ~((ulong)0x0000000000000001); WR |= (ulong)0x0000000000000008; } else { BK = (BK << 2); BR &= ~((ulong)0x0000000000000080); BR |= (ulong)0x0000000000000010; } P_Q_C = false; P_K_C = false; ChessBoard castling_b = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C); theList.Add(castling_b); continue; } if (move.PKC) // if the move is a player king side castling { if (player_color) { WK = (WK << 2); WR &= ~((ulong)0x0000000000000080); WR |= (ulong)0x0000000000000020; } else { BK = (BK >> 2); BR &= ~((ulong)0x0000000000000001); BR |= (ulong)0x0000000000000004; } P_Q_C = false; P_K_C = false; ChessBoard castling_b = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C); theList.Add(castling_b); continue; } switch (move.cap_type) { case PieceType.King: if(player_color) // if player use black BK &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WK &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Queen: if (player_color) BQ &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WQ &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Rook: if (player_color) BR &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WR &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Knight: if (player_color) BN &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WN &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Bishop: if (player_color) BB &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WB &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Pawn: if (player_color) BP &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WP &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; default: break; } switch (move.moved_type) { case PieceType.King: if (player_color) { WK |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WK &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { BK |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BK &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } PKC = false; PQC = false; break; case PieceType.Queen: if (player_color) { WQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WQ &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { BQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BQ &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Rook: if (player_color) { WR |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WR &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.from_file == 0) P_Q_C = false; if (move.from_file == 7) P_K_C = false; } else { BR |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BR &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.from_file == 0) P_K_C = false; if (move.from_file == 7) P_Q_C = false; } break; case PieceType.Knight: if (player_color) { WN |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WN &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { BN |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BN &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Bishop: if (player_color) { WB |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WB &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { BB |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BB &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Pawn: if (player_color) { WP &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if(move.promote) //if the pawn got promoted, then update a new piece in queen bitboard WQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); else WP |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); } else { BP &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.promote) //if the pawn got promoted, then update a new piece in queen bitboard BQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); else BP |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); } break; default: break; } // switch for special events ChessBoard cb = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C); theList.Add(cb); } } return theList; }
public static void addAIBestMoveQueue(Move historymove = null) { best_move_queue.Enqueue(historymove); }
public MoveCompare(Move last_move=null) { this.last_move = last_move; }
public MoveCompare() { this.last_move = null; }
public static void setCurrentBitboardsHistoryMove(Move historymove=null) { history_move = historymove; }
public static bool LegalSingleRookMove(ulong white_rook, ulong black_occupied, int x, int y, int new_x, int new_y) { int rook_index = (7 - y) * 8 + x; int new_rook_index = (7 - new_y) * 8 + new_x; Move player_move = new Move((7 - y), x, (7 - new_y), new_x); if (((white_rook >> rook_index) & 1) == 1) { ArrayList pos_moves = PossibleRook(white_rook, black_occupied); foreach (Move move in pos_moves) { if (move.from_rank == (7 - y) && move.from_file == x && move.to_rank == (7 - new_y) && move.to_file == new_x) { return true; } } return false; } else { return false; } }
public static bool LegalSingleKnightMove(ulong white_knight, ulong black_occupied, int x, int y, int new_x, int new_y) { int knight_index = (7 - y) * 8 + x; int new_knight_index = (7 - new_y) * 8 + new_x; Move player_move = new Move((7 - y),x , (7 - new_y), new_x); //Console.WriteLine("index " + knight_index); if(((white_knight >> knight_index) & 1) == 1) { ArrayList pos_moves = PossibleKnight(white_knight, black_occupied); foreach(Move move in pos_moves) { if (move.from_rank == (7 - y) && move.from_file == x && move.to_rank == (7 - new_y) && move.to_file == new_x) { return true; } } return false; } else { return false; } }
public ChessBoard(ulong WP, ulong WN, ulong WB, ulong WQ, ulong WR, ulong WK, ulong BP, ulong BN, ulong BB, ulong BQ, ulong BR, ulong BK, Move move=null , bool MKC= true, bool MQC =true, bool PKC= true, bool PQC=true) { this.WP = WP; this.WN = WN; this.WB = WB; this.WQ = WQ; this.WR = WR; this.WK = WK; this.BP = BP; this.BN = BN; this.BB = BB; this.BQ = BQ; this.BR = BR; this.BK = BK; this.move = move; this.MKC = MKC; this.MQC = MQC; this.PKC = PKC; this.PQC = PQC; //this.player = currentPlayer; createUsefullBitboards(); }
public int AlphaBetaSearch(int alpha, int beta, int layer, bool min_max) { if (move == null) { move = new Move(0, 0, 0, 0); } if (layer == 0) { return evaluateBoard(min_max, this); } else if (min_max) //max node { List<ChessBoard> chessboards = MoveGenerator.generateChessBoards(min_max, BP, BR, BN, BB, BQ, BK, WP, WR, WN, WB, WQ, WK, this.move, this.MKC, this.MQC, this.PKC, this.PQC, this.PC_DONE, this.MC_DONE); if (chessboards.Count == 0) { if (MoveGenerator.isKingInCheck(min_max)) { //Console.WriteLine("Game over machine lost"); bestState = null; return int.MinValue+1; } else { //Console.WriteLine("Game over draw (max) 1"); bestState = null; return 0; } } foreach (ChessBoard CB in chessboards) { if (DateTime.Compare(DateTime.Now, MoveGenerator.end_time) > 0) { return int.MaxValue-1; } if (CB.move.cap_type == PieceType.King) { bestState = CB; return int.MaxValue-1; //just change it to min, it was max } int result = CB.AlphaBetaSearch(alpha, beta, layer - 1, !min_max); if (result > alpha) { alpha = result; bestState = CB; } if (alpha >= beta) { break; } } if (MoveGenerator.isKingInCheck(min_max) && alpha == int.MinValue) { Console.WriteLine("Game over machine lost"); bestState = null; return int.MinValue+1; } else if(!MoveGenerator.isKingInCheck(min_max) && alpha == int.MinValue) { Console.WriteLine("Game over draw (max) 2"); bestState = null; return 0; } return alpha; } else { List<ChessBoard> chessboards = MoveGenerator.generateChessBoards(min_max, BP, BR, BN, BB, BQ, BK, WP, WR, WN, WB, WQ, WK, this.move, this.MKC, this.MQC, this.PKC, this.PQC, this.PC_DONE, this.MC_DONE); if (chessboards.Count == 0) { if (MoveGenerator.isKingInCheck(min_max)) { //Console.WriteLine("Game over player lost"); bestState = null; return int.MaxValue-1; } else { //Console.WriteLine("Game over draw (min) 1"); bestState = null; return 0; } } foreach (ChessBoard CB in chessboards) { if (DateTime.Compare(DateTime.Now, MoveGenerator.end_time) > 0) { return int.MinValue; } if (CB.move.cap_type == PieceType.King) { bestState = CB; return int.MinValue+1; } int result = CB.AlphaBetaSearch(alpha, beta, layer - 1, !min_max); if (result < beta) { beta = result; bestState = CB; } if (alpha >= beta) { break; } } if (MoveGenerator.isKingInCheck(min_max) && beta == int.MaxValue) { //Console.WriteLine("Game over player lost"); bestState = null; return int.MaxValue-1; } else if (!MoveGenerator.isKingInCheck(min_max) && beta == int.MaxValue) { //Console.WriteLine("Game over draw (min) 2"); bestState = null; return 0; } return beta; } }
public static List<ChessBoard> generateChessBoards(bool min_max, ulong B_P, ulong B_R, ulong B_N, ulong B_B, ulong B_Q, ulong B_K, ulong W_P, ulong W_R, ulong W_N, ulong W_B, ulong W_Q, ulong W_K, Move history_move, bool MKC, bool MQC, bool PKC, bool PQC, bool PC_DONE, bool MC_DONE) { List<ChessBoard> theList = new List<ChessBoard>(); ArrayList lastMovedCaptured = new ArrayList(); ArrayList captureMoves = new ArrayList(); ArrayList otherMoves = new ArrayList(); bool useHistory = true; bool useBestMove = false; if (history_move.to_file == history_move.from_file && history_move.to_rank == history_move.from_rank) { useHistory = false; } if (min_max) // if it is an ai max node { setCurrentBitboards(B_P, B_R, B_N, B_B, B_Q, B_K, W_P, W_R, W_N, W_B, W_Q, W_K); setCurrentBitboardsHistoryMove(history_move); setCurrentCastlingCondition(MKC, MQC, PKC, PQC); ArrayList moves = PossibleMovesMachine(); Move last_time_best = null; if (best_move_queue.Count != 0) { last_time_best = best_move_queue.Dequeue(); useBestMove = true; } foreach (Move move in moves) { if (useBestMove) { if (last_time_best.to_file == move.to_file && last_time_best.to_rank == move.to_rank && last_time_best.from_file == move.from_file && last_time_best.from_rank == move.from_rank) continue; } if (move.cap_type != null) { if (useHistory) { if (history_move.to_file == move.to_file && history_move.to_rank == move.to_rank) lastMovedCaptured.Add(move); else captureMoves.Add(move); } } else otherMoves.Add(move); } moves.Clear(); if (useBestMove) { moves.Add(last_time_best); } moves.AddRange(lastMovedCaptured); moves.AddRange(captureMoves); moves.AddRange(otherMoves); foreach (Move move in moves) { ulong BP = B_P; ulong WP = W_P; ulong BR = B_R; ulong WR = W_R; ulong BN = B_N; ulong WN = W_N; ulong BQ = B_Q; ulong WQ = W_Q; ulong BB = B_B; ulong WB = W_B; ulong BK = B_K; ulong WK = W_K; bool M_K_C = MKC; bool M_Q_C = MQC; bool P_K_C = PKC; bool P_Q_C = PQC; if (move.MQC) // if move is a machine queen side castling { int king_index = move.from_rank * 8 + move.from_file; if (player_color) { BK = (BK >> 2); BR &= ~((ulong)0x0100000000000000); BR |= (ulong)0x0800000000000000; } else { WK = (WK << 2); WR &= ~((ulong)0x8000000000000000); WR |= (ulong)0x0100000000000000; } M_Q_C = false; M_K_C = false; MC_DONE = true; ChessBoard castling_b = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C, PC_DONE, MC_DONE); theList.Add(castling_b); continue; } if (move.MKC) // if the move is a machine king side castling { int king_index = move.from_rank * 8 + move.from_file; if (player_color) { BK = (BK << 2); BR &= ~((ulong)0x8000000000000000); BR |= (ulong)0x2000000000000000; } else { WK = (WK >> 2); WR &= ~((ulong)0x0100000000000000); WR |= (ulong)0x0400000000000000; } M_Q_C = false; M_K_C = false; MC_DONE = true; ChessBoard castling_b = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C, PC_DONE, MC_DONE); theList.Add(castling_b); continue; } //normal moves are following switch (move.cap_type) { case PieceType.King: if (player_color) //if player play black then ai updates the white piece WK &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BK &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Queen: if (player_color) WQ &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BQ &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Rook: if (player_color) WR &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BR &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Knight: if (player_color) WN &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BN &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Bishop: if (player_color) WB &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BB &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Pawn: if (player_color) WP &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else BP &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; default: break; } switch (move.moved_type) { case PieceType.King: if (player_color) { BK |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BK &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { WK |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WK &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } M_K_C = false; M_Q_C = false; break; case PieceType.Queen: if (player_color) { BQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BQ &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { WQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WQ &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Rook: if (player_color) { BR |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BR &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.from_file == 0) M_Q_C = false; if (move.from_file == 7) M_K_C = false; } else { WR |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WR &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.from_file == 0) M_K_C = false; if (move.from_file == 7) M_Q_C = false; } break; case PieceType.Knight: if (player_color) { BN |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BN &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { WN |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WN &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Bishop: if (player_color) { BB |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BB &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { WB |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WB &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Pawn: if (player_color) { BP &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.promote) //if the pawn got promoted, then update a new piece in queen bitboard BQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); else BP |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); } else { WP &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.promote) //if the pawn got promoted, then update a new piece in queen bitboard WQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); else WP |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); } break; default: break; } ChessBoard cb = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C, PC_DONE, MC_DONE); theList.Add(cb); } } // if it is a player min node else { setCurrentBitboards(B_P, B_R, B_N, B_B, B_Q, B_K, W_P, W_R, W_N, W_B, W_Q, W_K); setCurrentBitboardsHistoryMove(history_move); setCurrentCastlingCondition(MKC, MQC, PKC, PQC); ArrayList moves = PossibleMovesPlayer(); Move last_time_best = null; if (best_move_queue.Count != 0) { last_time_best = best_move_queue.Dequeue(); useBestMove = true; } foreach (Move move in moves) { if (useBestMove) { if (last_time_best.to_file == move.to_file && last_time_best.to_rank == move.to_rank && last_time_best.from_file == move.from_file && last_time_best.from_rank == move.from_rank) continue; } if (move.cap_type != null) { if (useHistory) { if (history_move.to_file == move.to_file && history_move.to_rank == move.to_rank) lastMovedCaptured.Add(move); else captureMoves.Add(move); } } else otherMoves.Add(move); } moves.Clear(); if (useBestMove) { moves.Add(last_time_best); } moves.AddRange(lastMovedCaptured); moves.AddRange(captureMoves); moves.AddRange(otherMoves); foreach (Move move in moves) { ulong BP = B_P; ulong WP = W_P; ulong BR = B_R; ulong WR = W_R; ulong BN = B_N; ulong WN = W_N; ulong BQ = B_Q; ulong WQ = W_Q; ulong BB = B_B; ulong WB = W_B; ulong BK = B_K; ulong WK = W_K; bool M_K_C = MKC; bool M_Q_C = MQC; bool P_K_C = PKC; bool P_Q_C = PQC; if (move.PQC) // if move is a player queen side castling { if (player_color) { WK = (WK >> 2); WR &= ~((ulong)0x0000000000000001); WR |= (ulong)0x0000000000000008; } else { BK = (BK << 2); BR &= ~((ulong)0x0000000000000080); BR |= (ulong)0x0000000000000010; } P_Q_C = false; P_K_C = false; PC_DONE = true; ChessBoard castling_b = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C, PC_DONE, MC_DONE); theList.Add(castling_b); continue; } if (move.PKC) // if the move is a player king side castling { if (player_color) { WK = (WK << 2); WR &= ~((ulong)0x0000000000000080); WR |= (ulong)0x0000000000000020; } else { BK = (BK >> 2); BR &= ~((ulong)0x0000000000000001); BR |= (ulong)0x0000000000000004; } P_Q_C = false; P_K_C = false; PC_DONE = true; ChessBoard castling_b = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C, PC_DONE, MC_DONE); theList.Add(castling_b); continue; } switch (move.cap_type) { case PieceType.King: if (player_color) // if player use black BK &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WK &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Queen: if (player_color) BQ &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WQ &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Rook: if (player_color) BR &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WR &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Knight: if (player_color) BN &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WN &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Bishop: if (player_color) BB &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WB &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; case PieceType.Pawn: if (player_color) BP &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); else WP &= ~((ulong)1 << (move.to_rank * 8 + move.to_file)); break; default: break; } switch (move.moved_type) { case PieceType.King: if (player_color) { WK |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WK &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { BK |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BK &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } PKC = false; PQC = false; break; case PieceType.Queen: if (player_color) { WQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WQ &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { BQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BQ &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Rook: if (player_color) { WR |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WR &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.from_file == 0) P_Q_C = false; if (move.from_file == 7) P_K_C = false; } else { BR |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BR &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.from_file == 0) P_K_C = false; if (move.from_file == 7) P_Q_C = false; } break; case PieceType.Knight: if (player_color) { WN |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WN &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { BN |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BN &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Bishop: if (player_color) { WB |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); WB &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } else { BB |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); BB &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); } break; case PieceType.Pawn: if (player_color) { WP &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.promote) //if the pawn got promoted, then update a new piece in queen bitboard WQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); else WP |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); } else { BP &= ~((ulong)1 << (move.from_rank * 8 + move.from_file)); if (move.promote) //if the pawn got promoted, then update a new piece in queen bitboard BQ |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); else BP |= ((ulong)1 << (move.to_rank * 8 + move.to_file)); } break; default: break; } ChessBoard cb = new ChessBoard(WP, WN, WB, WQ, WR, WK, BP, BN, BB, BQ, BR, BK, move, M_K_C, M_Q_C, P_K_C, P_Q_C, PC_DONE, MC_DONE); theList.Add(cb); } } return theList; }