コード例 #1
0
ファイル: Moves.cs プロジェクト: adh2050/Chess
        private static void GetBishopMoves(Board board, int square, int[] moves, ref int count)
        {
            int   x      = Board.X(square);
            int   y      = Board.Y(square);
            Color color  = board.GetColor(square);
            int   target = 0;

            // Move up right
            target = square + 9;
            while (target < 64 && Board.X(target) > x && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
                if (board.State[target] != 0)                 // enemy piece
                {
                    break;
                }
                target += 9;
            }

            // Move up left
            target = square + 7;
            while (target < 64 && Board.X(target) < x && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
                if (board.State[target] != 0)                 // enemy piece
                {
                    break;
                }
                target += 7;
            }

            // Move down right
            target = square - 7;
            while (target >= 0 && Board.X(target) > x && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
                if (board.State[target] != 0)                 // enemy piece
                {
                    break;
                }
                target -= 7;
            }

            // Move down left
            target = square - 9;
            while (target >= 0 && Board.X(target) < x && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
                if (board.State[target] != 0)                 // enemy piece
                {
                    break;
                }
                target -= 9;
            }
        }
コード例 #2
0
ファイル: Moves.cs プロジェクト: adh2050/Chess
        private static void GetRookMoves(Board board, int square, int[] moves, ref int count)
        {
            Color color  = board.GetColor(square);
            int   target = 0;

            // Move up
            target = square + 8;
            while (target < 64 && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
                if (board.State[target] != 0)                 // enemy piece
                {
                    break;
                }
                target += 8;
            }

            // Move down
            target = square - 8;
            while (target >= 0 && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
                if (board.State[target] != 0)                 // enemy piece
                {
                    break;
                }
                target -= 8;
            }

            // Move right
            target = square + 1;
            while (Board.X(target) > Board.X(square) && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
                if (board.State[target] != 0)                 // enemy piece
                {
                    break;
                }
                target++;
            }

            // Move left
            target = square - 1;
            while (Board.X(target) < Board.X(square) && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
                if (board.State[target] != 0)                 // enemy piece
                {
                    break;
                }
                target--;
            }
        }
コード例 #3
0
ファイル: Zobrist.cs プロジェクト: adh2050/Chess
        public static ulong Calculate(Board board)
        {
            ulong hash = 0;

            for (int i = 0; i < 64; i++)
            {
                var color = board.GetColor(i);
                if (color == Color.None)
                {
                    continue;
                }

                var piece = board.GetPiece(i);

                hash = hash ^ Keys[Index[Colors.Val(color, piece)], i];
            }

            int castling = board.CastlingRights.Select(x => (int)x).Aggregate((total, x) => total | x);

            hash = hash ^ Keys[IndexPlayerTurn, (int)board.PlayerTurn];
            hash = hash ^ Keys[IndexCastling, castling];
            hash = hash ^ Keys[IndexEnPassant, board.EnPassantTile];

            return(hash);
        }
コード例 #4
0
ファイル: Board.cs プロジェクト: adh2050/Chess
        /// <summary>
        /// Evaluates how many pieces can attack each tile.
        /// Returns an array of 64 ints, each number represents the number of attackers
        /// for that square
        /// </summary>
        /// <param name="board"></param>
        /// <param name="attackerColor"></param>
        /// <returns></returns>
        public int[] GetAttackBoard(Color attackerColor)
        {
            Board board = this;

            Color color       = attackerColor;
            var   attackBoard = new int[64];

            // Search for all pieces of the attacker's color
            for (int i = 0; i < 64; i++)
            {
                if (board.GetColor(i) != color)
                {
                    continue;
                }

                // find all the moves this piece can make
                var moves = Attacks.GetAttacks(board, i);

                // mark them on the attack board
                foreach (int move in moves)
                {
                    attackBoard[move]++;
                }
            }

            return(attackBoard);
        }
コード例 #5
0
ファイル: Board.cs プロジェクト: adh2050/Chess
        /// <summary>
        /// Figures out if the specified move puts or keeps your own king in check, which is illegal
        /// </summary>
        /// <param name="board"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        public bool MoveSelfChecks(int from, int to)
        {
            Board board       = this;
            Color colorToMove = board.GetColor(from);

            board = board.Copy();
            board.Move(from, to, false);
            bool ok = board.IsChecked(colorToMove);

            return(ok);
        }
