Exemplo n.º 1
0
        public static void perft(ulong bKB, ulong bQB, ulong bRB, ulong bBB, ulong bNB, ulong bPB, ulong wKB, ulong wQB, ulong wRB, ulong wBB, ulong wNB, ulong wPB, ulong EPB, bool castleWKside, bool castleWQside, bool castleBKside, bool castleBQside, bool white2Move, int depth)
        {
            if (depth < perftMaxDepth)
            {
                string moves;
                char[] Cmoves = new char[4];
                if (white2Move)
                {
                    moves = Moves.possibleMovesW(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, EPB, castleWKside, castleWQside, castleBKside, castleBQside);
                }
                else
                {
                    moves = Moves.possibleMovesB(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, EPB, castleWKside, castleWQside, castleBKside, castleBQside);
                }
                for (int i = 0; i < moves.Length; i += 4)
                {
                    Cmoves[0] = moves[i]; Cmoves[1] = moves[i + 1]; Cmoves[2] = moves[i + 2]; Cmoves[3] = moves[i + 3];
                    int start = (((Cmoves[0] - '0') * 8) + (Cmoves[1] - '0'));
                    int end   = (((Cmoves[2] - '0') * 8) + (Cmoves[3] - '0'));

                    UInt64 bKBt = Moves.makeMove(bKB, Cmoves, 'k', start, end),
                           bQBt = Moves.makeMove(bQB, Cmoves, 'q', start, end),
                           bRBt = Moves.makeMove(bRB, Cmoves, 'r', start, end),
                           bBBt = Moves.makeMove(bBB, Cmoves, 'b', start, end),
                           bNBt = Moves.makeMove(bNB, Cmoves, 'n', start, end),
                           bPBt = Moves.makeMove(bPB, Cmoves, 'p', start, end),
                           wKBt = Moves.makeMove(wKB, Cmoves, 'K', start, end),
                           wQBt = Moves.makeMove(wQB, Cmoves, 'Q', start, end),
                           wRBt = Moves.makeMove(wRB, Cmoves, 'R', start, end),
                           wBBt = Moves.makeMove(wBB, Cmoves, 'B', start, end),
                           wNBt = Moves.makeMove(wNB, Cmoves, 'N', start, end),
                           wPBt = Moves.makeMove(wPB, Cmoves, 'P', start, end),
                           EPBt = Moves.makeMoveEP(wPB | bPB, Cmoves, start);

                    wRBt = Moves.CastleMove(wRBt, wKB, Cmoves, 'R', start);
                    bRBt = Moves.CastleMove(bRBt, bKB, Cmoves, 'r', start);

                    // BoardGeneration.drawArray(bKBt, bQBt, bRBt, bBBt, bNBt, bPBt, wKBt, wQBt, wRBt, wBBt, wNBt, wPBt);
                    // Console.WriteLine();
                    // Console.ReadKey();
                    // Console.Clear();

                    bool castleWKsideT = castleWKside, castleWQsideT = castleWQside, castleBKsideT = castleBKside, castleBQsideT = castleBQside;

                    if ((((UInt64)1 << start) & wKB) != 0)
                    {
                        castleWKsideT = false;
                        castleWQsideT = false;
                    }
                    if ((((UInt64)1 << start) & bKB) != 0)
                    {
                        castleBKsideT = false;
                        castleBQsideT = false;
                    }
                    if (((((UInt64)1 << start) & wRB) & ((UInt64)1 << 63)) != 0)
                    {
                        castleWKsideT = false;
                    }
                    if (((((UInt64)1 << start) & wRB) & ((UInt64)1 << 56)) != 0)
                    {
                        castleWQsideT = false;
                    }
                    if (((((UInt64)1 << start) & bRB) & ((UInt64)1 << 7)) != 0)
                    {
                        castleBKsideT = false;
                    }
                    if (((((UInt64)1 << start) & bRB) & (UInt64)1) != 0)
                    {
                        castleBQsideT = false;
                    }


                    //                    UInt64 occu = bKBt|bQBt|bRBt|bBBt|bNBt|bPBt|wKBt|wQBt|wRBt|wBBt|wNBt|wPBt;
                    if (((wKBt & Moves.unsafeWhite(bKBt, bQBt, bRBt, bBBt, bNBt, bPBt, wKBt, wQBt, wRBt, wBBt, wNBt, wPBt)) == 0 && white2Move) ||
                        ((bKBt & Moves.unsafeBlack(bKBt, bQBt, bRBt, bBBt, bNBt, bPBt, wKBt, wQBt, wRBt, wBBt, wNBt, wPBt)) == 0 && !white2Move))
                    {
                        if (depth + 1 == perftMaxDepth)
                        {
                            perftMoveCount++;
                        }
                        perft(bKBt, bQBt, bRBt, bBBt, bNBt, bPBt, wKBt, wQBt, wRBt, wBBt, wNBt, wPBt, EPBt, castleWKsideT, castleWQsideT, castleBKsideT, castleBQsideT, !white2Move, depth + 1);
                    }
                }
            }
        }
