예제 #1
0
 /// <summary>
 /// Some data, like En Passant right, needs resetting before a new move is applied
 /// </summary>
 /// <returns></returns>
 public void ResetHashBeforeMove(ref ulong hash, IrrevState irrevState)
 {
     if (irrevState.EnPassantCapture != 0)
     {
         UpdateEnPassant(ref hash, irrevState.EnPassantCapture);
     }
 }
예제 #2
0
        protected IEnumerable <Move> GenerateCastlingMoves(ulong sq)
        {
            IrrevState irrevState = gameState.GetIrrevState();

            for (int i = 0; i <= 1; i++)
            {
                if (IsCastlingAllowed(irrevState, i))
                {
                    ulong target = castlingKingTarget[i] & BitboardUtils.FIRST_RANK[gameState.Turn];
                    Move  move   = new CastlingMove(gameState, sq, target);
                    yield return(move);
                }
            }
        }
예제 #3
0
        public int GetKingFileScore(int pl, int file, bool rooksConnected, IrrevState irrevState)
        {
            int score = kingFile[file];

            if (score < 0)
            {
                if (!irrevState.CastlingAllowed[pl, 0] && !irrevState.CastlingAllowed[pl, 1])
                {
                    score = (int)(score * 1.5);
                }
            }
            else if (!rooksConnected)
            {
                score = (int)(score * 0.2);
            }
            return(score);
        }
예제 #4
0
        public ulong GenerateHash(GameState gameState)
        {
            ulong hash = 0;

            for (int pl = 0; pl < 2; pl++)
            {
                for (int i = 0; i < 6; i++)
                {
                    int   pInd   = GetPieceIndex(pl, (PieceType)i);
                    ulong pieces = gameState.Pieces[pl, i];
                    while (pieces > 0)
                    {
                        int sqInd = BitboardUtils.PopLSB(ref pieces);
                        hash ^= piecePosBitstring[pInd, sqInd];
                    }
                }
            }

            IrrevState irrevState = gameState.GetIrrevState();

            for (int pl = 0; pl < 2; pl++)
            {
                if (!irrevState.CastlingAllowed[pl, 0])
                {
                    DisableCastling(ref hash, pl, 0);
                }
                if (!irrevState.CastlingAllowed[pl, 1])
                {
                    DisableCastling(ref hash, pl, 1);
                }
            }
            if (irrevState.EnPassantCapture != 0)
            {
                UpdateEnPassant(ref hash, irrevState.EnPassantCapture);
            }
            return(hash);
        }
예제 #5
0
 protected bool IsCastlingAllowed(IrrevState irrevState, int side)
 {
     return(irrevState.CastlingAllowed[gameState.Turn, side] &&
            (castlingEmptySquares[side] & BitboardUtils.FIRST_RANK[gameState.Turn] & gameState.FullOccupancy) == 0);
 }
예제 #6
0
        public void Load(string fen, GameState gameState, bool verifyValidity = false)
        {
            if (verifyValidity && !IsValid(fen))
            {
                throw new ArgumentException("Invalid FEN");
            }
            gameState.Reset();
            IrrevState irrevState = gameState.GetIrrevState();
            ulong      currPos    = 1;

            string[] parts = fen.Split(' ');
            string[] ranks = parts[0].Split('/');
            for (int i = ranks.Length - 1; i >= 0; i--)
            {
                string rank = ranks[i];
                for (int j = 0; j < rank.Length; j++)
                {
                    char c = rank[j];
                    if (char.IsDigit(c))
                    {
                        int shift = (int)char.GetNumericValue(c);
                        currPos = currPos << shift;
                    }
                    else
                    {
                        int pl        = char.IsLower(c) ? 1 : 0;
                        int pieceType = (int)c.ToPieceType();
                        gameState.Pieces[pl, pieceType] |= currPos;
                        gameState.Occupancy[pl]         |= currPos;
                        currPos = currPos << 1;
                    }
                }
            }
            int turn = parts[1] == "w" ? 0 : 1;

            if (gameState.Turn != turn)
            {
                gameState.ChangeTurn();
            }
            if (parts[2].IndexOf('Q') < 0)
            {
                irrevState.CastlingAllowed[0, 0] = false;
            }
            if (parts[2].IndexOf('K') < 0)
            {
                irrevState.CastlingAllowed[0, 1] = false;
            }
            if (parts[2].IndexOf('q') < 0)
            {
                irrevState.CastlingAllowed[1, 0] = false;
            }
            if (parts[2].IndexOf('k') < 0)
            {
                irrevState.CastlingAllowed[1, 1] = false;
            }

            if (parts[3] != "-")
            {
                irrevState.EnPassantCapture = BitboardUtils.GetBitboard(parts[3].StringToPos());
            }
            irrevState.HalfmoveClock = int.Parse(parts[4]);
            irrevState.ZobristHash   = gameState.ZobristHashUtils.GenerateHash(gameState);
        }
