Beispiel #1
0
 /* Takes the board, current player, and current players king position and looks for checks on the
 king position from the opponent rook and diagonal queen. */
 private bool RookQueenCheck(ChessPosition cpmCopy, Player curPlayer, Tuple<int, int> curPlayersKingPos, ref List<Tuple<int, int>> kingCheckedBy)
 {
     bool kingInCheck = false;
     EGamePieces oppositeRook = (curPlayer.PlayerValue == EGamePlayers.White) ? EGamePieces.BlackRook : EGamePieces.WhiteRook;
     EGamePieces oppositeQueen = (curPlayer.PlayerValue == EGamePlayers.White) ? EGamePieces.BlackQueen : EGamePieces.WhiteQueen;
     var adjRays = GetPieceRay(oppositeRook, curPlayersKingPos);
     // look through the rays until blocked, if find a rook or queen not owned by curPlayer
     // then this represents a discovered attack on current Player's king.
     foreach (var ray in adjRays)
     {
         foreach (var position in ray)
         {
             Tile tileAtPosition = cpmCopy.Board[position.Item1, position.Item2];
             // if position not empty
             if (!tileAtPosition.IsEmpty())
             {
                 // if the position is occupied by an attacking bishop/ queen
                 // add this to the kingcheckedbyvalue
                 if (!curPlayer.Owns(tileAtPosition.piece))
                 {
                     if (tileAtPosition.piece.Val == oppositeRook || tileAtPosition.piece.Val == oppositeQueen)
                     {
                         kingInCheck = true;
                         kingCheckedBy.Add(position);
                     }
                 }
                 // no more threats in this ray, move onto next rays to see if any other threats
                 break;
             }
         }
     }
     return kingInCheck;
 }
Beispiel #2
0
 /* This function receives a move object and the chess game and checks if the move also
 includes a pawn promotion, if it does it prompts the player for the selection piece, and
 adds it to the FormedMove. If it does not it ends silently
 TODO: could change it back to return bool, ref the selection piece then add it to move in the calling code ~~style issue*/
 private void MoveIncludesPawnPromotion(ref FormedMove move, ChessPosition cpm)
 {
     Piece mvPiece = cpm.Board[move.PosA.Item1, move.PosA.Item2].piece;
     Tuple<int, int> posB = move.PosB;
     // if moving piece is a pawn and posB isHighRank
     if ((mvPiece.Val == EGamePieces.WhitePawn || mvPiece.Val == EGamePieces.BlackPawn) &&
         (IsHighRank(posB)))
     {
         // Safe invoke for popup onto main thread via viewRef
         PromotionSelectionPopup(ref move, mvPiece);
     }
 }
Beispiel #3
0
 /* Takes the board, current player, and current players king position and looks for checks on the
 king position from the opponent Pawn. */
 private bool PawnCheck(ChessPosition cpmCopy, Player curPlayer, Tuple<int, int> curPlayersKingPos, ref List<Tuple<int, int>> kingCheckedBy)
 {
     bool kingInCheck = false;
     // the code must look in the advance direction (own pawn / CURRENT) to see the tiles an OPPONENT pawn could be on
     EGamePieces currentPawn = (curPlayer.PlayerValue == EGamePlayers.White) ? EGamePieces.WhitePawn : EGamePieces.BlackPawn;
     EGamePieces opponentPawn = (curPlayer.PlayerValue == EGamePlayers.White) ? EGamePieces.BlackPawn : EGamePieces.WhitePawn;
     var pRays = GetPieceRayPawnCapture(currentPawn, curPlayersKingPos);
     // look through the rays until blocked, if find a Pawn not owned by curPlayer
     // then this represents a discovered attack on current Player's king.
     foreach (var ray in pRays)
     {
         foreach (var position in ray)
         {
             Tile tileAtPosition = cpmCopy.Board[position.Item1, position.Item2];
             // if position not empty
             if (!tileAtPosition.IsEmpty())
             {
                 // if the position is occupied by an attacking pawn
                 // add this to the kingcheckedbyvalue
                 if (!curPlayer.Owns(tileAtPosition.piece))
                 {
                     if (tileAtPosition.piece.Val == opponentPawn)
                     {
                         kingInCheck = true;
                         kingCheckedBy.Add(position);
                     }
                 }
                 // no more threats in this ray, move onto next rays to see if any other threats
                 break;
             }
         }
     }
     return kingInCheck;
 }