コード例 #6
0
ファイル: Moves.cs プロジェクト: adh2050/Chess
        /// <summary>
        /// Returns the tile of the pawn that is killed in an en passant capture
        /// </summary>
        /// <param name="board"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        public static int EnPassantVictim(Board board, int from, int to)
        {
            var color = board.GetColor(from);

            if (color == Color.White)
            {
                return(to - 8);
            }

            if (color == Color.Black)
            {
                return(to + 8);
            }

            throw new Exception("Unrecognized color");
        }
コード例 #7
0
ファイル: Moves.cs プロジェクト: adh2050/Chess
        /// <summary>
        /// Returns all moves, valid or not, for the current player
        /// </summary>
        /// <param name="board"></param>
        /// <returns></returns>
        public static Move[] GetMoves(Board board)
        {
            var moves  = new List <Move>();
            var player = board.PlayerTurn;

            for (int i = 0; i < 64; i++)
            {
                if (board.GetColor(i) != player)
                {
                    continue;
                }

                Piece piece = board.GetPiece(i);

                var dest = GetMoves(board, i);
                for (int j = 0; j < dest.Length; j++)
                {
                    var move = new Move();
                    move.From = i;
                    move.To   = dest[j];
                    moves.Add(move);

                    if (CanPromote(move.To, player, piece))
                    {
                        var move2 = move.Copy();
                        var move3 = move.Copy();
                        var move4 = move.Copy();

                        move.Promotion  = Piece.Knight;
                        move2.Promotion = Piece.Bishop;
                        move3.Promotion = Piece.Rook;
                        move4.Promotion = Piece.Queen;

                        moves.Add(move2);
                        moves.Add(move3);
                        moves.Add(move4);
                    }
                }
            }

            return(moves.ToArray());
        }
コード例 #8
0
ファイル: Moves.cs プロジェクト: adh2050/Chess
        /// <summary>
        /// Checks if the move is pawn moving 2 tiles, and returns the tile at which it can be captured
        /// (between from and to). Returns 0 if the piece can not be captured in an en passant move
        /// </summary>
        /// <param name="board"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        public static int EnPassantTile(Board board, int from, int to)
        {
            var color = board.GetColor(from);
            var piece = board.GetPiece(from);
            var y     = Board.Y(from);

            if (piece != Piece.Pawn)
            {
                return(0);
            }

            if (color == Color.White && y == 1 && to == (from + 16))
            {
                return(from + 8);
            }

            if (color == Color.Black && y == 6 && to == (from - 16))
            {
                return(from - 8);
            }

            return(0);
        }
コード例 #9
0
ファイル: Board.cs プロジェクト: adh2050/Chess
        /// <summary>
        /// Checks if a piece on the board can be promoted
        /// </summary>
        /// <param name="square"></param>
        /// <param name="pieceType"></param>
        /// <returns></returns>
        public bool CanPromote(int square)
        {
            Board board = this;

            // Can only promote pawns
            if (board.GetPiece(square) != Piece.Pawn)
            {
                return(false);
            }

            Color color = board.GetColor(square);

            if (Board.Y(square) == 7 && color == Color.White)
            {
                return(true);
            }

            if (Board.Y(square) == 0 && color == Color.Black)
            {
                return(true);
            }

            return(false);
        }