Exemplo n.º 2
0
        public static UInt64 EPB      = 0;      // en passant maske bliver sat af makeMoveEP()

        public static void initiateStdChess()   // starter skakspillet og sætter bitboards til hvad positionerne i arrayet er
        // 12 bitboards 1 for hver brik
        {
            UInt64 bKB = 0;
            UInt64 bQB = 0;
            UInt64 bRB = 0;
            UInt64 bBB = 0;
            UInt64 bNB = 0;
            UInt64 bPB = 0;
            UInt64 wKB = 0;
            UInt64 wQB = 0;
            UInt64 wRB = 0;
            UInt64 wBB = 0;
            UInt64 wNB = 0;
            UInt64 wPB = 0;


            char[,] chessBoard = new char[, ] // 2 dimensional array for startposition
            {
                /*//
                 * {bKC,eC,eC,eC,eC,eC,eC,eC},
                 * {eC,eC,eC,eC,eC,eC,eC,eC},
                 * {eC,eC,eC,eC,eC,eC,eC,eC},
                 * {eC,eC,eC,eC,eC,eC,eC,eC},
                 * {eC,eC,eC,eC,eC,eC,eC,eC},
                 * {eC,eC,eC,eC,eC,eC,eC,eC},
                 * {eC,eC,eC,wKC,eC,eC,bPC,eC},
                 * {eC,eC,eC,eC,eC,eC,eC,eC},
                 *
                 */
                /*
                 * // r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq
                 * {bRC,eC,eC,eC,bKC,eC,eC,bRC},
                 * {bPC,eC,bPC,bPC,bQC,bPC,bBC,eC},
                 * {bBC,bNC,eC,eC,bPC,bNC,bPC,eC},
                 * {eC,eC,eC,wPC,wNC,eC,eC,eC},
                 * {eC,bPC,eC,eC,wPC,eC,eC,eC},
                 * {eC,eC,wNC,eC,eC,wQC,eC,bPC},
                 * {wPC,wPC,wPC,wBC,wBC,wPC,wPC,wPC},
                 * {wRC,eC,eC,eC,wKC,eC,eC,wRC},
                 */                                         //
                //  NORMAL CHESS
                { bRC, bNC, bBC, bQC, bKC, bBC, bNC, bRC }, // startposition for spillet
                { bPC, bPC, bPC, bPC, bPC, bPC, bPC, bPC },
                { eC, eC, eC, eC, eC, eC, eC, eC },
                { eC, eC, eC, eC, eC, eC, eC, eC },
                { eC, eC, eC, eC, eC, eC, eC, eC },
                { eC, eC, eC, eC, eC, eC, eC, eC },
                { wPC, wPC, wPC, wPC, wPC, wPC, wPC, wPC },
                { wRC, wNC, wBC, wQC, wKC, wBC, wNC, wRC },
            };

            // putter bit i korrekt position for hver briks bitboard
            string binaryString;                                                                   // deklerer binarære streng

            for (int i = 0; i < 64; i++)                                                           // looper 64 gange, 1 for hver bit
            {
                binaryString = "0000000000000000000000000000000000000000000000000000000000000000"; // start streng bitboard
                binaryString = binaryString.Substring(i + 1) + "1" + binaryString.Substring(0, i); // for hver loop sæt 1 ind fra højre. første runde substring er fra index 1 til 63 + '1' plus substring 0,0 giver 0
                switch (chessBoard[i / 8, i % 8])                                                  // i/8 giver hvilken rank og i mod 8 giver hvilken file index i arrayet, som den binære string hører sammen med
                {
                case bRC:                                                                          // hvis indexet i arrayet er sort rook char
                    bRB += convertString2Bitboard(binaryString);                                   // adder med strengen koverteret til unsigned int 64
                    break;                                                                         // break ud af case

                case bNC:
                    bNB += convertString2Bitboard(binaryString);
                    break;

                case bBC:
                    bBB += convertString2Bitboard(binaryString);
                    break;

                case bQC:
                    bQB += convertString2Bitboard(binaryString);
                    break;

                case bKC:
                    bKB += convertString2Bitboard(binaryString);
                    break;

                case bPC:
                    bPB += convertString2Bitboard(binaryString);
                    break;

                // white pieces from here
                case wRC:
                    wRB += convertString2Bitboard(binaryString);
                    break;

                case wNC:
                    wNB += convertString2Bitboard(binaryString);
                    break;

                case wBC:
                    wBB += convertString2Bitboard(binaryString);
                    break;

                case wQC:
                    wQB += convertString2Bitboard(binaryString);
                    break;

                case wKC:
                    wKB += convertString2Bitboard(binaryString);
                    break;

                case wPC:
                    wPB += convertString2Bitboard(binaryString);
                    break;
                }
            }


            bool kingsafe = true;                                                          // bool om kongen er sikker
            bool whitewon = false;                                                         //bool om hvid har vundet
            bool blackwon = false;                                                         // bool om sort har vunder
            bool qgame    = false;                                                         // bool om spilleren har valgt q for at stoppe programmet/spillet

            while (true)                                                                   // program loop, kører indtil en break
            {
                string Wplay = "";                                                         // spillerens play string
                do                                                                         // do while loop for at få korrekt play af spilleren og printer boardet
                {
                    Console.Clear();                                                       // renser konsol vindue
                    drawArray(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB); // kalder drawArray for at printe et skakbræt ud fra tilstanden af alle bitboards
                    if (!kingsafe)                                                         // hvis kongen ikke er sikker informer spilleren
                    {
                        Console.WriteLine("Your move made your king in check");
                        Console.WriteLine("Try another move: ");
                        Console.WriteLine("Type 'h' for help");
                    }
                    else   // ellers print insert play og hvordan hjælpemenu tilgås
                    {
                        Console.WriteLine("Insert play: ");
                        Console.WriteLine("Type 'h' for help");
                    }
                    Wplay = Console.ReadLine().ToLower();                                                      // tager spilleren input og laver lower så caps lock gælder
                    if (!string.IsNullOrEmpty(Wplay) && Char.ToLower(Wplay[0]) == 'q')                         // hvis strengen ikke er tom og index 0 af playet er q
                    {
                        qgame = true;                                                                          // sæt qgame til true
                    }
                    if (!(string.IsNullOrEmpty(Wplay)) && Wplay[0] == 'h' && Wplay.Length == 1)                // hvis strengen ikke er tom og index 0 er h og længden er 1
                    {
                        PrintHelp();                                                                           //kald print hjælpemenu
                        Console.Write("\nPress a key to continue");
                        Console.ReadKey(true);                                                                 // venter på keypress fra spiller
                    }
                }while(!qgame && ((Wplay.Length < 4) || (string.IsNullOrEmpty(Wplay)) || (Wplay.Length > 6))); // do while kører så længe qgame ikke er false og længden er under 4 eller tom eller mere end 6 lang.
                if (qgame)                                                                                     // hvis qgame er true
                {
                    break;                                                                                     // break ud af spillet
                }

                Wplay = Tools.algebra2Move(Wplay); // laver player inputtet til programmets interne koordinatsystem

                /*
                 * Console.WriteLine(Wplay.Length);
                 * Console.WriteLine(Wplay);
                 * Console.WriteLine("play is");
                 * Console.ReadKey(true);
                 */
                char[] Pmoves = new char[4];                                                                                                                           // laver char array for at holde på trækket
                char[] Cmoves = new char[4];                                                                                                                           // laver char array for at holde på hvert muligt træk fundet af possibleMovesW
                Pmoves[0] = Wplay[0]; Pmoves[1] = Wplay[1]; Pmoves[2] = Wplay[2]; Pmoves[3] = Wplay[3];                                                                // putter hvert char i streng ind i char array
                string moves;                                                                                                                                          // streng der holder på alle mulige træk
                moves = Moves.possibleMovesW(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, EPB, castleWKside, castleWQside, castleBKside, castleBQside); // kalder metode der finder alle mulige træk
                if (!AnyLegalMove(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, moves, "white"))                                                         // kalder metode der checker om der findes nogen træk
                {
                    blackwon = true;                                                                                                                                   // sætter blackwon til true så korret meddelse kan printes efter break
                    break;                                                                                                                                             // breaker ud af program
                }
                for (int i = 0; i < moves.Length; i += 4)                                                                                                              // hver move er 4 chars så længden af moves divideret med 4 er antal træk(derfor i incrementer med 4)
                {
                    Cmoves[0] = moves[i]; Cmoves[1] = moves[i + 1]; Cmoves[2] = moves[i + 2]; Cmoves[3] = moves[i + 3];                                                // putter hver muligt move ind i Cmoves char arrayet
                    if (Tools.ArrC(Pmoves, Cmoves))                                                                                                                    // checker hvert move om spillerens move er ens med en af de mulige træk
                    {
                        if (checkMove(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, Pmoves, "white"))                                                    // checker om trækket for kongen til at blive i skak
                        {
                            kingsafe = true;                                                                                                                           // sætter kingsafe til true
                            int start = (((Pmoves[0] - '0') * 8) + (Pmoves[1] - '0'));                                                                                 // sætter start index ud fra trækket(minus '0' char konvertere char tallet til int automatisk)
                            int end   = (((Pmoves[2] - '0') * 8) + (Pmoves[3] - '0'));                                                                                 // sætter s**t index ud fra trækket(minus '0' char konvertere char tallet til int automatisk)

                            if ((((UInt64)1 << start) & wKB) != 0)                                                                                                     // hvis hvid konge bevæger sig set kongerokademuligheder til false
                            {
                                castleWKside = false;
                                castleWQside = false;
                            }
                            if (((((UInt64)1 << start) & wRB) & ((UInt64)1 << 63)) != 0)   // hvis hvid tårn på index 63(højre) bevæger sig set kongesiden til false
                            {
                                castleWKside = false;
                            }
                            if (((((UInt64)1 << start) & wRB) & ((UInt64)1 << 56)) != 0)   // hvis dronnigside tårnet bevæger sig set hvid dronning kongerokade til false
                            {
                                castleWQside = false;
                            }

                            // sender alle brikkers bitboard til makeMove metoden for at ændre deres bitboard afhængig af hvad trækket er
                            EPB = Moves.makeMoveEP(wPB | bPB, Cmoves, start);     // sætter en passant masken EPB til den til den fil hvor en bonde bevæger sig 2 ranks op, ellers sætter den 0 så den kun masker en runde
                            wRB = Moves.CastleMove(wRB, wKB, Cmoves, 'R', start); // checker om kongen bevæger sig 2 træk og sætter tårnets position ud fra det
                            bKB = Moves.makeMove(bKB, Cmoves, 'k', start, end);   // sætter sort konge bitboard til retur værdi af makeMove
                            bQB = Moves.makeMove(bQB, Cmoves, 'q', start, end);
                            bRB = Moves.makeMove(bRB, Cmoves, 'r', start, end);
                            bBB = Moves.makeMove(bBB, Cmoves, 'b', start, end);
                            bNB = Moves.makeMove(bNB, Cmoves, 'n', start, end);
                            bPB = Moves.makeMove(bPB, Cmoves, 'p', start, end);
                            wKB = Moves.makeMove(wKB, Cmoves, 'K', start, end);
                            wQB = Moves.makeMove(wQB, Cmoves, 'Q', start, end);
                            wRB = Moves.makeMove(wRB, Cmoves, 'R', start, end);
                            wBB = Moves.makeMove(wBB, Cmoves, 'B', start, end);
                            wNB = Moves.makeMove(wNB, Cmoves, 'N', start, end);
                            wPB = Moves.makeMove(wPB, Cmoves, 'P', start, end);

                            break; // breaker ud af for loop da trækket blev fundet og resten af moves er ubetydelig
                        }
                    }
                }

                // Det her er noget rod
                if (!Tools.ArrC(Pmoves, Cmoves))                                                                 // hvis trækket ikke er i Cmoves       continue while loop if invalid move or king check so not blacks turn
                {
                    if (!checkMove(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, Pmoves, "white")) // hvis trækket får kongen i check
                    {
                        kingsafe = false;                                                                        // sæt kingsafe false
                        Console.Write("king is in check");
                        Console.ReadKey();
                        continue;                                   // continue loop så turen ikke går til sort/computer hvis trækket er invalid
                    }
                    Console.Write("move not found in valid moves"); // trækket er invalid
                    Console.ReadKey();
                    continue;                                       // continue loop så turen ikke går til sort/computer hvis trækket er invalid
                }


                /////// BLACK COMPUTER STARTS HERE ///////////////////
                moves = Moves.possibleMovesB(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, EPB, castleWKside, castleWQside, castleBKside, castleBQside); // kalder possibleMovesB som finder alle mulige træk og sætter i strengen moves
                if (!AnyLegalMove(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, moves, "black"))                                                         // hvis computeren ikke har nogen lovlige træk break ud og sæt whitewon true
                {
                    whitewon = true;
                    break;
                }

                Random r = new Random(); // laver random object
                do                       // do while loop der prøver tilfælde træk indtil en der er valid

                {
                    int length      = moves.Length / 4;                                                                                                         // hvor mange moves der er
                    int randomMoveN = r.Next(0, length) * 4;                                                                                                    // tager random tal fra 0 til antal moves og ganger med 4 for at få start index på trækket
                    Cmoves[0] = moves[randomMoveN]; Cmoves[1] = moves[randomMoveN + 1]; Cmoves[2] = moves[randomMoveN + 2]; Cmoves[3] = moves[randomMoveN + 3]; // putter det random move ind i Cmoves arrayet
                }while(!checkMove(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, Cmoves, "black"));                                                // checker trækket


                //
                // det næste er kommenteret når hvid laver et træk
                //

                int startpc = (((Cmoves[0] - '0') * 8) + (Cmoves[1] - '0'));
                int endpc   = (((Cmoves[2] - '0') * 8) + (Cmoves[3] - '0'));

                if ((((UInt64)1 << startpc) & bKB) != 0)
                {
                    castleBKside = false;
                    castleBQside = false;
                }
                if (((((UInt64)1 << startpc) & bRB) & ((UInt64)1 << 7)) != 0)
                {
                    castleBKside = false;
                }
                if (((((UInt64)1 << startpc) & bRB) & (UInt64)1) != 0)
                {
                    castleBQside = false;
                }


                EPB = Moves.makeMoveEP(wPB | bPB, Cmoves, startpc);
                bRB = Moves.CastleMove(bRB, bKB, Cmoves, 'r', startpc);
                bKB = Moves.makeMove(bKB, Cmoves, 'k', startpc, endpc);
                bQB = Moves.makeMove(bQB, Cmoves, 'q', startpc, endpc);
                bRB = Moves.makeMove(bRB, Cmoves, 'r', startpc, endpc);
                bBB = Moves.makeMove(bBB, Cmoves, 'b', startpc, endpc);
                bNB = Moves.makeMove(bNB, Cmoves, 'n', startpc, endpc);
                bPB = Moves.makeMove(bPB, Cmoves, 'p', startpc, endpc);
                wKB = Moves.makeMove(wKB, Cmoves, 'K', startpc, endpc);
                wQB = Moves.makeMove(wQB, Cmoves, 'Q', startpc, endpc);
                wRB = Moves.makeMove(wRB, Cmoves, 'R', startpc, endpc);
                wBB = Moves.makeMove(wBB, Cmoves, 'B', startpc, endpc);
                wNB = Moves.makeMove(wNB, Cmoves, 'N', startpc, endpc);
                wPB = Moves.makeMove(wPB, Cmoves, 'P', startpc, endpc);
            } // while loop slutter her

            if (blackwon) // hvis blackwon er true
            {
                Console.WriteLine("You lost against a stupid computer!");
                Console.Read(true);
            }
            else if (whitewon) // hvis whitewon er true
            {
                Console.WriteLine("You won against a stupid computer!");
                Console.Read(true);
            }
            else if (qgame)  // hvis qgame er true
            {
                Console.WriteLine("The game ended before a winner was found!");
                Console.Read(true);
            }
        } // initiatestdchess metode slutter her
