private static ulong AKnightMoveMap(Board board, bool activePlayer, BoardAddress address)
 {
     if (activePlayer)
     {
         return(MoveMaps.Knight[address.Index] & ~board.ActivePlayer.All);
     }
     else
     {
         return(MoveMaps.Knight[address.Index] & ~board.InactivePlayer.All);
     }
 }
Exemple #2
0
 // get the type of piece at a given board address
 private static PieceMoveType PieceTypeAtAddress(PiecePositions.Player player, BoardAddress address)
 {
     if ((address.Position & player.Pawns) != 0)
     {
         return(PieceMoveType.Pawn);
     }
     else if ((address.Position & player.Knights) != 0)
     {
         return(PieceMoveType.Knight);
     }
     else if ((address.Position & player.Bishops) != 0)
     {
         return(PieceMoveType.Bishop);
     }
     else if ((address.Position & player.Rooks) != 0)
     {
         return(PieceMoveType.Rook);
     }
     else if ((address.Position & player.Queens) != 0)
     {
         return(PieceMoveType.Queen);
     }
     else if ((address.Position & player.King) != 0)
     {
         return(PieceMoveType.King);
     }
     else
     {
         Debug.WriteLine("no piece found at specified position"); return(PieceMoveType.Undefined);
     }
 }
 private static ulong AQueenMoveMap(Board board, bool activePlayer, BoardAddress address)
 {
     return(ARookMoveMap(board, activePlayer, address) | ABishopMoveMap(board, activePlayer, address));
 }
        private static ulong ARookMoveMap(Board board, bool activePlayer, BoardAddress address)
        {
            // get the rook's move bitboard
            ulong Result = MoveMaps.Rook[address.Index];

            // get the file and rank of the rook
            int RookFile = address.File;
            int RookRank = address.Rank;

            // get file and rank masks
            ulong FileMask = Masks.Files[RookFile];
            ulong RankMask = Masks.Ranks[RookRank];

            // get friends and foes in the same rank and file as the rook
            ulong FriendsInFile, FriendsInRank, FoesInFile, FoesInRank;

            if (activePlayer)
            {
                FriendsInFile = Result & board.ActivePlayer.All & FileMask;
                FriendsInRank = Result & board.ActivePlayer.All & RankMask;
                FoesInFile    = Result & board.InactivePlayer.All & FileMask;
                FoesInRank    = Result & board.InactivePlayer.All & RankMask;
            }
            else
            {
                FriendsInFile = Result & board.InactivePlayer.All & FileMask;
                FriendsInRank = Result & board.InactivePlayer.All & RankMask;
                FoesInFile    = Result & board.ActivePlayer.All & FileMask;
                FoesInRank    = Result & board.ActivePlayer.All & RankMask;
            }

            int TempFile, TempRank;

            // step through friends in the same file
            foreach (BoardAddress friend in BoardAddresses(FriendsInFile))
            {
                TempRank = friend.Rank;
                if (TempRank > RookRank) // clear moves at and above this piece
                {
                    Result &= ~Masks.North[TempRank];
                }
                else // clear moves at and below this piece
                {
                    Result &= ~Masks.South[TempRank];
                }
            }

            // step through foes in the same file
            foreach (BoardAddress foe in BoardAddresses(FoesInFile))
            {
                TempRank = foe.Rank;
                if (TempRank > RookRank)   // clear moves above this piece
                {
                    if (TempRank != 7)
                    {
                        Result &= ~Masks.North[TempRank + 1];
                    }
                }
                else     // clear moves below this piece
                {
                    if (TempRank != 0)
                    {
                        Result &= ~Masks.South[TempRank - 1];
                    }
                }
            }

            // step through friends in the same rank
            foreach (BoardAddress friend in BoardAddresses(FriendsInRank))
            {
                TempFile = friend.File;
                if (TempFile > RookFile) // clear moves at and to the right of this piece
                {
                    Result &= ~Masks.East[TempFile];
                }
                else // clear moves at and to the left of this piece
                {
                    Result &= ~Masks.West[TempFile];
                }
            }

            // step through foes in the same rank
            foreach (BoardAddress foe in BoardAddresses(FoesInRank))
            {
                TempFile = foe.File;
                if (TempFile > RookFile)   // clear moves to the right of this piece
                {
                    if (TempFile != 7)
                    {
                        Result &= ~Masks.East[TempFile + 1];
                    }
                }
                else     // clear moves to the left of this piece
                {
                    if (TempFile != 0)
                    {
                        Result &= ~Masks.West[TempFile - 1];
                    }
                }
            }

            return(Result);
        }
        private static ulong ABishopMoveMap(Board board, bool activePlayer, BoardAddress address)
        {
            // get the bishop's move bitboard
            ulong Result = MoveMaps.Bishop[address.Index];

            // get the file and rank of the bishop
            int BishopFile = address.File;
            int BishopRank = address.Rank;

            // get slash and backslash masks
            ulong SlashMask     = Masks.Slash[address.SlashIndex];
            ulong BackslashMask = Masks.BackSlash[address.BackSlashIndex];

            // get friends and foes in same slash and backslash as bishop
            ulong FriendsInSlash, FriendsInBackslash, FoesInSlash, FoesInBackslash;

            if (activePlayer)
            {
                FriendsInSlash     = Result & board.ActivePlayer.All & SlashMask;
                FriendsInBackslash = Result & board.ActivePlayer.All & BackslashMask;
                FoesInSlash        = Result & board.InactivePlayer.All & SlashMask;
                FoesInBackslash    = Result & board.InactivePlayer.All & BackslashMask;
            }
            else
            {
                FriendsInSlash     = Result & board.InactivePlayer.All & SlashMask;
                FriendsInBackslash = Result & board.InactivePlayer.All & BackslashMask;
                FoesInSlash        = Result & board.ActivePlayer.All & SlashMask;
                FoesInBackslash    = Result & board.ActivePlayer.All & BackslashMask;
            }

            int TempFile, TempRank;

            // step through friends in the same slash
            foreach (BoardAddress friend in BoardAddresses(FriendsInSlash))
            {
                TempFile = friend.File;
                if (TempFile > BishopFile) // clear moves at and to the northeast of this piece
                {
                    Result &= ~Masks.NorthEast[friend.BackSlashIndex];
                }
                else // clear moves at and to the southwest of this piece
                {
                    Result &= ~Masks.SouthWest[friend.BackSlashIndex];
                }
            }

            // step through foes in the same slash
            foreach (BoardAddress foe in BoardAddresses(FoesInSlash))
            {
                TempFile = foe.File;
                if (TempFile > BishopFile)   // clear moves to the northeast of this piece
                {
                    if (foe.BackSlashIndex != 9)
                    {
                        Result &= ~Masks.NorthEast[(foe.BackSlashIndex - 1) & 0xF];
                    }
                }
                else     // clear moves to the southwest of this piece
                {
                    if (foe.BackSlashIndex != 7)
                    {
                        Result &= ~Masks.SouthWest[(foe.BackSlashIndex + 1) & 0xF];
                    }
                }
            }

            // step through friends in the same backslash
            foreach (BoardAddress friend in BoardAddresses(FriendsInBackslash))
            {
                TempRank = friend.Rank;
                if (TempRank > BishopRank) // clear moves at and to the northwest of this piece
                {
                    Result &= ~Masks.NorthWest[friend.SlashIndex];
                }
                else // clear moves at and to the southeast of this piece
                {
                    Result &= ~Masks.SouthEast[friend.SlashIndex];
                }
            }

            // step through foes in the same backslash
            foreach (BoardAddress foeInBackslash in BoardAddresses(FoesInBackslash))
            {
                TempRank = foeInBackslash.Rank;
                if (TempRank > BishopRank)   // clear moves to the northwest of this piece
                {
                    if (foeInBackslash.SlashIndex != 7)
                    {
                        Result &= ~Masks.NorthWest[(foeInBackslash.SlashIndex + 1) & 0xF];
                    }
                }
                else     // clear moves to the southeast of this piece
                {
                    if (foeInBackslash.SlashIndex != 9)
                    {
                        Result &= ~Masks.SouthEast[(foeInBackslash.SlashIndex - 1) & 0xF];
                    }
                }
            }

            return(Result);
        }
        // get a map of all of a player's moves for a particular piece
        private static ulong APawnMoveMap(Board board, bool activePlayer, BoardAddress address)
        {
            // get moves and captures
            ulong Moves, Caps;

            if (board.ActiveColorWhite)
            {
                if (activePlayer)
                {
                    Moves = MoveMaps.WhitePawn[address.Index];
                    Caps  = MoveMaps.WhitePawnCapture[address.Index];
                }
                else
                {
                    Moves = MoveMaps.BlackPawn[address.Index];
                    Caps  = MoveMaps.BlackPawnCapture[address.Index];
                }
            }
            else     // black
            {
                if (activePlayer)
                {
                    Moves = MoveMaps.BlackPawn[address.Index];
                    Caps  = MoveMaps.BlackPawnCapture[address.Index];
                }
                else
                {
                    Moves = MoveMaps.WhitePawn[address.Index];
                    Caps  = MoveMaps.WhitePawnCapture[address.Index];
                }
            }

            // is a double move allowed?
            if (Utilities.NumActiveBits(Moves) == 2)   // yes
            // is at least one move unallowed?
            {
                if ((Moves & board.Pieces.All) != 0)   //yes
                // get the single move
                {
                    ulong SingleMove = Moves & ((address.Position << 8) | (address.Position >> 8));

                    // if single move allowed, then it is the only move
                    if ((SingleMove & board.Pieces.All) == 0)
                    {
                        Moves = SingleMove;
                    }
                    else // otherwise no moves are allowed
                    {
                        Moves = 0;
                    }
                } // else no, leave both moves
            }
            else     // no
            // can't move into a another piece
            {
                Moves &= ~board.Pieces.All;
            }

            // can only move to en passant position or into an enemy position
            if (activePlayer)
            {
                Caps &= board.InactivePlayer.All | board.EnPassantTarget;                // only active player can cap en passant
            }
            else
            {
                Caps &= board.ActivePlayer.All;
            }

            return(Moves | Caps);
        }
