Beispiel #1
0
        private void FindKingCastleMoves(
            List <Move> moves,
            ThreatMatrix threats,
            Player player,
            BoardLocation playerPieceLocation)
        {
            //When are you not allowed to castle?
            //    There are a number of cases when castling is not permitted:
            //    -Your king has been moved earlier in the game.
            //    -The rook that castles has been moved earlier in the game.
            //    -There are pieces standing between your king and rook.
            //    -The king is in check.
            //    -The king moves through a square that is attacked by a piece of the opponent.
            //    -The king would be in check after castling.

            if ((KingHasMoved(player)) ||                   //king has moved
                (threats.ContainsKey(playerPieceLocation))) //king in check
            {
                return;
            }

            if (CastleQueensideMoveAvailable(player, threats))
            {
                moves.Add(new Move(playerPieceLocation, player == Player.White ? BoardLocation.C1 : BoardLocation.C8, SpecialMoveType.CastleQueenside));
            }

            if (CastleKingsideMoveAvailable(player, threats))
            {
                moves.Add(new Move(playerPieceLocation, player == Player.White ? BoardLocation.G1 : BoardLocation.G8, SpecialMoveType.CastleKingside));
            }
        }
Beispiel #2
0
        private void DetermineGameState()
        {
            //find the king and moves for this player
            var kingLocation = _board.GetKingsLocation(CurrentPlayer);
            var moves        = FindMoves();

            //if we have no moves, this gets easy...
            if (!moves.Any())
            {
                //checkmate, son
                if (_threatMatrix.ContainsKey(kingLocation))
                {
                    GameState = CurrentPlayer == Player.White ? GameState.BlackWin : GameState.WhiteWin;
                }
                else
                {
                    GameState = GameState.DrawStalemate;
                }
                return;
            }

            //we need to check for draw due to insufficient material
            if (HasInsufficientMaterialForMate(CurrentPlayer) &&
                HasInsufficientMaterialForMate(CurrentPlayer.OpposingPlayer()))
            {
                GameState = GameState.DrawInsufficientMaterial;
            }

            //TODO
            //https://en.wikipedia.org/wiki/Draw_(chess)
            //TODO:Check threefold repetition
            //TODO:Check fifty-move rule
            //TODO: Check 'dead position' (not sure how that is done)
        }
Beispiel #3
0
 private bool CastleKingsideMoveAvailable(Player player, ThreatMatrix threats)
 {
     if (player == Player.White)
     {
         return
             ((!_moveHistory.Any(a => a.Source == BoardLocation.H1)) &&                             //rook has not moved
              (!threats.ContainsKey(BoardLocation.F1) && !threats.ContainsKey(BoardLocation.G1)) && //no threats in path
              (_board[BoardLocation.G1].IsEmpty() && _board[BoardLocation.G1].IsEmpty()));          //path is empty
     }
     else
     {
         return
             ((!_moveHistory.Any(a => a.Source == BoardLocation.H8)) &&                             //rook has not moved
              (!threats.ContainsKey(BoardLocation.F8) && !threats.ContainsKey(BoardLocation.G8)) && //no threats in path
              (_board[BoardLocation.F8].IsEmpty() && _board[BoardLocation.G8].IsEmpty()));          //path is empty
     }
 }
Beispiel #4
0
        private void FindMoves(
            List <Move> moves,
            ThreatMatrix threats,
            BoardLocation playerPieceLocation)
        {
            var chessPiece = _board[playerPieceLocation];
            var player     = chessPiece.Player();
            var playerPiecePinDirection = threats.ContainsKey(playerPieceLocation) ? threats[playerPieceLocation].Pin : default(ThreatDirection?);

            switch (chessPiece)
            {
            case ChessPiece.BlackPawn:
            case ChessPiece.WhitePawn:
                FindPawnMoves(moves, threats, player, playerPieceLocation, playerPiecePinDirection);
                break;

            case ChessPiece.BlackKnight:
            case ChessPiece.WhiteKnight:
                FindKnightMoves(moves, threats, player, playerPieceLocation, playerPiecePinDirection);
                break;

            case ChessPiece.BlackBishop:
            case ChessPiece.WhiteBishop:
                FindBishopMoves(moves, threats, player, playerPieceLocation, playerPiecePinDirection);
                break;

            case ChessPiece.BlackRook:
            case ChessPiece.WhiteRook:
                FindRookMoves(moves, threats, player, playerPieceLocation, playerPiecePinDirection);
                break;

            case ChessPiece.BlackQueen:
            case ChessPiece.WhiteQueen:
                FindQueenMoves(moves, threats, player, playerPieceLocation, playerPiecePinDirection);
                break;

            case ChessPiece.BlackKing:
            case ChessPiece.WhiteKing:
                //da king cant be pinned yo!
                FindKingMoves(moves, threats, player, playerPieceLocation);
                break;

            default:
                break;
            }
        }
Beispiel #5
0
        private void AddThreat(
            ThreatMatrix threatMatrix,
            BoardLocation playerKingLocation,
            BoardLocation threateningPieceLocation,
            BoardLocation boardLocationBeingThreatening,
            ThreatDirection direction,
            ThreatDirection?pin = null)
        {
            if (!threatMatrix.ContainsKey(boardLocationBeingThreatening))
            {
                threatMatrix.Add(boardLocationBeingThreatening, direction, pin);
            }
            else
            {
                //update the threat direction
                threatMatrix[boardLocationBeingThreatening].AddDirection(direction);

                //can only be pinned in one direction (since there is only one king)
                if (pin != null)
                {
                    threatMatrix[boardLocationBeingThreatening].AddPin(pin.Value);
                }
            }

            //if this is a king threat
            if (playerKingLocation == boardLocationBeingThreatening)
            {
                //we set the piece that is threatening the king here. Please note that it is possible more than one piece
                //is threatening the king but it is IMPOSSIBLE for a triple check to occur.
                var threat = threatMatrix[boardLocationBeingThreatening];
                if (threat.FirstPieceThreateningKingBoardLocation.HasValue)
                {
                    threat.SecondPieceThreateningKingBoardLocation = threateningPieceLocation;
                }
                else
                {
                    threat.FirstPieceThreateningKingBoardLocation = threateningPieceLocation;
                }
            }
        }
Beispiel #6
0
        private void FindKingMoves(
            List <Move> moves,
            ThreatMatrix threats,
            Player player,
            BoardLocation playerPieceLocation)
        {
            //we will use the threats matrix for this king to calculate our moves...
            var kingThreatLocations = _threatProvider.FindThreatsForBoardLocation(_board, playerPieceLocation);

            foreach (var location in kingThreatLocations.Keys)
            {
                //only add moves that do not have a threat on them
                if ((_board.LocationIsEmptyOrOccupiedBy(location, player.OpposingPlayer())) &&
                    (threats.ContainsKey(location) == false))
                {
                    moves.Add(new Move(playerPieceLocation, location, _board[location]));
                }
            }

            //find our castle moves
            FindKingCastleMoves(moves, threats, player, playerPieceLocation);
        }