Beispiel #4
0
        /* Takes a move object and a chess board object and returns true if
        the piece on the B position of the move belongs to the other player.

        TODO: replace with alternate call to previous functions*/
        private bool IsMoveBPieceOtherPlayer(FormedMove move, ChessPosition cpm, ref Tile tileB)
        {
            bool result = false;
            tileB = cpm.Board[move.PosB.Item1, move.PosB.Item2];
            if (!tileB.IsEmpty())
                if (!cpm.Player.Owns(tileB.piece))
                    result = true;
            return result;
        }
Beispiel #5
0
        /* Takes a move which so far meets the requirements for a Movement type
        move on the chess board. This function checks that one of the moving piece's
        rays covers this move object (The piece itself can move in this direction/way)
        and that the way is not blocked by another piece. */
        private bool IsPieceMovementLegal(FormedMove move, ChessPosition cpm)
        {
            bool isLegalMovement = true;
            Tuple<int, int> posA = move.PosA;
            Tuple<int, int> posB = move.PosB;
            Tile tileA = cpm.Board[posA.Item1, posA.Item2];
            List<List<Tuple<int, int>>> movementRays;
            // get the rays for a piece of type=piece.Val and location=posA

            movementRays = GetPieceRay(tileA.piece.Val, posA);
            ;
            List<Tuple<int, int>> moveRayUsed = null;
            foreach (List<Tuple<int, int>> ray in movementRays)
            {
                // for pawns the rays are comprise TWO forward positions (from first move)
                // so if the pawn has already .MovedOnce don not consider the second position in the ray
                // as the pawn can no longer legally move to that position
                if ((tileA.piece.Val == EGamePieces.WhitePawn || tileA.piece.Val == EGamePieces.BlackPawn) &&
                    (tileA.piece.MovedOnce))
                {
                    ;
                    if (ray[0].Equals(posB))
                    {
                        ;
                        moveRayUsed = ray;
                        break;
                    }
                }
                // for all other cases consider the entirety of the ray
                else
                {
                    if (ray.Contains(posB))
                    {
                        moveRayUsed = ray;
                        break;
                    }
                }

            }
            if (moveRayUsed != null)
                // check there are no intermediate Pieces blocking the movement
                foreach (Tuple<int, int> tilePos in moveRayUsed)
                {
                    Tile tileAtPosition = cpm.Board[tilePos.Item1, tilePos.Item2];
                    if (!tileAtPosition.IsEmpty())
                    {
                        isLegalMovement = false;
                        break;
                    }
                    if (tilePos.Equals(posB))
                        break;
                }
            else
                isLegalMovement = false;

            return isLegalMovement;
        }
Beispiel #6
0
 /* Takes a move object and a chess board object and returns true if
 the piece on the A position of the move belongs to the current player. */
 private bool IsMoveAPieceCurPlayer(FormedMove move, ChessPosition cpm, ref Tile tileA)
 {
     bool result = false;
     tileA = cpm.Board[move.PosA.Item1, move.PosA.Item2];
     if (!tileA.IsEmpty())
         if (cpm.Player.Owns(tileA.piece))
             result = true;
     return result;
 }
Beispiel #7
0
 /* Takes a move object and a chess board object and returns true if
 the tile on the B position of the move is empty. */
 private bool IsMoveBEmpty(FormedMove move, ChessPosition cpm, ref Tile tileB)
 {
     tileB = cpm.Board[move.PosB.Item1, move.PosB.Item2];
     return tileB.IsEmpty();
 }
