private void startIterativeSearch(ChessBoard init) { DateTime start_time = DateTime.Now; MoveGenerator.end_time = start_time.AddSeconds(this.Interval); //set iterative deepning end time; int i = 1; while (DateTime.Compare(DateTime.Now , MoveGenerator.end_time)<=0) { Console.WriteLine("Depth is "+i); init.AlphaBetaSearch(int.MinValue, int.MaxValue, i, true); ChessBoard bestState = init.bestState; MoveGenerator.best_move_queue.Clear(); while (bestState != null) { MoveGenerator.addAIBestMoveQueue(bestState.move); bestState = bestState.bestState; } //foreach (Move move in MoveGenerator.best_move_queue) //{ // Console.WriteLine("Best move is " + move.from_rank + move.from_file + move.to_rank + move.to_file); //} i++; } return; }
public void AlgorithmThread() { try { while (true) { if (turn) { this.MachineTimer.startClock(); // this is the current chess board state ChessBoard curr_board_state = new ChessBoard(MoveGenerator.white_pawns, MoveGenerator.white_knights, MoveGenerator.white_bishops, MoveGenerator.white_queens, MoveGenerator.white_rooks, MoveGenerator.white_king, MoveGenerator.black_pawns, MoveGenerator.black_knights, MoveGenerator.black_bishops, MoveGenerator.black_queens, MoveGenerator.black_rooks, MoveGenerator.black_king, MoveGenerator.history_move, MoveGenerator.MKC, MoveGenerator.MQC, MoveGenerator.PKC, MoveGenerator.PQC); //code below is for updating frontend Move ai_move = getNextMove(curr_board_state); if (ai_move.MKC || ai_move.MQC) { Console.WriteLine("AI moves Castling"); Messenger.Default.Send(new MachineMoveMessage { Turn = this.turn, From_Rank = ai_move.from_rank, From_File = ai_move.from_file, MKC = ai_move.MKC, MQC = ai_move.MQC }); this.MachineTimer.stopClock(); this.turn = false; } else { //Console.WriteLine("AI Move " + ai_move.moved_type + " from " + ai_move.from_rank + " " + ai_move.from_file + " to " + ai_move.to_rank + " " + ai_move.to_file + " Cap " + ai_move.cap_type); Messenger.Default.Send(new MachineMoveMessage { Turn = this.turn, From_Rank = ai_move.from_rank, From_File = ai_move.from_file, To_Rank = ai_move.to_rank, To_File = ai_move.to_file }); this.MachineTimer.stopClock(); this.turn = false; } Console.WriteLine(" board state is " + Convert.ToString((long)MoveGenerator.pieces_occupied, 2)); //!!!!!!! } } } catch (Exception ex) { Console.WriteLine("Something wrong with the algorithm. check the code!!!"); } }
public Move getNextMove(ChessBoard curr_board_state) { startIterativeSearch(curr_board_state); MoveGenerator.setCurrentBitboards(curr_board_state.bestState.BP, curr_board_state.bestState.BR, curr_board_state.bestState.BN, curr_board_state.bestState.BB, curr_board_state.bestState.BQ, curr_board_state.bestState.BK, curr_board_state.bestState.WP, curr_board_state.bestState.WR, curr_board_state.bestState.WN, curr_board_state.bestState.WB, curr_board_state.bestState.WQ, curr_board_state.bestState.WK); MoveGenerator.setCurrentBitboardsHistoryMove(curr_board_state.bestState.move); MoveGenerator.setCurrentCastlingCondition(curr_board_state.bestState.MKC, curr_board_state.bestState.MQC, curr_board_state.bestState.PKC, curr_board_state.bestState.PQC); return curr_board_state.bestState.move; }
public void MVMAlgorithmThread() { try { while (true) { if (turn) { // this is the current chess board state ChessBoard curr_board_state = new ChessBoard(MoveGenerator.white_pawns, MoveGenerator.white_knights, MoveGenerator.white_bishops, MoveGenerator.white_queens, MoveGenerator.white_rooks, MoveGenerator.white_king, MoveGenerator.black_pawns, MoveGenerator.black_knights, MoveGenerator.black_bishops, MoveGenerator.black_queens, MoveGenerator.black_rooks, MoveGenerator.black_king, MoveGenerator.history_move, MoveGenerator.MKC, MoveGenerator.MQC, MoveGenerator.PKC, MoveGenerator.PQC, false, false); Move ai_move = getNextMove(curr_board_state, min_max); if (min_max) { if (ai_move.MKC || ai_move.MQC) { Console.WriteLine("AI 1 moves Castling"); Messenger.Default.Send(new MachineMoveMessage { Turn = this.turn, From_Rank = ai_move.from_rank, From_File = ai_move.from_file, MKC = ai_move.MKC, MQC = ai_move.MQC }); } else if (ai_move.promote) { Console.WriteLine("AI 1 moves promotion"); Messenger.Default.Send(new MachineMoveMessage { Turn = this.turn, From_Rank = ai_move.from_rank, From_File = ai_move.from_file, To_Rank = ai_move.to_rank, To_File = ai_move.to_file, Promotion = ai_move.promote }); } else { Messenger.Default.Send(new MachineMoveMessage { Turn = this.turn, From_Rank = ai_move.from_rank, From_File = ai_move.from_file, To_Rank = ai_move.to_rank, To_File = ai_move.to_file }); } Console.WriteLine("AI 1 Move is " + ai_move.from_rank + ai_move.from_file + ai_move.to_rank + ai_move.to_file); //!!!!!!! } else { if (ai_move.PKC || ai_move.PQC) { Messenger.Default.Send(new MachineMoveMessage { Turn = this.turn, From_Rank = ai_move.from_rank, From_File = ai_move.from_file, PKC = ai_move.PKC, PQC = ai_move.PQC }); } else if (ai_move.promote) { Messenger.Default.Send(new MachineMoveMessage { Turn = this.turn, From_Rank = ai_move.from_rank, From_File = ai_move.from_file, Promotion = ai_move.promote }); } else { Messenger.Default.Send(new MachineMoveMessage { Turn = this.turn, From_Rank = ai_move.from_rank, From_File = ai_move.from_file, To_Rank = ai_move.to_rank, To_File = ai_move.to_file }); } Console.WriteLine("AI 2 Move is " + ai_move.from_rank + ai_move.from_file + ai_move.to_rank + ai_move.to_file); //!!!!!!! } min_max = !min_max; Console.WriteLine(" board state is " + Convert.ToString((long)MoveGenerator.pieces_occupied, 2)); //!!!!!!! } } } catch (Exception ex) { Console.WriteLine("Something wrong with the algorithm. check the code!!!"); Console.WriteLine(ex); } }
private void startIterativeSearch(ChessBoard init, bool min_max) { DateTime start_time = DateTime.Now; MoveGenerator.end_time = start_time.AddSeconds(this.Interval); //set iterative deepning end time; int i = 1; MoveGenerator.best_move_queue.Clear(); while (DateTime.Compare(DateTime.Now, MoveGenerator.end_time) <= 0) { MoveGenerator.states = 0; Console.WriteLine("Depth is " + i); int alpha_beta = init.AlphaBetaSearch(int.MinValue, int.MaxValue, i, min_max); ChessBoard bestState = init.bestState; if (bestState == null) { Console.WriteLine("Game over!!!"); MessageBoxResult result = MessageBox.Show("Game over", "Confirmation", MessageBoxButton.OK); if (result == MessageBoxResult.OK) { Application.Current.Dispatcher.Invoke((Action)(() => { Application.Current.Shutdown(); })); } } MoveGenerator.best_move_queue.Clear(); while (bestState != null) { MoveGenerator.addAIBestMoveQueue(bestState.move); bestState = bestState.bestState; } //Console.WriteLine("Searching in layer: {0} through {1} evaluations with an average branching factor of {2}", i, MoveGenerator.states, (Math.Pow(MoveGenerator.states, (1 / (double)i)))); MoveGenerator.branchingfactor += (Math.Pow(MoveGenerator.states, (1 / (double)i))); MoveGenerator.searchcounter += 1; //Console.WriteLine("Average branching factor of the algorithm: "+ (MoveGenerator.branchingfactor/ MoveGenerator.searchcounter)); i++; } return; }
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 Move getNextMove(ChessBoard curr_board_state, bool min_max) { startIterativeSearch(curr_board_state, min_max); //this is game over if (curr_board_state.bestState == null) return null; MoveGenerator.setCurrentBitboards(curr_board_state.bestState.BP, curr_board_state.bestState.BR, curr_board_state.bestState.BN, curr_board_state.bestState.BB, curr_board_state.bestState.BQ, curr_board_state.bestState.BK, curr_board_state.bestState.WP, curr_board_state.bestState.WR, curr_board_state.bestState.WN, curr_board_state.bestState.WB, curr_board_state.bestState.WQ, curr_board_state.bestState.WK); MoveGenerator.setCurrentBitboardsHistoryMove(curr_board_state.bestState.move); MoveGenerator.setCurrentCastlingCondition(curr_board_state.bestState.MKC, curr_board_state.bestState.MQC, curr_board_state.bestState.PKC, curr_board_state.bestState.PQC); return curr_board_state.bestState.move; }
//public void Copyboard(ulong WP, ulong WN, ulong WB, ulong WQ, ulong WR, ulong WK, ulong BP, ulong BN, ulong BB, ulong BQ, ulong BR, ulong BK) //{ // 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; // //createUsefullBitboards(); //} // TO DO public int evaluateBoard(bool min_max, ChessBoard leaf_chessboard) { int Machine_Points = 0; int Player_Points = 0; // Evaluate pieces under threat MoveGenerator.setCurrentBitboards(leaf_chessboard.BP, leaf_chessboard.BR, leaf_chessboard.BN, leaf_chessboard.BB, leaf_chessboard.BQ, leaf_chessboard.BK, leaf_chessboard.WP, leaf_chessboard.WR, leaf_chessboard.WN, leaf_chessboard.WB, leaf_chessboard.WQ, leaf_chessboard.WK); MoveGenerator.setCurrentBitboardsHistoryMove(leaf_chessboard.move); MoveGenerator.setCurrentCastlingCondition(leaf_chessboard.MKC, leaf_chessboard.MQC, leaf_chessboard.PKC, leaf_chessboard.PQC); ArrayList moves; if (leaf_chessboard.move.PKC || leaf_chessboard.move.PQC) { Player_Points += 14; } if (leaf_chessboard.move.MKC || leaf_chessboard.move.MQC) { //Console.WriteLine("Hallo"); Machine_Points += 14; } if (min_max) { moves = MoveGenerator.PossibleMovesMachine(); } else { moves = MoveGenerator.PossibleMovesPlayer(); } moves.Sort(new MoveCompare()); // sort the list so it get captured move first; Nullable<PieceType> piece_cap = null; foreach (Move leaf_move in moves) { //this is castling move bonus if (leaf_move.cap_type != piece_cap) { if (min_max) //if it is a max leaf node, add value to machine's value; Machine_Points += 7; else Player_Points += 7; } else { break; } } for (int i = 0; i < 64; i++) { // Evaluate positions of each piece on the board if (((leaf_chessboard.occupied >> i) & 1) == 1) { if (MoveGenerator.player_color) //if player plays white { if (((leaf_chessboard.WB >> i) & 1) == 1) { //Evaluation of White Bishop Player_Points += (Constants.Constants.BISHOP_WEIGHT+ BishopTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.WK >> i) & 1) == 1) { //Evaluation of White King Player_Points += (Constants.Constants.KING_WEIGHT+ KingTableO[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.WN >> i) & 1) == 1) { //Evaluation of White Knight Player_Points += (Constants.Constants.KNIGHT_WEIGHT+ KnightTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.WP >> i) & 1) == 1) { //Evaluation of White Pawns Player_Points += (Constants.Constants.PAWN_WEIGHT+ PawnTable[(8 * (7 - i / 8) + i % 8)]); //evaluate of dobble pawn weakness for (int rank= (7- i/8); rank >=0 ; rank--) if (((leaf_chessboard.WP >> (i+8*rank)) & 1) ==1) { Player_Points += -7; } } else if (((leaf_chessboard.WQ >> i) & 1) == 1) { //Evaluation of White Queen Player_Points += (Constants.Constants.QUEEN_WEIGHT+ QueenTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.WR >> i) & 1) == 1) { //Evaluation of White Rook Player_Points += (Constants.Constants.ROOK_WEIGHT+ RookTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BB >> i) & 1) == 1) { //Evaluation of Black Bishop Machine_Points += (Constants.Constants.BISHOP_WEIGHT+ BishopTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BK >> i) & 1) == 1) { //Evaluation of Black King Machine_Points += (Constants.Constants.KING_WEIGHT + KingTableO[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BN >> i) & 1) == 1) { //Evaluation of Black Knight Machine_Points += (Constants.Constants.KNIGHT_WEIGHT + KnightTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BP >> i) & 1) == 1) { //Evaluation of Black Pawns Machine_Points += (Constants.Constants.PAWN_WEIGHT+ PawnTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); //evaluate of dobble pawn weakness for (int rank = (7 - i / 8); rank >= 0; rank--) if (((leaf_chessboard.WP >> (i + 8 * rank)) & 1) == 1) { Machine_Points += -7; } } else if (((leaf_chessboard.BQ >> i) & 1) == 1) { //Evaluation of Black Queen Machine_Points += (Constants.Constants.QUEEN_WEIGHT+ QueenTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BR >> i) & 1) == 1) { //Evaluation of Black Rook Machine_Points += (Constants.Constants.ROOK_WEIGHT + RookTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } } else //player plays black { if (((leaf_chessboard.WB >> i) & 1) == 1) { //Evaluation of White Bishop Machine_Points += (Constants.Constants.BISHOP_WEIGHT+ BishopTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.WK >> i) & 1) == 1) { //Evaluation of White King Machine_Points += (Constants.Constants.KING_WEIGHT+ KingTableO[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.WN >> i) & 1) == 1) { //Evaluation of White Knight Machine_Points += (Constants.Constants.KNIGHT_WEIGHT+ KnightTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.WP >> i) & 1) == 1) { //Evaluation of White Pawns Machine_Points += (Constants.Constants.PAWN_WEIGHT+ PawnTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); //evaluate of dobble pawn weakness for (int rank = (7 - i / 8); rank >= 0; rank--) if (((leaf_chessboard.WP >> (i + 8 * rank)) & 1) == 1) { Machine_Points += -7; } } else if (((leaf_chessboard.WQ >> i) & 1) == 1) { //Evaluation of White Queen Machine_Points +=(Constants.Constants.QUEEN_WEIGHT+ QueenTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.WR >> i) & 1) == 1) { //Evaluation of White Rook Machine_Points += (Constants.Constants.ROOK_WEIGHT+ RookTable[Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BB >> i) & 1) == 1) { //Evaluation of Black Bishop Player_Points += (Constants.Constants.BISHOP_WEIGHT+ BishopTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BK >> i) & 1) == 1) { //Evaluation of Black King Player_Points += (Constants.Constants.KING_WEIGHT+ KingTableO[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BN >> i) & 1) == 1) { //Evaluation of Black Knight Player_Points += (Constants.Constants.KNIGHT_WEIGHT+ KnightTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BP >> i) & 1) == 1) { //Evaluation of Black Pawns Player_Points += (Constants.Constants.PAWN_WEIGHT+ PawnTable[(8 * (7 - i / 8) + i % 8)]); //evaluate of dobble pawn weakness for (int rank = (7 - i / 8); rank >= 0; rank--) if (((leaf_chessboard.WP >> (i + 8 * rank)) & 1) == 1) { Player_Points += -7; } } else if (((leaf_chessboard.BQ >> i) & 1) == 1) { //Evaluation of Black Queen Player_Points +=(Constants.Constants.QUEEN_WEIGHT+ QueenTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BR >> i) & 1) == 1) { //Evaluation of Black Rook Player_Points += (Constants.Constants.ROOK_WEIGHT+ RookTable[(8 * (7 - i / 8) + i % 8)]); } } } } return Machine_Points - Player_Points; //(machine point - player point) }
public int AlphaBetaSearch(int alpha, int beta, int layer, bool min_max) { if (layer == 0) { return evaluateBoard(min_max, this); } else if (min_max) { 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); foreach (ChessBoard CB in chessboards) { if (DateTime.Compare(DateTime.Now, MoveGenerator.end_time) > 0) { break; } //Console.WriteLine("Chessboard item max " + Convert.ToString((long)CB.occupied, 2)); //Console.WriteLine("Chessboard eva " + evaluateBoard(!min_max, CB)); //evaluateBoard(min_max, CB); //Console.WriteLine("Chessboard eva " + evaluateBoard(min_max, CB)); //evaluateBoard(min_max, CB); int result = CB.AlphaBetaSearch(alpha, beta, layer - 1, !min_max); if (result > alpha) { alpha = result; bestState = CB; } if (alpha >= beta) { break; } } 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); foreach (ChessBoard CB in chessboards) { if (DateTime.Compare(DateTime.Now, MoveGenerator.end_time) > 0) { break; } // Console.WriteLine("This is min // Console.WriteLine("Chessboard item min " + Convert.ToString((long)CB.occupied, 2)); //Console.WriteLine("Chessboard Bish min " + Convert.ToString((long)CB.BB, 2)); //Console.WriteLine("Chessboard knig min " + Convert.ToString((long)CB.WN, 2)); //Console.WriteLine("Chessboard eva " + evaluateBoard(!min_max, CB)); //evaluateBoard(min_max, CB); int result = CB.AlphaBetaSearch(alpha, beta, layer - 1, !min_max); if (result < beta) { beta = result; bestState = CB; } if (alpha >= beta) { break; } } return beta; } }
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 int evaluateBoard(bool min_max, ChessBoard leaf_chessboard) { //MoveGenerator.states += 1; int Machine_Points = 0; int Player_Points = 0; // Evaluate pieces under threat ulong[] bitboards = MoveGenerator.getCurrentBitboards(); MoveGenerator.setCurrentBitboards(leaf_chessboard.BP, leaf_chessboard.BR, leaf_chessboard.BN, leaf_chessboard.BB, leaf_chessboard.BQ, leaf_chessboard.BK, leaf_chessboard.WP, leaf_chessboard.WR, leaf_chessboard.WN, leaf_chessboard.WB, leaf_chessboard.WQ, leaf_chessboard.WK); ArrayList moves; if (leaf_chessboard.PC_DONE) { Player_Points += 100; } if (leaf_chessboard.MC_DONE) { Machine_Points += 100; } if (min_max) { moves = MoveGenerator.PossibleMovesMachine(); } else { moves = MoveGenerator.PossibleMovesPlayer(); } moves.Sort(new MoveCompare()); // sort the list so it get captured move first; Nullable<PieceType> piece_cap = null; foreach (Move leaf_move in moves) { if (leaf_move.cap_type != piece_cap) { if (min_max) //if it is a max leaf node, add value to machine's value; Machine_Points += 7; else Player_Points += 7; } else { break; } } for (int i = 0; i < 64; i++) { // Evaluate positions of each piece on the board if (((leaf_chessboard.occupied >> i) & 1) == 1) { if (MoveGenerator.player_color) //if player plays white { if (((leaf_chessboard.WB >> i) & 1) == 1) { //Evaluation of White Bishop Player_Points += (Constants.Constants.BISHOP_WEIGHT+ Constants.Constants.BishopTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.WK >> i) & 1) == 1) { //Evaluation of White King Player_Points += (Constants.Constants.KING_WEIGHT+ Constants.Constants.KingTableO[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.WN >> i) & 1) == 1) { //Evaluation of White Knight Player_Points += (Constants.Constants.KNIGHT_WEIGHT+ Constants.Constants.KnightTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.WP >> i) & 1) == 1) { //Evaluation of White Pawns Player_Points += (Constants.Constants.PAWN_WEIGHT+ Constants.Constants.PawnTable[(8 * (7 - i / 8) + i % 8)]); //evaluate of dobble pawn weakness for (int rank= (7- i/8); rank >=0 ; rank--) if (((leaf_chessboard.WP >> (i+8*rank)) & 1) ==1) { Player_Points += -7; } } else if (((leaf_chessboard.WQ >> i) & 1) == 1) { //Evaluation of White Queen Player_Points += (Constants.Constants.QUEEN_WEIGHT+ Constants.Constants.QueenTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.WR >> i) & 1) == 1) { //Evaluation of White Rook Player_Points += (Constants.Constants.ROOK_WEIGHT+ Constants.Constants.RookTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BB >> i) & 1) == 1) { //Evaluation of Black Bishop Machine_Points += (Constants.Constants.BISHOP_WEIGHT+ Constants.Constants.BishopTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BK >> i) & 1) == 1) { //Evaluation of Black King Machine_Points += (Constants.Constants.KING_WEIGHT + Constants.Constants.KingTableO[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BN >> i) & 1) == 1) { //Evaluation of Black Knight Machine_Points += (Constants.Constants.KNIGHT_WEIGHT + Constants.Constants.KnightTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BP >> i) & 1) == 1) { //Evaluation of Black Pawns Machine_Points += (Constants.Constants.PAWN_WEIGHT+ Constants.Constants.PawnTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); //evaluate of dobble pawn weakness for (int rank = (7 - i / 8); rank >= 0; rank--) if (((leaf_chessboard.WP >> (i + 8 * rank)) & 1) == 1) { Machine_Points += -7; } } else if (((leaf_chessboard.BQ >> i) & 1) == 1) { //Evaluation of Black Queen Machine_Points += (Constants.Constants.QUEEN_WEIGHT+ Constants.Constants.QueenTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BR >> i) & 1) == 1) { //Evaluation of Black Rook Machine_Points += (Constants.Constants.ROOK_WEIGHT + Constants.Constants.RookTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } } else //player plays black { if (((leaf_chessboard.WB >> i) & 1) == 1) { //Evaluation of White Bishop Machine_Points += (Constants.Constants.BISHOP_WEIGHT+ Constants.Constants.BishopTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.WK >> i) & 1) == 1) { //Evaluation of White King Machine_Points += (Constants.Constants.KING_WEIGHT+ Constants.Constants.KingTableO[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.WN >> i) & 1) == 1) { //Evaluation of White Knight Machine_Points += (Constants.Constants.KNIGHT_WEIGHT+ Constants.Constants.KnightTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.WP >> i) & 1) == 1) { //Evaluation of White Pawns Machine_Points += (Constants.Constants.PAWN_WEIGHT+ Constants.Constants.PawnTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); //evaluate of dobble pawn weakness for (int rank = (7 - i / 8); rank >= 0; rank--) if (((leaf_chessboard.WP >> (i + 8 * rank)) & 1) == 1) { Machine_Points += -7; } } else if (((leaf_chessboard.WQ >> i) & 1) == 1) { //Evaluation of White Queen Machine_Points +=(Constants.Constants.QUEEN_WEIGHT+ Constants.Constants.QueenTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.WR >> i) & 1) == 1) { //Evaluation of White Rook Machine_Points += (Constants.Constants.ROOK_WEIGHT+ Constants.Constants.RookTable[Constants.Constants.Mirror64[(8 * (7 - i / 8) + i % 8)]]); } else if (((leaf_chessboard.BB >> i) & 1) == 1) { //Evaluation of Black Bishop Player_Points += (Constants.Constants.BISHOP_WEIGHT+ Constants.Constants.BishopTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BK >> i) & 1) == 1) { //Evaluation of Black King Player_Points += (Constants.Constants.KING_WEIGHT+ Constants.Constants.KingTableO[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BN >> i) & 1) == 1) { //Evaluation of Black Knight Player_Points += (Constants.Constants.KNIGHT_WEIGHT+ Constants.Constants.KnightTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BP >> i) & 1) == 1) { //Evaluation of Black Pawns Player_Points += (Constants.Constants.PAWN_WEIGHT+ Constants.Constants.PawnTable[(8 * (7 - i / 8) + i % 8)]); //evaluate of dobble pawn weakness for (int rank = (7 - i / 8); rank >= 0; rank--) if (((leaf_chessboard.WP >> (i + 8 * rank)) & 1) == 1) { Player_Points += -7; } } else if (((leaf_chessboard.BQ >> i) & 1) == 1) { //Evaluation of Black Queen Player_Points +=(Constants.Constants.QUEEN_WEIGHT+ Constants.Constants.QueenTable[(8 * (7 - i / 8) + i % 8)]); } else if (((leaf_chessboard.BR >> i) & 1) == 1) { //Evaluation of Black Rook Player_Points += (Constants.Constants.ROOK_WEIGHT+ Constants.Constants.RookTable[(8 * (7 - i / 8) + i % 8)]); } } } } MoveGenerator.setCurrentBitboards(bitboards[0], bitboards[1], bitboards[2], bitboards[3], bitboards[4], bitboards[5], bitboards[6], bitboards[7], bitboards[8], bitboards[9], bitboards[10], bitboards[11]); return Machine_Points - Player_Points; //(machine point - player point) }
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; }