Exemple #7
0
        // create a board with a FEN string
        public Board(string fen)
        {
            Match Match = FenParser.Match(fen);

            if (!Match.Success)
            {
                throw new ArgumentException(string.Format("invalid FEN string \"{0}\"", fen));
            }

            // piece placement
            string Field = Match.Groups[1].Value;

            string[]     RankPlacement = Field.Split('/');
            BoardAddress Location;
            int          File;

            Pieces = new PiecePositions();
            for (int rank = 0; rank < 8; rank++)
            {
                File = 0;
                foreach (char c in RankPlacement[7 - rank])
                {
                    Location = new BoardAddress((char)('a' + File), rank);

                    switch (c)
                    {
                    case 'p':
                        Pieces.Black.Pawns |= Location.Position;
                        break;

                    case 'P':
                        Pieces.White.Pawns |= Location.Position;
                        break;

                    case 'n':
                        Pieces.Black.Knights |= Location.Position;
                        break;

                    case 'N':
                        Pieces.White.Knights |= Location.Position;
                        break;

                    case 'b':
                        Pieces.Black.Bishops |= Location.Position;
                        break;

                    case 'B':
                        Pieces.White.Bishops |= Location.Position;
                        break;

                    case 'r':
                        Pieces.Black.Rooks |= Location.Position;
                        break;

                    case 'R':
                        Pieces.White.Rooks |= Location.Position;
                        break;

                    case 'q':
                        Pieces.Black.Queens |= Location.Position;
                        break;

                    case 'Q':
                        Pieces.White.Queens |= Location.Position;
                        break;

                    case 'k':
                        Pieces.Black.King |= Location.Position;
                        break;

                    case 'K':
                        Pieces.White.King |= Location.Position;
                        break;

                    default:     // num empty spaces
                        if (!char.IsDigit(c))
                        {
                            throw new ArgumentException(string.Format("invalid character \"{0}\" in piece placement field", c));
                        }
                        File += c - '1';     // convert char to int
                        break;
                    }

                    File++;
                }
            }

            // active color
            Field = Match.Groups[2].Value.ToLower();
            if (Field == "w")
            {
                ActiveColorWhite = true;
            }
            else
            {
                ActiveColorWhite = false;
            }

            // castling availablity
            CastlingAvailability = new Castling();
            Field = Match.Groups[3].Value;
            if (Field == "-")   // not available
            {
                CastlingAvailability.White = Castling.Move.Disallowed;
                CastlingAvailability.Black = Castling.Move.Disallowed;
            }
            else     // available to at least one player
            // check white
            {
                if (Field.Contains("K") && Field.Contains("Q"))
                {
                    CastlingAvailability.White = Castling.Move.BothSides;
                }
                else if (Field.Contains("K"))
                {
                    CastlingAvailability.White = Castling.Move.KingSide;
                }
                else if (Field.Contains("Q"))
                {
                    CastlingAvailability.White = Castling.Move.QueenSide;
                }
                else
                {
                    CastlingAvailability.White = Castling.Move.Disallowed;
                }

                // check black
                if (Field.Contains("k") && Field.Contains("q"))
                {
                    CastlingAvailability.Black = Castling.Move.BothSides;
                }
                else if (Field.Contains("k"))
                {
                    CastlingAvailability.Black = Castling.Move.KingSide;
                }
                else if (Field.Contains("q"))
                {
                    CastlingAvailability.Black = Castling.Move.QueenSide;
                }
                else
                {
                    CastlingAvailability.Black = Castling.Move.Disallowed;
                }
            }

            // enpassant location
            Field = Match.Groups[4].Value;
            if (Field == "-")
            {
                EnPassantTarget = 0;
            }
            else
            {
                EnPassantTarget = new BoardAddress(Field).Position;
            }

            // halfmove clock
            Field = Match.Groups[5].Value;
            if (!byte.TryParse(Field, out HalfMoveClock))
            {
                throw new ArgumentException(string.Format("could not parse halfmove clock \"{0}\"", Field));
            }

            // halfmove clock
            Field = Match.Groups[6].Value;
            if (!int.TryParse(Field, out FullMoveNumber))
            {
                throw new ArgumentException(string.Format("could not parse full move number \"{0}\"", Field));
            }
        }