コード例 #10
0
ファイル: Moves.cs プロジェクト: adh2050/Chess
        private static void GetKingMoves(Board board, int square, int[] moves, ref int count)
        {
            int   x      = Board.X(square);
            int   y      = Board.Y(square);
            Color color  = board.GetColor(square);
            int   target = 0;

            if (y < 7)
            {
                target = square + 7;
                if (x > 0 && board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }

                target = square + 8;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }

                target = square + 9;
                if (x < 7 && board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }

            target = square - 1;
            if (x > 0 && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
            }

            target = square + 1;
            if (x < 7 && board.GetColor(target) != color)
            {
                moves[count] = target;
                count++;
            }

            if (y > 0)
            {
                target = square - 9;
                if (x > 0 && board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }

                target = square - 8;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }

                target = square - 7;
                if (x < 7 && board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }

            // castling
            // no quares between rook and king can be occupied, the king cannot pass through any checked attacked squares
            if (color == Color.White && square == 4)
            {
                if (board.CanCastleKWhite && board.State[5] == 0 && board.State[6] == 0)
                {
                    var attacks = board.GetAttackBoard(Color.Black);
                    if (attacks[4] == 0 && attacks[5] == 0 && attacks[6] == 0)
                    {
                        moves[count] = 6;
                        count++;
                    }
                }
                if (board.CanCastleQWhite && board.State[3] == 0 && board.State[2] == 0 && board.State[1] == 0)
                {
                    var attacks = board.GetAttackBoard(Color.Black);
                    if (attacks[2] == 0 && attacks[3] == 0 && attacks[4] == 0)
                    {
                        moves[count] = 2;
                        count++;
                    }
                }
            }
            else if (color == Color.Black && square == 60)
            {
                if (board.CanCastleKBlack && board.State[61] == 0 && board.State[62] == 0)
                {
                    var attacks = board.GetAttackBoard(Color.White);
                    if (attacks[60] == 0 && attacks[61] == 0 && attacks[62] == 0)
                    {
                        moves[count] = 62;
                        count++;
                    }
                }
                if (board.CanCastleQBlack && board.State[59] == 0 && board.State[58] == 0 && board.State[57] == 0)
                {
                    var attacks = board.GetAttackBoard(Color.White);
                    if (attacks[58] == 0 && attacks[59] == 0 && attacks[60] == 0)
                    {
                        moves[count] = 58;
                        count++;
                    }
                }
            }
        }
コード例 #11
0
ファイル: Moves.cs プロジェクト: adh2050/Chess
        private static void GetKnightMoves(Board board, int square, int[] moves, ref int count)
        {
            // -x-x-  -0-1-
            // x---x  2---3
            // --O--  --O--
            // x---x  4---5
            // -x-x-  -6-7-

            int target = 0;

            int   x     = Board.X(square);
            int   y     = Board.Y(square);
            Color color = board.GetColor(square);

            // 0
            if (x > 0 && y < 6)
            {
                target = square + 15;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }
            // 1
            if (x < 7 && y < 6)
            {
                target = square + 17;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }

            // 2
            if (x > 1 && y < 7)
            {
                target = square + 6;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }
            // 3
            if (x < 6 && y < 7)
            {
                target = square + 10;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }

            // -x-x-  -0-1-
            // x---x  2---3
            // --O--  --O--
            // x---x  4---5
            // -x-x-  -6-7-

            // 4
            if (x > 1 && y > 0)
            {
                target = square - 10;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }
            // 5
            if (x < 6 && y > 0)
            {
                target = square - 6;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }

            // 6
            if (x > 0 && y > 1)
            {
                target = square - 17;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }
            // 7
            if (x < 7 && y > 1)
            {
                target = square - 15;
                if (board.GetColor(target) != color)
                {
                    moves[count] = target;
                    count++;
                }
            }
        }
コード例 #12
0
ファイル: Moves.cs プロジェクト: adh2050/Chess
        private static void GetPawnMoves(Board board, int square, int[] moves, ref int count)
        {
            int   x     = Board.X(square);
            int   y     = Board.Y(square);
            Color color = board.GetColor(square);

            if (y == 0 || y == 7)             // cannot ever happen
            {
                return;
            }

            if (color == Color.White)
            {
                // move forward
                int target = square + 8;
                if (target < 64 && board.State[target] == 0)
                {
                    moves[count] = target;
                    count++;

                    target = square + 16;
                    if (y == 1 && board.State[target] == 0)
                    {
                        moves[count] = target;
                        count++;
                    }
                }

                // capture left
                target = square + 7;
                if (x > 0 && y < 7 && board.GetColor(target) == Color.Black)
                {
                    moves[count] = target;
                    count++;
                }

                // capture right
                target = square + 9;
                if (x < 7 && y < 7 && board.GetColor(target) == Color.Black)
                {
                    moves[count] = target;
                    count++;
                }

                // en passant left
                target = square + 7;
                if (y == 4 && x > 0 && board.EnPassantTile == target && board.State[target - 8] == ((int)Piece.Pawn | (int)Color.Black))
                {
                    moves[count] = target;
                    count++;
                }

                // en passant right
                target = square + 9;
                if (y == 4 && x < 7 && board.EnPassantTile == target && board.State[target - 8] == ((int)Piece.Pawn | (int)Color.Black))
                {
                    moves[count] = target;
                    count++;
                }
            }
            else
            {
                int target = square - 8;
                if (target >= 0 && board.State[target] == 0)
                {
                    moves[count] = target;
                    count++;

                    target = square - 16;
                    if (y == 6 && board.State[target] == 0)
                    {
                        moves[count] = target;
                        count++;
                    }
                }

                // capture left
                target = square - 9;
                if (x > 0 && y > 0 && board.GetColor(target) == Color.White)
                {
                    moves[count] = target;
                    count++;
                }

                // capture right
                target = square - 7;
                if (x < 7 && y > 0 && board.GetColor(target) == Color.White)
                {
                    moves[count] = target;
                    count++;
                }

                // en passant left
                target = square - 9;
                if (y == 3 && x > 0 && board.EnPassantTile == target && board.State[target + 8] == Colors.Val(Piece.Pawn, Color.White))
                {
                    moves[count] = target;
                    count++;
                }

                // en passant right
                target = square - 7;
                if (y == 3 && x < 7 && board.EnPassantTile == target && board.State[target + 8] == Colors.Val(Piece.Pawn, Color.White))
                {
                    moves[count] = target;
                    count++;
                }
            }
        }
