Exemple #1
0
    /// <summary>
    /// Construct board based on FEN.
    /// </summary>
    public Board(string Fen)
    {
        pieces  = new int[64]; //Every square for every piece
        PvArray = new int[Defs.MaxDepth];

        History = new HMove[2056];
        for (int i = 0; i < History.Length; i++)
        {
            History[i] = new HMove();
        }

        InitPVTable();
        SearchHistory = new int[14][];
        SearchKillers = new int[2][];
        for (int i = 0; i < 14; i++)
        {
            SearchHistory[i] = new int[64];
        }

        SearchKillers[0] = new int[Defs.MaxDepth];
        SearchKillers[1] = new int[Defs.MaxDepth];

        //Init board from FEN
        this.BoardFromFen(Fen);

        //Get hash key
        Position = Zobrist.GetHashPosition(this);

        UpdateOccupancy();
    }
Exemple #2
0
    /// <summary>
    /// Makes a move.
    /// </summary>
    public void MakeMove(int move)
    {
        HMove hisMove = History[ply];

        hisMove.castle    = CastlePermission;
        hisMove.ep        = (int)EnPassantSq;
        hisMove.move      = move;
        hisMove.pos       = Position;
        hisMove.fiftyMove = FiftyMove;

        //Move was made no more en passant square
        EnPassantSq = Squares.None;

        //increase it, but it may reset
        FiftyMove++;

        int From      = move & 0x3f;
        int To        = (move >> 6) & 0x3f;
        int movePiece = (move >> 12) & 0xf;

        //Removes the current castle permission from hash key since that might change during the move making
        Position ^= Zobrist.CastleRights[CastlePermission];

        switch (movePiece)
        {
            #region WHITE
        case Defs.WPawn:
            //Moved to the desired position
            WPawn ^= Ops.Pow2[From];
            WPawn |= Ops.Pow2[To];

            //Zobrist
            Position ^= Zobrist.Pieces[From][Defs.WPawn];
            Position ^= Zobrist.Pieces[To][Defs.WPawn];

            //Reset fifty move
            FiftyMove = 0;

            pieces[From] = 0;
            pieces[To]   = Defs.WPawn;

            if ((move & 0x700000) == 0x100000) // En passan capture
            {
                //Remove pawn
                BPawn         ^= Ops.Pow2[To + 8];
                pieces[To + 8] = 0;

                //Removes only
                Position ^= Zobrist.Pieces[To + 8][Defs.BPawn];
            }
            else if (From - To == 16)             //Double pawn move
            {
                EnPassantSq = (Squares)(To + 8);
            }
            else if ((move & 0x700000) > 0x200000) //Move is promotion
            {
                #region promo
                switch ((move >> 20) & 0xf)
                {
                case Defs.PromoQueen:
                    WQueen    ^= Ops.Pow2[To];
                    WPawn     ^= Ops.Pow2[To];
                    pieces[To] = Defs.WQueen;
                    Position  ^= Zobrist.Pieces[To][Defs.WPawn];
                    Position  ^= Zobrist.Pieces[To][Defs.WQueen];
                    break;

                case Defs.PromoBishop:
                    WBishop   ^= Ops.Pow2[To];
                    WPawn     ^= Ops.Pow2[To];
                    pieces[To] = Defs.WBishop;
                    Position  ^= Zobrist.Pieces[To][Defs.WPawn];
                    Position  ^= Zobrist.Pieces[To][Defs.WBishop];
                    break;

                case Defs.PromoKnight:
                    WKnight   ^= Ops.Pow2[To];
                    WPawn     ^= Ops.Pow2[To];
                    pieces[To] = Defs.WKnight;
                    Position  ^= Zobrist.Pieces[To][Defs.WPawn];
                    Position  ^= Zobrist.Pieces[To][Defs.WKnight];
                    break;

                case Defs.PromoRook:
                    WRook     ^= Ops.Pow2[To];
                    WPawn     ^= Ops.Pow2[To];
                    pieces[To] = Defs.WRook;
                    Position  ^= Zobrist.Pieces[To][Defs.WPawn];
                    Position  ^= Zobrist.Pieces[To][Defs.WRook];
                    break;
                }
                #endregion
            }


            break;

        case Defs.WBishop:
            WBishop ^= Ops.Pow2[From];
            WBishop |= Ops.Pow2[To];

            Position ^= Zobrist.Pieces[From][Defs.WBishop];
            Position ^= Zobrist.Pieces[To][Defs.WBishop];

            pieces[From] = 0;
            pieces[To]   = Defs.WBishop;

            break;

        case Defs.WKnight:
            WKnight ^= Ops.Pow2[From];
            WKnight |= Ops.Pow2[To];

            Position ^= Zobrist.Pieces[From][Defs.WKnight];
            Position ^= Zobrist.Pieces[To][Defs.WKnight];

            pieces[From] = 0;
            pieces[To]   = Defs.WKnight;

            break;

        case Defs.WRook:
            WRook ^= Ops.Pow2[From];
            WRook |= Ops.Pow2[To];

            Position ^= Zobrist.Pieces[From][Defs.WRook];
            Position ^= Zobrist.Pieces[To][Defs.WRook];

            pieces[From] = 0;
            pieces[To]   = Defs.WRook;

            if (From == 56)
            {
                CastlePermission &= ~Defs.CastleRightsQWCa;
            }
            else if (From == 63)
            {
                CastlePermission &= ~Defs.CastleRightsKWCa;
            }

            break;

        case Defs.WQueen:
            WQueen ^= Ops.Pow2[From];
            WQueen |= Ops.Pow2[To];

            Position ^= Zobrist.Pieces[From][Defs.WQueen];
            Position ^= Zobrist.Pieces[To][Defs.WQueen];

            pieces[From] = 0;
            pieces[To]   = Defs.WQueen;

            break;

        case Defs.WKing:
            WKing ^= Ops.Pow2[From];
            WKing |= Ops.Pow2[To];

            Position ^= Zobrist.Pieces[From][Defs.WKing];
            Position ^= Zobrist.Pieces[To][Defs.WKing];


            pieces[From] = 0;
            pieces[To]   = Defs.WKing;


            if ((move & 0x700000) == 0x200000)
            {
                if (To == 58)
                {
                    WRook     ^= Ops.Pow2[56];
                    WRook     ^= Ops.Pow2[59];
                    pieces[56] = 0;
                    pieces[59] = Defs.WRook;
                    Position  ^= Zobrist.Pieces[56][Defs.WRook];
                    Position  ^= Zobrist.Pieces[59][Defs.WRook];
                }
                else if (To == 62)
                {
                    WRook     ^= Ops.Pow2[61];
                    WRook     ^= Ops.Pow2[63];
                    pieces[63] = 0;
                    pieces[61] = Defs.WRook;
                    Position  ^= Zobrist.Pieces[61][Defs.WRook];
                    Position  ^= Zobrist.Pieces[63][Defs.WRook];
                }
            }

            CastlePermission &= ~(Defs.CastleRightsKWCa | Defs.CastleRightsQWCa);

            break;
            #endregion

            #region BLACK
        case Defs.BPawn:
            //Moved to the desired position
            BPawn ^= Ops.Pow2[From];
            BPawn |= Ops.Pow2[To];

            Position ^= Zobrist.Pieces[From][Defs.BPawn];
            Position ^= Zobrist.Pieces[To][Defs.BPawn];

            //Reset fifty move
            FiftyMove = 0;

            pieces[From] = 0;
            pieces[To]   = Defs.BPawn;

            if ((move & 0x700000) == 0x100000)
            {
                //Remove pawn
                WPawn         ^= Ops.Pow2[To - 8];
                pieces[To - 8] = 0;

                //Removes only
                Position ^= Zobrist.Pieces[To + 8][Defs.BPawn];
            }
            else if (From - To == -16)
            {
                EnPassantSq = (Squares)(To - 8);
            }
            else if ((move & 0x700000) > 0x200000)
            #region promo
            {
                switch ((move >> 20) & 0xf)
                {
                case Defs.PromoQueen:
                    BQueen    ^= Ops.Pow2[To];
                    BPawn     ^= Ops.Pow2[To];
                    pieces[To] = Defs.BQueen;
                    Position  ^= Zobrist.Pieces[To][Defs.BPawn];
                    Position  ^= Zobrist.Pieces[To][Defs.BQueen];

                    break;

                case Defs.PromoBishop:
                    BBishop   ^= Ops.Pow2[To];
                    BPawn     ^= Ops.Pow2[To];
                    pieces[To] = Defs.BBishop;
                    Position  ^= Zobrist.Pieces[To][Defs.BPawn];
                    Position  ^= Zobrist.Pieces[To][Defs.BBishop];

                    break;

                case Defs.PromoKnight:
                    BKnight   ^= Ops.Pow2[To];
                    BPawn     ^= Ops.Pow2[To];
                    pieces[To] = Defs.BKnight;
                    Position  ^= Zobrist.Pieces[To][Defs.BPawn];
                    Position  ^= Zobrist.Pieces[To][Defs.BKnight];

                    break;

                case Defs.PromoRook:
                    BRook     ^= Ops.Pow2[To];
                    BPawn     ^= Ops.Pow2[To];
                    pieces[To] = Defs.BRook;
                    Position  ^= Zobrist.Pieces[To][Defs.BPawn];
                    Position  ^= Zobrist.Pieces[To][Defs.BRook];

                    break;
                }
            }
            #endregion


            break;

        case Defs.BBishop:
            BBishop ^= Ops.Pow2[From];
            BBishop |= Ops.Pow2[To];

            pieces[From] = 0;
            pieces[To]   = Defs.BBishop;

            Position ^= Zobrist.Pieces[From][Defs.BBishop];
            Position ^= Zobrist.Pieces[To][Defs.BBishop];


            break;

        case Defs.BKnight:
            BKnight ^= Ops.Pow2[From];
            BKnight ^= Ops.Pow2[To];

            pieces[From] = 0;
            pieces[To]   = Defs.BKnight;

            Position ^= Zobrist.Pieces[From][Defs.BKnight];
            Position ^= Zobrist.Pieces[To][Defs.BKnight];


            break;

        case Defs.BRook:
            BRook ^= Ops.Pow2[From];
            BRook |= Ops.Pow2[To];

            pieces[From] = 0;
            pieces[To]   = Defs.BRook;

            Position ^= Zobrist.Pieces[From][Defs.BRook];
            Position ^= Zobrist.Pieces[To][Defs.BRook];


            if (From == 0)
            {
                CastlePermission &= ~Defs.CastleRightsQBCa;
            }
            else if (From == 7)
            {
                CastlePermission &= ~Defs.CastleRightsKBCa;
            }

            break;

        case Defs.BQueen:
            BQueen ^= Ops.Pow2[From];
            BQueen |= Ops.Pow2[To];

            pieces[From] = 0;
            pieces[To]   = Defs.BQueen;

            Position ^= Zobrist.Pieces[From][Defs.BQueen];
            Position ^= Zobrist.Pieces[To][Defs.BQueen];


            break;

        case Defs.BKing:
            BKing ^= Ops.Pow2[From];
            BKing |= Ops.Pow2[To];

            pieces[From] = 0;
            pieces[To]   = Defs.BKing;

            Position ^= Zobrist.Pieces[From][Defs.BKing];
            Position ^= Zobrist.Pieces[To][Defs.BKing];


            if ((move & 0x700000) == 0x200000)
            {
                if (To == 2)
                {
                    BRook    ^= Ops.Pow2[3];
                    BRook    ^= Ops.Pow2[0];
                    pieces[0] = 0;
                    pieces[3] = Defs.BRook;

                    Position ^= Zobrist.Pieces[0][Defs.BRook];
                    Position ^= Zobrist.Pieces[3][Defs.BRook];
                }
                else if (To == 6)
                {
                    BRook    ^= Ops.Pow2[5];
                    BRook    ^= Ops.Pow2[7];
                    pieces[7] = 0;
                    pieces[5] = Defs.BRook;
                    Position ^= Zobrist.Pieces[5][Defs.BRook];
                    Position ^= Zobrist.Pieces[7][Defs.BRook];
                }
            }
            CastlePermission &= ~(Defs.CastleRightsKBCa | Defs.CastleRightsQBCa);

            break;
            #endregion
        }

        if ((move & 0xf0000) != 0) //Move was capture
        {
            #region capture
            switch ((move >> 16) & 0xf)
            {
                #region white
            case Defs.WPawn:
                WPawn    ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.WPawn];
                break;

            case Defs.WKnight:
                WKnight  ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.WKnight];
                break;

            case Defs.WBishop:
                WBishop  ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.WKnight];
                break;

            case Defs.WRook:
                WRook    ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.WRook];

                if (To == 56)
                {
                    CastlePermission &= ~Defs.CastleRightsQWCa;
                }
                else if (To == 63)
                {
                    CastlePermission &= ~Defs.CastleRightsKWCa;
                }

                break;

            case Defs.WQueen:
                WQueen   ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.WQueen];

                break;

                #endregion
                #region black
            case Defs.BPawn:
                BPawn    ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.BPawn];

                break;

            case Defs.BKnight:
                BKnight  ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.BKnight];

                break;

            case Defs.BBishop:
                BBishop  ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.BBishop];

                break;

            case Defs.BRook:
                BRook    ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.BRook];

                if (To == 0)
                {
                    CastlePermission &= ~Defs.CastleRightsQBCa;
                }
                else if (To == 7)
                {
                    CastlePermission &= ~Defs.CastleRightsKBCa;
                }
                break;

            case Defs.BQueen:
                BQueen   ^= Ops.Pow2[To];
                Position ^= Zobrist.Pieces[To][Defs.BQueen];

                break;
                #endregion
            }
            #endregion

            //Reset fifty move
            FiftyMove = 0;
        }

        //Castle permission
        Position ^= Zobrist.CastleRights[CastlePermission];

        Position ^= Zobrist.CastleRights[SideToPlay];

        //Side to play
        SideToPlay = 1 - SideToPlay;

        Position ^= Zobrist.CastleRights[SideToPlay];

        //Updates occupancy
        BOcc = BPawn | BBishop | BKnight | BRook | BQueen | BKing;
        WOcc = WPawn | WBishop | WKnight | WRook | WQueen | WKing;

        History[ply] = hisMove;
        ply++;
    }
