Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 10
0
        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;
            }
        }
Ejemplo n.º 11
0
        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;
        }