Beispiel #8
0
        /* Takes a move which so far meets the requirements for an EnPassant type
        move on the chess board. This function checks that one of the moving pawn's
        diagonal rays covers this move object (The piece itself can move in this direction/way)
        and that the corresponding enpassant capture tile for this movement contains
        an enemy pawn piece to capture.*/
        private bool IsEnPassantCaptureLegal(FormedMove move, ChessPosition cpm)
        {
            bool isLegalEnPassantCapture = true;
            Tuple<int, int> posA = move.PosA;
            Tuple<int, int> posB = move.PosB;
            Tile tileA = cpm.Board[posA.Item1, posA.Item2];
            List<List<Tuple<int, int>>> epMovementRays;
            // get attack ray for the pawn on tileA
            // these are the movement rays in the case of EP
            epMovementRays = GetPieceRayPawnCapture(tileA.piece.Val, posA);
            List<Tuple<int, int>> moveRayUsed = null;
            foreach(List<Tuple<int, int>> ray in epMovementRays)
            {
                if (ray.Contains(posB))
                {
                    moveRayUsed = ray;
                    break;
                }
            }
            // so at this point:
            // have posA and posB and it is a valid enpassant-type
            // movement (diagonal to empty square)

            if (moveRayUsed != null)
            {
                // continue checking ep position
                int epX = posB.Item2;
                int epY = posA.Item1;
                Tuple<int, int> posEP = Tuple.Create(epY, epX);
                // if this computed ep square between posA and posB does not
                // match the currently valid EnPassantSq, then this is not
                // a valid EP capture
                if (!posEP.Equals(cpm.EnPassantSq))
                    isLegalEnPassantCapture = false;

            }
            else
                isLegalEnPassantCapture = false;

            return isLegalEnPassantCapture;
        }
Beispiel #9
0
        /* Takes a move which so far meets the requirements for a Capture type
        move on the chess board. This function checks that the one of the capturer
        piece's rays covers this move object (The piece itself can move in this way)
        and that the way is not blocked by another piece en route.

        Note: This is very similar to the IsPieceMovementLegal function, only
        difference is that the check for pieces on a tile is moved after the
        check for the final tile (since the final tile will have a piece on it:
        the piece being captured, and dont want the code to consider that as an
        intermediate piece which would block the capture.

        Other difference is that if the capturer piece is of type pawn, a unique
        set of pawn capture rays are gotten (Pawn only piece to use different rays
        for capture and movement). */
        private bool IsCaptureLegal(FormedMove move, ChessPosition cpm)
        {
            bool isLegalCapture = true;

            Tuple<int, int> posA = move.PosA;
            Tuple<int, int> posB = move.PosB;

            Tile tileA = cpm.Board[posA.Item1, posA.Item2];
            List<List<Tuple<int, int>>> captureRays;

            if (tileA.piece.Val == EGamePieces.BlackPawn || tileA.piece.Val == EGamePieces.WhitePawn)
                captureRays = GetPieceRayPawnCapture(tileA.piece.Val, posA);
            else
                captureRays = GetPieceRay(tileA.piece.Val, posA);

            List<Tuple<int, int>> captureRayUsed = null;
            foreach (List<Tuple<int, int>> ray in captureRays)
            {
                if (ray.Contains(posB))
                {
                    captureRayUsed = ray;
                    break;
                }
            }
            if (captureRayUsed != null)
                // check there are no intermediate Pieces blocking the capture movement
                foreach (Tuple<int, int> position in captureRayUsed)
                {
                    if (position.Equals(posB))
                        break;
                    Tile tileAtPosition = cpm.Board[position.Item1, position.Item2];
                    if (!tileAtPosition.IsEmpty())
                    {
                        isLegalCapture = false;
                        break;
                    }
                }
            else
                isLegalCapture = false;

            return isLegalCapture;
        }