コード例 #13
0
ファイル: Attacks.cs プロジェクト: adh2050/Chess
        private static void GetPawnAttacks(Board board, int square, int[] moves, ref int count)
        {
            int   x     = Board.X(square);
            int   y     = Board.Y(square);
            Color color = board.GetColor(square);

            if (color == Color.White)
            {
                // capture left
                int target = square + 7;
                if (x > 0 && y < 7)
                {
                    moves[count] = target;
                    count++;
                }

                // capture right
                target = square + 9;
                if (x < 7 && y < 7)
                {
                    moves[count] = target;
                    count++;
                }

                // en passant left
                target = square + 7;
                if (y == 4 && x > 0 && board.EnPassantTile == target && board.State[target - 8] == Colors.Val(Piece.Pawn, Color.Black))
                {
                    moves[count] = target - 8;                     // I'm ATTACKING the pawn at target-8 even though I move to target
                    count++;
                }

                // en passant right
                target = square + 9;
                if (y == 4 && x < 7 && board.EnPassantTile == target && board.State[target - 8] == Colors.Val(Piece.Pawn, Color.Black))
                {
                    moves[count] = target - 8;                     // I'm ATTACKING the pawn at target-8 even though I move to target
                    count++;
                }
            }
            else
            {
                // capture left
                int target = square - 9;
                if (x > 0 && y > 0)
                {
                    moves[count] = target;
                    count++;
                }

                // capture right
                target = square - 7;
                if (x < 7 && y > 0)
                {
                    moves[count] = target;
                    count++;
                }

                // en passant left
                target = square - 9;
                if (y == 3 && x > 0 && board.EnPassantTile == target && board.State[target + 8] == Colors.Val(Piece.Pawn, Color.White))
                {
                    moves[count] = target + 8;                   // I'm ATTACKING the pawn at target+8 even though I move to target
                    count++;
                }

                // en passant right
                target = square - 7;
                if (y == 3 && x < 7 && board.EnPassantTile == target && board.State[target + 8] == Colors.Val(Piece.Pawn, Color.White))
                {
                    moves[count] = target + 8;                     // I'm ATTACKING the pawn at target+8 even though I move to target
                    count++;
                }
            }
        }
コード例 #14
0
ファイル: Attacks.cs プロジェクト: adh2050/Chess
        private static void GetKingAttacks(Board board, int square, int[] moves, ref int count)
        {
            int   x      = Board.X(square);
            int   y      = Board.Y(square);
            Color color  = board.GetColor(square);
            int   target = 0;

            if (y < 7)
            {
                target = square + 7;
                if (x > 0)
                {
                    moves[count] = target;
                    count++;
                }

                target       = square + 8;
                moves[count] = target;
                count++;

                target = square + 9;
                if (x < 7)
                {
                    moves[count] = target;
                    count++;
                }
            }

            target = square - 1;
            if (x > 0)
            {
                moves[count] = target;
                count++;
            }

            target = square + 1;
            if (x < 7)
            {
                moves[count] = target;
                count++;
            }

            if (y > 0)
            {
                target = square - 9;
                if (x > 0)
                {
                    moves[count] = target;
                    count++;
                }

                target       = square - 8;
                moves[count] = target;
                count++;

                target = square - 7;
                if (x < 7)
                {
                    moves[count] = target;
                    count++;
                }
            }
        }