예제 #7
0
        public string Convert(GameState gameState)
        {
            StringBuilder builder = new StringBuilder();

            for (int r = 7; r >= 0; r--)
            {
                int emptySq = 0;
                for (int f = 0; f < 8; f++)
                {
                    int    sqInd = r * 8 + f;
                    string piece = GetPieceBySquare(gameState, sqInd);
                    if (piece == null)
                    {
                        emptySq++;
                    }
                    else
                    {
                        if (emptySq > 0)
                        {
                            builder.Append(emptySq);
                            emptySq = 0;
                        }
                        builder.Append(piece);
                    }
                }
                if (emptySq > 0)
                {
                    builder.Append(emptySq);
                }
                if (r > 0)
                {
                    builder.Append('/');
                }
            }
            char turn = gameState.Turn == 0 ? 'w' : 'b';

            builder.Append(" " + turn + " ");
            string     castling   = "";
            IrrevState irrevState = gameState.GetIrrevState();

            if (irrevState.CastlingAllowed[0, 1])
            {
                castling += 'K';
            }
            if (irrevState.CastlingAllowed[0, 0])
            {
                castling += 'Q';
            }
            if (irrevState.CastlingAllowed[1, 1])
            {
                castling += 'k';
            }
            if (irrevState.CastlingAllowed[1, 0])
            {
                castling += 'q';
            }
            if (castling == "")
            {
                castling = "-";
            }
            builder.Append(castling + " ");
            string enPassant = "-";

            if (irrevState.EnPassantCapture != 0)
            {
                enPassant = irrevState.EnPassantCapture.PosToString();
            }
            builder.Append(enPassant + " ");
            builder.Append(irrevState.HalfmoveClock + " ");
            builder.Append(gameState.GetTurnNum());
            return(builder.ToString());
        }
예제 #8
0
 protected void SetIrrevState()
 {
     irrevState = gameState.GetIrrevState();
 }
예제 #9
0
        private IEnumerable <Move> GetRegularMovesFromSquare(ulong sq, GenerationMode generationMode)
        {
            ulong reversedFullOccupancy = ~gameState.FullOccupancy;
            ulong to;
            ulong attacks;

            if (gameState.Turn == 0)
            {
                if (generationMode == GenerationMode.Normal)
                {
                    to = sq << 8 & reversedFullOccupancy;
                    if (to != 0)
                    {
                        yield return(new Move(gameState, sq, to, pieceType));

                        if ((sq & BitboardUtils.SECOND_RANK[gameState.Turn]) > 0)
                        {
                            to = to << 8 & reversedFullOccupancy;
                            if (to != 0)
                            {
                                yield return(new Move(gameState, sq, to, pieceType));
                            }
                        }
                    }
                }
                to      = sq << 7 & BitboardUtils.NOT_H_FILE;
                attacks = to;
                if ((to & gameState.Occupancy[1 - gameState.Turn]) != 0)
                {
                    yield return(new Move(gameState, sq, to, pieceType));
                }
                to       = sq << 9 & BitboardUtils.NOT_A_FILE;
                attacks |= to;
                if ((to & gameState.Occupancy[1 - gameState.Turn]) != 0)
                {
                    yield return(new Move(gameState, sq, to, pieceType));
                }
            }
            else
            {
                if (generationMode == GenerationMode.Normal)
                {
                    to = sq >> 8 & reversedFullOccupancy;
                    if (to != 0)
                    {
                        yield return(new Move(gameState, sq, to, pieceType));

                        if ((sq & BitboardUtils.SECOND_RANK[gameState.Turn]) > 0)
                        {
                            to = to >> 8 & reversedFullOccupancy;
                            if (to != 0)
                            {
                                yield return(new Move(gameState, sq, to, pieceType));
                            }
                        }
                    }
                }
                to      = sq >> 9 & BitboardUtils.NOT_H_FILE;
                attacks = to;
                if ((to & gameState.Occupancy[1 - gameState.Turn]) != 0)
                {
                    yield return(new Move(gameState, sq, to, pieceType));
                }
                to       = sq >> 7 & BitboardUtils.NOT_A_FILE;
                attacks |= to;
                if ((to & gameState.Occupancy[1 - gameState.Turn]) != 0)
                {
                    yield return(new Move(gameState, sq, to, pieceType));
                }
            }

            //En Passant
            IrrevState irrevState = gameState.GetIrrevState();

            if ((irrevState.EnPassantCapture & attacks) > 0)
            {
                yield return(new EnPassantMove(gameState, sq, irrevState.EnPassantCapture));
            }
        }