Beispiel #10
0
 /* Takes the board and the current player and returns the position of the current
 player's king. */
 private Tuple<int, int> GetCurPlayersKingPos(ChessPosition cpmCopy, Player curPlayer)
 {
     Tuple<int, int> curPlayersKingPos = null;
     for (int row = 0; row<cpmCopy.Size; row ++)
     {
         for (int col = 0; col<cpmCopy.Size; col ++)
         {
             Tile tile = cpmCopy.Board[row, col];
             if (!tile.IsEmpty())
             {
                 if ((curPlayer.Owns(tile.piece)) &&
                     (tile.piece.Val == EGamePieces.WhiteKing || tile.piece.Val == EGamePieces.BlackKing))
                 {
                     curPlayersKingPos = Tuple.Create(row, col);
                     break;
                 }
             }
         }
     }
     return curPlayersKingPos;
 }
Beispiel #11
0
        /* This function is passed a copy of the chess game. It uses the information contained in this object
        to determine whether or not the Current player's king is being threatened by check from the other player
        returning true if so. If it is being checked by the opposing player a list of the one / two coords containing the
        attacking pieces is stored in 'kingCheckedBy */
        public bool IsKingInCheck(ChessPosition cpmCopy, ref List<Tuple<int, int>> kingCheckedBy)
        {
            bool kingInCheck = false;
            Player curPlayer = cpmCopy.Player;
            Tuple<int, int> curPlayersKingPos = GetCurPlayersKingPos(cpmCopy, curPlayer);

            // using current player's king position, generate all attack vectors
            if (curPlayersKingPos != null)
            {
                // check for threats from the pieces of the opponent
                if (BishopQueenCheck(cpmCopy, curPlayer, curPlayersKingPos, ref kingCheckedBy) ||
                    RookQueenCheck(cpmCopy, curPlayer, curPlayersKingPos, ref kingCheckedBy) ||
                    KnightCheck(cpmCopy, curPlayer, curPlayersKingPos, ref kingCheckedBy) ||
                    KingCheck(cpmCopy, curPlayer, curPlayersKingPos, ref kingCheckedBy) ||
                    PawnCheck(cpmCopy, curPlayer, curPlayersKingPos, ref kingCheckedBy))
                    kingInCheck = true;
            }
            return kingInCheck;
        }
Beispiel #12
0
 /* Returns a ChessPosition object which is a deep copy of this one. Since this method is
 also inherited by the ChessPositionModel, if the CPM produces this object it will be a
 deep copy of the ChessPositionModel object as if it were a ChessPosition. (CPM minus handlers etc).
 This function will be used during evaluation in the king check phase, and will also be used during
 the move search of the ai function. */
 public ChessPosition getChessPositionCopy()
 {
     int dimCopy = Size;
     // deep copy the board manually //
     Tile[,] boardCopy = new Tile[dimCopy, dimCopy];
     for (int j = 0; j < dimCopy; j ++)
     {
         for (int k = 0; k < dimCopy; k ++)
         {
             Tile tileCopy = new Tile();
             if (!Board[j,k].IsEmpty())
             {
                 Piece piece = Board[j, k].piece;
                 EGamePieces val = piece.Val;
                 bool mv = piece.MovedOnce;
                 Piece pieceCopy = new Piece(val);
                 pieceCopy.MovedOnce = mv;
                 tileCopy.piece = pieceCopy;
             }
             boardCopy[j, k] = tileCopy;
         }
     }
     // copy rest of ChessPosition properties
     Player playerCopy = new Player(this.Player.PlayerValue);
     Dictionary<char, bool> castleCopy = new Dictionary<char, bool>(Castle);
     Tuple<int, int> enPassantSqCopy = (EnPassantSq == null) ? null : Tuple.Create(EnPassantSq.Item1, EnPassantSq.Item2);
     int halfmoveClockCopy = HalfMoveClock;
     List<EGamePieces> piecesCapdCopy = new List<EGamePieces>(PiecesCapd);
     // create and return the copy
     ChessPosition cpCopy = new ChessPosition(dimCopy, boardCopy, playerCopy, castleCopy, enPassantSqCopy, halfmoveClockCopy, piecesCapdCopy);
     return cpCopy;
 }