示例#1
0
        public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player)
        {
            List <Pos2> maneuvers = new List <Pos2>();
            List <Pos2> captures  = new List <Pos2>();

            int[,] dydx =
            {
                { 2, -1 }, { 2, 1 }, { -2, -1 }, { -2, 1 },
                { 1, -2 }, { 1, 2 }, { -1, -2 }, { -1, 2 }
            };

            int y, x;

            for (int i = 0; i < (dydx.Length / dydx.Rank); i++)
            {
                y = pos.y + dydx[i, 0];
                x = pos.x + dydx[i, 1];

                // if this is a valid spot to put the knight
                if (y >= 0 && y < 8 && // within bounds
                    x >= 0 && x < 8 && // ^^^
                    Math.Sign(board.value[y, x]) != player)    // not own piece
                {
                    if (Math.Sign(board.value[y, x]) == -player)
                    {
                        captures.Add(new Pos2(y, x));
                    }
                    else
                    {
                        maneuvers.Add(new Pos2(y, x));
                    }
                }
            }
            return(maneuvers, captures);
        }
示例#2
0
        public bool PlayerIsTrapped(int player)
        {
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    int p = value[i, j];

                    // if piece does not belong to player, move on
                    if (Math.Sign(p) != player)
                    {
                        continue;
                    }

                    List <Pos2>[] sqrs = new List <Pos2> [2]; // destination squares
                    Pos2          src  = new Pos2(i, j);      // current piece's starting position

                    // get all pseudo-legal moves for current piece
                    (sqrs[0], sqrs[1]) =
                        Pieces.dict[(uint)Math.Abs(p)].ListMoves(this, src, player);

                    foreach (List <Pos2> l in sqrs) // for each move type
                    {
                        // try to find a non suicidal move
                        if (l.Exists(d => !MoveIsSuicide(new Move(src, d), player)))
                        {
                            return(false);
                        }
                    }
                }
            }
            // if you've checked every move and none work,
            return(true);
        }
示例#3
0
        public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player)
        {
            List <Pos2> maneuvers = new List <Pos2>();
            List <Pos2> captures  = new List <Pos2>();

            // first determine maneuvers available to the pawn
            int y = pos.y + player;
            int x = pos.x;

            if (y < 8 && y >= 0 &&
                Math.Sign(board.value[y, x]) == 0)    // or is empty
            {
                // it can move forward 1
                maneuvers.Add(new Pos2(y, x));

                // if pawn is at home & nothing is 2 squares ahead
                y += player;
                if (board.touch[pos.y, x] == 0 &&
                    Math.Sign(board.value[y, x]) == 0)    // or is empty
                {
                    maneuvers.Add(new Pos2(y, x));
                }
            }

            // now determine captures available to the pawn
            y = pos.y + player;
            for (int i = 0; i < 2; i++)
            {
                x = pos.x + 1 - 2 * i;

                // check if it's possible to capture in this direction
                if (x >= 0 && x < 8 &&
                    y >= 0 && y < 8)
                {
                    // capture other player's piece directly
                    if (Math.Sign(board.value[y, x]) == -player)
                    {
                        captures.Add(new Pos2(y, x));
                    }
                    // capture via en passant (considered maneuver)
                    if (pos.y == (int)(3.5f + player) &&
                        board.value[pos.y, x] == -player &&
                        board.touch[pos.y, x] == 1 &&
                        board.touch[pos.y + player * 2, x] == 1)
                    {
                        maneuvers.Add(new Pos2(y, x));
                    }
                }
            }
            return(maneuvers, captures);
        }
示例#4
0
        public bool MoveIsSuicide(Move move, int player)
        {
            // allow null move parameter to mean no move
            move ??= new Move(new Pos2(0, 0), new Pos2(0, 0));

            Board test = new Board(this); // copy board state

            test.MakeMove(move, player);  // make move on new board

            // find kind in both variations
            Pos2[] pos = new Pos2[2];

            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if (value[i, j] == Pieces.KING * player)
                    {
                        pos[0] = new Pos2(i, j);
                    }

                    if (test.value[i, j] == Pieces.KING * player)
                    {
                        pos[1] = new Pos2(i, j);
                    }

                    if (pos[0] != null && pos[1] != null)
                    {
                        break;
                    }
                }
            }

            do                                              // (must happen at least once)
            {
                pos[0].y += Math.Sign(pos[1].y - pos[0].y); // interpolate king positions on 2nd board
                pos[0].x += Math.Sign(pos[1].x - pos[0].x); // (if king is stationary do nothing)

                // if king is hit at any point during his journey
                if (test.PosIsHitBy(pos[0], null, player))
                {
                    return(true);
                }
            }while (pos[0].y != pos[1].y || pos[0].x != pos[1].x);

            return(false);
        }