Exemplo n.º 3
0
        static int perftMaxDepth = 4; // set how many ply to search

        public static void perftRoot(ulong bKB, ulong bQB, ulong bRB, ulong bBB, ulong bNB, ulong bPB, ulong wKB, ulong wQB, ulong wRB, ulong wBB, ulong wNB, ulong wPB, ulong EPB, bool castleWKside, bool castleWQside, bool castleBKside, bool castleBQside, bool white2Move, int depth)
        {
            if (depth < perftMaxDepth)
            {
                string moves;
                char[] Cmoves = new char[4]; //create array to send to makeMove method
                if (white2Move)              // get string of all possible moves for white
                {
                    moves = Moves.possibleMovesW(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, EPB, castleWKside, castleWQside, castleBKside, castleBQside);
                }
                else   // get string of all possible moves for black
                {
                    moves = Moves.possibleMovesB(bKB, bQB, bRB, bBB, bNB, bPB, wKB, wQB, wRB, wBB, wNB, wPB, EPB, castleWKside, castleWQside, castleBKside, castleBQside);
                }
                for (int i = 0; i < moves.Length; i += 4) // every move is 4 char so length of movesString / 4 is how many moves possibleMoves method found

                {
                    Cmoves[0] = moves[i]; Cmoves[1] = moves[i + 1]; Cmoves[2] = moves[i + 2]; Cmoves[3] = moves[i + 3]; // put char into array for makeMove method
                    int start = (((Cmoves[0] - '0') * 8) + (Cmoves[1] - '0'));                                          // set start location for each move i counts by 4 to get moves
                    int end   = (((Cmoves[2] - '0') * 8) + (Cmoves[3] - '0'));                                          // get end for every move

                    // send all piece bitboards to makeMove to make a move or get removed if piece is attacked
                    UInt64 bKBt = Moves.makeMove(bKB, Cmoves, 'k', start, end),
                           bQBt = Moves.makeMove(bQB, Cmoves, 'q', start, end),
                           bRBt = Moves.makeMove(bRB, Cmoves, 'r', start, end),
                           bBBt = Moves.makeMove(bBB, Cmoves, 'b', start, end),
                           bNBt = Moves.makeMove(bNB, Cmoves, 'n', start, end),
                           bPBt = Moves.makeMove(bPB, Cmoves, 'p', start, end),
                           wKBt = Moves.makeMove(wKB, Cmoves, 'K', start, end),
                           wQBt = Moves.makeMove(wQB, Cmoves, 'Q', start, end),
                           wRBt = Moves.makeMove(wRB, Cmoves, 'R', start, end),
                           wBBt = Moves.makeMove(wBB, Cmoves, 'B', start, end),
                           wNBt = Moves.makeMove(wNB, Cmoves, 'N', start, end),
                           wPBt = Moves.makeMove(wPB, Cmoves, 'P', start, end),
                           EPBt = Moves.makeMoveEP(wPB | bPB, Cmoves, start); // set the en passant mask EPBt to a file if a pawn moved 2 steps // else set it 0 so only round after double move have valid EP move

                    wRBt = Moves.CastleMove(wRBt, wKB, Cmoves, 'R', start);   // checks if the king made a castle move if true then moves the rook
                    bRBt = Moves.CastleMove(bRBt, bKB, Cmoves, 'r', start);

                    // BoardGeneration.drawArray(bKBt, bQBt, bRBt, bBBt, bNBt, bPBt, wKBt, wQBt, wRBt, wBBt, wNBt, wPBt);
                    // Console.WriteLine();
                    // Console.ReadKey();
                    // Console.Clear();
                    bool castleWKsideT = castleWKside, castleWQsideT = castleWQside, castleBKsideT = castleBKside, castleBQsideT = castleBQside; // set temporary castleflags to the bool send from search before

                    if ((((UInt64)1 << start) & wKB) != 0)                                                                                       // if wking moved set false flags
                    {
                        castleWKsideT = false;
                        castleWQsideT = false;
                    }
                    if ((((UInt64)1 << start) & bKB) != 0)   // if bking moved set false flags
                    {
                        castleBKsideT = false;
                        castleBQsideT = false;
                    }
                    if (((((UInt64)1 << start) & wRB) & ((UInt64)1 << 63)) != 0)   // if wrook kingside moves set kingside flag false
                    {
                        castleWKsideT = false;
                    }
                    if (((((UInt64)1 << start) & wRB) & ((UInt64)1 << 56)) != 0)   // if wrook queenside moves set queenside flag false
                    {
                        castleWQsideT = false;
                    }
                    if (((((UInt64)1 << start) & bRB) & ((UInt64)1 << 7)) != 0)   // if brook kingside moves set king side flag false
                    {
                        castleBKsideT = false;
                    }
                    if (((((UInt64)1 << start) & bRB) & (UInt64)1) != 0)   // if brook queenside moves set queensdie flag false
                    {
                        castleBQsideT = false;
                    }

//                    UInt64 occu = bKBt|bQBt|bRBt|bBBt|bNBt|bPBt|wKBt|wQBt|wRBt|wBBt|wNBt|wPBt;
                    if (((wKBt & Moves.unsafeWhite(bKBt, bQBt, bRBt, bBBt, bNBt, bPBt, wKBt, wQBt, wRBt, wBBt, wNBt, wPBt)) == 0 && white2Move) || // check if white king is in check and its white turn
                        ((bKBt & Moves.unsafeBlack(bKBt, bQBt, bRBt, bBBt, bNBt, bPBt, wKBt, wQBt, wRBt, wBBt, wNBt, wPBt)) == 0 && !white2Move))  // check if black king is in check and its black turn
                    // start next perft search if no checkmate
                    {
                        perft(bKBt, bQBt, bRBt, bBBt, bNBt, bPBt, wKBt, wQBt, wRBt, wBBt, wNBt, wPBt, EPBt, castleWKsideT, castleWQsideT, castleBKsideT, castleBQsideT, !white2Move, depth + 1);
                        //  Console.WriteLine(move2Algebra(moves.Substring(i, 4)) + " " + perftMoveCount);
                        perftTotalCount += perftMoveCount; // count moves that are valid out of the possible moves
                        perftMoveCount   = 0;
                    }
                }
            }
        }