Exemple #8
0
        // create a move from ACN string and the piece positions
        public Move(string acn, PiecePositions pieces)
        {
            int Len = acn.Length;

            if (Len < 4 || Len > 5)
            {
                throw new ArgumentException(string.Format("ACN strings must be 4 or 5 characters long: \"{0}\"", acn));
            }
            string f = acn.Substring(0, 2);
            string t = acn.Substring(2, 2);

            From = new BoardAddress(f);
            To   = new BoardAddress(t);

            // determine the type of piece that is moving
            if ((pieces.Pawns & From.Position) != 0)
            {
                MoveType = PieceMoveType.Pawn;
            }
            else if ((pieces.Knights & From.Position) != 0)
            {
                MoveType = PieceMoveType.Knight;
            }
            else if ((pieces.Bishops & From.Position) != 0)
            {
                MoveType = PieceMoveType.Bishop;
            }
            else if ((pieces.Rooks & From.Position) != 0)
            {
                MoveType = PieceMoveType.Rook;
            }
            else if ((pieces.Queens & From.Position) != 0)
            {
                MoveType = PieceMoveType.Queen;
            }
            else if ((pieces.Kings & From.Position) != 0)
            {
                MoveType = PieceMoveType.King;
            }
            else
            {
                throw new ArgumentException(string.Format("move \"{0}\" invalid given current piece positions", acn));
            }

            // promotion on this move?
            if (Len == 5)   // yes
            {
                if (MoveType != PieceMoveType.Pawn)
                {
                    throw new ArgumentException("tried to promote from a piece type other than pawn");
                }
                char promo = char.ToLower(acn[4]);
                switch (promo)
                {
                case 'n':
                    MoveType = PieceMoveType.PawnKnight;
                    break;

                case 'b':
                    MoveType = PieceMoveType.PawnBishop;
                    break;

                case 'r':
                    MoveType = PieceMoveType.PawnRook;
                    break;

                case 'q':
                    MoveType = PieceMoveType.PawnQueen;
                    break;

                default:
                    throw new ArgumentException(string.Format("ACN string contains invalid promotion character \"{0}\"", promo));
                }
            }
        }
Exemple #9
0
 public Move(ulong f, ulong t, PieceMoveType m)
 {
     From     = new BoardAddress(f);
     To       = new BoardAddress(t);
     MoveType = m;
 }
Exemple #10
0
 public Move(BoardAddress f, BoardAddress t, PieceMoveType m)
 {
     From     = f;
     To       = t;
     MoveType = m;
 }