示例#5
0
        public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player)
        {
            List <Pos2> maneuvers = new List <Pos2>();
            List <Pos2> captures  = new List <Pos2>();

            int dy, dx;

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    dy = 1 - 2 * i; // every combination of 1 & -1
                    dx = 1 - 2 * j;

                    var(tmpm, tmpc) = IPiece.CastMoves(board, pos, dy, dx, player);

                    maneuvers.AddRange(tmpm);
                    captures.AddRange(tmpc);
                }
            }
            return(maneuvers, captures);
        }
示例#6
0
        public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player)
        {
            List <Pos2> maneuvers = new List <Pos2>();
            List <Pos2> captures  = new List <Pos2>();

            int dy, dx;

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    dy = i * (1 - 2 * j);
                    dx = (i == 0 ? 1 : 0) * (1 - 2 * j);

                    var(tmpm, tmpc) = IPiece.CastMoves(board, pos, dy, dx, player);

                    maneuvers.AddRange(tmpm);
                    captures.AddRange(tmpc);
                }
            }
            return(maneuvers, captures);
        }
示例#7
0
        public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player)
        {
            List <Pos2> maneuvers = new List <Pos2>();
            List <Pos2> captures  = new List <Pos2>();

            for (int dx = -1; dx < 2; dx++)
            {
                for (int dy = -1; dy < 2; dy++)
                {
                    if (dx == 0 && dy == 0)
                    {
                        continue;
                    }

                    var(tmpm, tmpc) = IPiece.CastMoves(board, pos, dy, dx, player);

                    maneuvers.AddRange(tmpm);
                    captures.AddRange(tmpc);
                }
            }
            return(maneuvers, captures);
        }
示例#8
0
        /*-BOARD STATE QUERY FUNCTIONS---------------------------------------*/

        public bool PosIsHitBy(Pos2 pos, uint[] ignoredPieces, int player)
        {
            if (pos == null)
            {
                throw new ArgumentNullException();
            }
            if (ignoredPieces == null)
            {
                ignoredPieces = new uint[] { }
            }
            ;

            // iterate through each piece type
            foreach (KeyValuePair <uint, IPiece> kvp in Pieces.dict)
            {
                // check if piece is included
                if (ignoredPieces.Contains(kvp.Key))
                {
                    continue;
                }

                // get all captures possible of piece from pos
                List <Pos2> captures = kvp.Value.ListMoves(this, pos, player).c;

                // check all potential captures here
                foreach (Pos2 dst in captures)
                {
                    // if this is the right piece to attack pos
                    if (Math.Abs(value[dst.y, dst.x]) == kvp.Key)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
示例#9
0
        public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player)
        {
            List <Pos2> maneuvers = new List <Pos2>();
            List <Pos2> captures  = new List <Pos2>();

            // first find all normal moves
            for (int dy = -1; dy <= 1; dy++)
            {
                for (int dx = -1; dx <= 1; dx++)
                {
                    int y = pos.y + dy;
                    int x = pos.x + dx;

                    if (y >= 0 && y < 8 && // within bounds
                        x >= 0 && x < 8 && // ^^^
                        Math.Sign(board.value[y, x]) != player)    // or is not friendly piece
                    {
                        if (Math.Sign(board.value[y, x]) == -player)
                        {
                            captures.Add(new Pos2(y, x));
                        }
                        else
                        {
                            maneuvers.Add(new Pos2(y, x));
                        }
                    }
                }
            }

            // now find castling moves
            // TODO: implement chess960 castling rules (more general)
            if (board.touch[pos.y, pos.x] == 0 && // untouched king
                !board.PosIsHitBy(pos, new uint[] { Pieces.KING }, player))    // not in check
            {
                for (int i = 0; i < 2; i++)
                {
                    int dx = 1 - 2 * i;                                // -1 or 1

                    if (board.touch[pos.y, (int)(4 + 3.5f * dx)] == 0) // untouched rook
                    {
                        bool flag = false;

                        // make sure squares are open
                        for (int j = 3 + dx; j > 0 && j < 7; j += dx)
                        {
                            if (board.value[pos.y, j] != 0)
                            {
                                flag = true;
                                break;
                            }
                        }
                        if (flag)
                        {
                            continue;
                        }

                        maneuvers.Add(new Pos2(pos.y, 3 + 2 * dx));
                    }
                }
            }

            return(maneuvers, captures);
        }