Exemple #3
0
    public void UndoMove()
    {
        if (ply == 0)        //No moves to undo
        {
            return;
        }

        ply--;

        HMove hisMove = History[ply];
        int   move    = hisMove.move;

        int From      = move & 0x3f;
        int To        = (move >> 6) & 0x3f;
        int movePiece = (move >> 12) & 0xf;

        switch (movePiece)
        {
            #region WHITE
        case Defs.WPawn:

            if ((move & 0x700000) > 0x200000)
            {
                #region promo
                switch ((move >> 20) & 0xf)
                {
                case Defs.PromoQueen:
                    WQueen ^= Ops.Pow2[To];
                    break;

                case Defs.PromoBishop:
                    WBishop ^= Ops.Pow2[To];
                    break;

                case Defs.PromoKnight:
                    WKnight ^= Ops.Pow2[To];
                    break;

                case Defs.PromoRook:
                    WRook ^= Ops.Pow2[To];
                    break;
                }
                #endregion
            }
            else
            {
                WPawn ^= Ops.Pow2[To];
            }

            //Moved to the desired position
            WPawn ^= Ops.Pow2[From];

            pieces[To]   = 0;
            pieces[From] = Defs.WPawn;

            if (move.IsEnPassantCapt())
            {
                BPawn         ^= Ops.Pow2[To + 8];
                pieces[To + 8] = Defs.BPawn;
            }


            break;

        case Defs.WBishop:
            WBishop ^= Ops.Pow2[From];
            WBishop ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.WBishop;

            break;

        case Defs.WKnight:
            WKnight ^= Ops.Pow2[From];
            WKnight ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.WKnight;

            break;

        case Defs.WRook:
            WRook ^= Ops.Pow2[From];
            WRook ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.WRook;

            break;

        case Defs.WQueen:
            WQueen ^= Ops.Pow2[From];
            WQueen ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.WQueen;

            break;

        case Defs.WKing:
            WKing ^= Ops.Pow2[From];
            WKing ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.WKing;


            if ((move & 0x700000) == 0x200000)
            {
                if (To == 58)
                {
                    WRook     ^= Ops.Pow2[56];
                    WRook     ^= Ops.Pow2[59];
                    pieces[56] = Defs.WRook;
                    pieces[59] = Defs.Empty;
                }
                else if (To == 62)
                {
                    WRook     ^= Ops.Pow2[61];
                    WRook     ^= Ops.Pow2[63];
                    pieces[63] = Defs.WRook;
                    pieces[61] = Defs.Empty;
                }
            }
            break;
            #endregion

            #region BLACK
        case Defs.BPawn:

            if ((move & 0x700000) > 0x200000)
            {
                #region promo
                switch ((move >> 20) & 0xf)
                {
                case Defs.PromoQueen:
                    BQueen ^= Ops.Pow2[To];
                    break;

                case Defs.PromoBishop:
                    BBishop ^= Ops.Pow2[To];
                    break;

                case Defs.PromoKnight:
                    BKnight ^= Ops.Pow2[To];
                    break;

                case Defs.PromoRook:
                    BRook ^= Ops.Pow2[To];
                    break;
                }
                #endregion
            }
            else
            {
                BPawn ^= Ops.Pow2[To];
            }


            //Moved to the desired position
            BPawn ^= Ops.Pow2[From];

            pieces[To]   = 0;
            pieces[From] = Defs.BPawn;

            if (move.IsEnPassantCapt())
            {
                WPawn         ^= Ops.Pow2[To - 8];
                pieces[To - 8] = Defs.WPawn;
            }


            break;

        case Defs.BBishop:
            BBishop ^= Ops.Pow2[From];
            BBishop ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.BBishop;

            break;

        case Defs.BKnight:
            BKnight ^= Ops.Pow2[From];
            BKnight ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.BKnight;

            break;

        case Defs.BRook:
            BRook ^= Ops.Pow2[From];
            BRook ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.BRook;

            break;

        case Defs.BQueen:
            BQueen ^= Ops.Pow2[From];
            BQueen ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.BQueen;

            break;

        case Defs.BKing:
            BKing ^= Ops.Pow2[From];
            BKing ^= Ops.Pow2[To];

            pieces[To]   = 0;
            pieces[From] = Defs.BKing;


            if ((move & 0x700000) == 0x200000)
            {
                if (To == 2)
                {
                    BRook    ^= Ops.Pow2[3];
                    BRook    ^= Ops.Pow2[0];
                    pieces[0] = Defs.BRook;
                    pieces[3] = Defs.Empty;
                }
                else if (To == 6)
                {
                    BRook    ^= Ops.Pow2[5];
                    BRook    ^= Ops.Pow2[7];
                    pieces[7] = Defs.BRook;
                    pieces[5] = Defs.Empty;
                }
            }



            break;
            #endregion
        }

        if ((move & 0xf0000) != 0)
        {
            #region capture
            switch ((move >> 16) & 0xf)
            {
                #region white
            case Defs.WPawn:
                WPawn     ^= Ops.Pow2[To];
                pieces[To] = Defs.WPawn;
                break;

            case Defs.WKnight:
                WKnight   ^= Ops.Pow2[To];
                pieces[To] = Defs.WKnight;
                break;

            case Defs.WBishop:
                WBishop   ^= Ops.Pow2[To];
                pieces[To] = Defs.WBishop;
                break;

            case Defs.WRook:
                WRook     ^= Ops.Pow2[To];
                pieces[To] = Defs.WRook;
                break;

            case Defs.WQueen:
                WQueen    ^= Ops.Pow2[To];
                pieces[To] = Defs.WQueen;
                break;

                #endregion
                #region black
            case Defs.BPawn:
                BPawn     ^= Ops.Pow2[To];
                pieces[To] = Defs.BPawn;
                break;

            case Defs.BKnight:
                BKnight   ^= Ops.Pow2[To];
                pieces[To] = Defs.BKnight;
                break;

            case Defs.BBishop:
                BBishop   ^= Ops.Pow2[To];
                pieces[To] = Defs.BBishop;
                break;

            case Defs.BRook:
                BRook     ^= Ops.Pow2[To];
                pieces[To] = Defs.BRook;
                break;

            case Defs.BQueen:
                BQueen    ^= Ops.Pow2[To];
                pieces[To] = Defs.BQueen;
                break;
                #endregion
            }
            #endregion
        }


        //Updates occupancy
        BOcc = BPawn | BBishop | BKnight | BRook | BQueen | BKing;
        WOcc = WPawn | WBishop | WKnight | WRook | WQueen | WKing;

        CastlePermission = hisMove.castle;
        EnPassantSq      = (Squares)hisMove.ep;
        Position         = hisMove.pos;
        FiftyMove        = hisMove.fiftyMove;

        SideToPlay = 1 - SideToPlay;
    }
Exemple #4
0
 public Move(HMove h, VMove v)
 {
     H = h;
     V = v;
 }