コード例 #1
0
    public void HandleInput(ChessGameController gameController)
    {
        if (piecePromotionIsActive)
        {
            HandlePromotion(gameController);
            return;
        }

        ChessPlayer player = gameController.ActivePlayer;
        Board       board  = gameController.Board;

        if (board.TurnIsActive || (gameController.State != GameState.Normal && gameController.State != GameState.Check))
        {
            return;
        }

        ChessPlayer   playerCopy = new ChessPlayer(null, player.TeamColor);
        ChessPlayer   enemyCopy  = new ChessPlayer(null, gameController.GetOppositeToActivePlayer().TeamColor);
        ChessGridInfo gridCopy   = playerCopy.TeamColor == TeamColor.White ? ChessGridInfo.CopyGrid(board.ChessGrid, playerCopy, enemyCopy) :
                                   ChessGridInfo.CopyGrid(board.ChessGrid, enemyCopy, playerCopy);

        Move foundMove = FindBestMove(gridCopy, playerCopy, enemyCopy);
        Move bestMove  = new Move(board.ChessGrid.GetPieceOnSquareIndex(foundMove.MovingPiece), foundMove.TargetSquare,
                                  board.ChessGrid.GetPieceOnSquareIndex(foundMove.TargetPiece), foundMove.PromotionFlag, foundMove.CastlingFlag,
                                  board.ChessGrid.GetPieceOnSquareIndex(foundMove.CastlingPiece), foundMove.CastlingTargetSquare);

        board.OnSelectPiece(bestMove.MovingPiece);
        board.OnSelectedPieceMove(bestMove);
        gameController.OnEnteredNormalMode();
        board.OnDeselectActivePiece();
    }
コード例 #2
0
    private Move FindBestMove(ChessGridInfo grid, ChessPlayer player, ChessPlayer enemy)
    {
        bool isMaximazing = player.TeamColor == TeamColor.White ? true : false;
        int  bestScore    = player.TeamColor == TeamColor.White ? int.MinValue : int.MaxValue;

        player.GenerateAllPossibleMoves(grid, true, true);
        enemy.GenerateAllPossibleMoves(grid, false, false);
        List <Move> possibleMoves = OrderMoves(player.AllPossibleMoves, enemy.AllPossibleMoves);
        Move        bestMove      = possibleMoves[0];

        for (int i = 0; i < possibleMoves.Count; i++)
        {
            grid.MakeMove(possibleMoves[i], player, enemy, true);

            int score = MiniMax(grid, enemy, player, !isMaximazing, MAX_DEPTH, int.MinValue, int.MaxValue);

            if ((isMaximazing && score > bestScore) || (!isMaximazing && score < bestScore))
            {
                bestScore = score;
                bestMove  = possibleMoves[i];
            }

            grid.UndoMove(player, enemy);
        }

        return(bestMove);
    }
コード例 #3
0
    private int MiniMax(ChessGridInfo grid, ChessPlayer player, ChessPlayer enemy, bool isMaximazing, int depth, int alpha, int beta)
    {
        player.GenerateAllPossibleMoves(grid, true, true);
        enemy.GenerateAllPossibleMoves(grid, false, false);

        if (depth == 0 || !player.HasAnyMoves())
        {
            return(EvaluateGrid(grid, player, enemy));
        }

        List <Move> possibleMoves = OrderMoves(player.AllPossibleMoves, enemy.AllPossibleMoves);

        if (isMaximazing)
        {
            int bestScore = int.MinValue;

            for (int i = 0; i < possibleMoves.Count; i++)
            {
                grid.MakeMove(possibleMoves[i], player, enemy, true);

                int score = MiniMax(grid, enemy, player, !isMaximazing, depth - 1, alpha, beta);
                bestScore = Mathf.Max(score, bestScore);
                alpha     = Mathf.Max(alpha, bestScore);

                grid.UndoMove(player, enemy);

                if (alpha <= beta)
                {
                    break;
                }
            }

            return(bestScore);
        }
        else
        {
            int bestScore = int.MaxValue;

            for (int i = 0; i < possibleMoves.Count; i++)
            {
                grid.MakeMove(possibleMoves[i], player, enemy, true);

                int score = MiniMax(grid, enemy, player, !isMaximazing, depth - 1, alpha, beta);
                bestScore = Mathf.Min(score, bestScore);
                beta      = Mathf.Min(beta, bestScore);

                grid.UndoMove(player, enemy);

                if (alpha <= beta)
                {
                    break;
                }
            }

            return(bestScore);
        }
    }
コード例 #4
0
ファイル: King.cs プロジェクト: wiktoriakeller/ChessGame
    public override void GeneratePossibleMoves(ChessGridInfo grid, ChessGridInfo gridCopy, ChessPlayer playerCopy, ChessPlayer enemyCopy,
                                               bool checkMovesValidity, bool checkSpecialMoves)
    {
        base.GeneratePossibleMoves(grid, gridCopy, playerCopy, enemyCopy, checkMovesValidity, checkSpecialMoves);

        if (checkSpecialMoves)
        {
            Castling(grid, gridCopy, enemyCopy);
        }
    }
コード例 #5
0
    public static void CreatePiecePrefabAndInitialize(Vector2Int squareIndex, PieceType pieceType, TeamColor teamColor,
                                                      ChessGridInfo grid, ChessPlayer player)
    {
        Piece       newPiece = CreateChessPiece(squareIndex, pieceType, grid, player);
        PieceEntity entity   = PieceFactory.CreatePiecePrefab(pieceType.ToString()).GetComponent <PieceEntity>();

        IMovable pieceMovementType = PieceFactory.GetMovementType(pieceType.ToString()) == MovementType.MovesInLine ?
                                     new MoveInLine() as IMovable : new Jump();

        newPiece.SetData(squareIndex, squareIndex, pieceType, teamColor, false, pieceMovementType, entity);
        player.AddPiece(newPiece);
    }
コード例 #6
0
ファイル: Piece.cs プロジェクト: wiktoriakeller/ChessGame
    public bool CheckIfMoveIsValid(ChessGridInfo grid, ChessPlayer player, ChessPlayer enemy, Move pieceMove)
    {
        grid.MakeMove(pieceMove, player, enemy, true);

        enemy.GenerateAllPossibleMoves(grid, false, false);
        Piece king        = player.FindFirstPieceOfType(PieceType.King);
        bool  isMoveValid = !(enemy.IsFieldUnderAttack(king.SquareIndex));

        grid.UndoMove(player, enemy);

        return(isMoveValid);
    }
コード例 #7
0
    public override void GeneratePossibleMoves(ChessGridInfo grid, ChessGridInfo gridCopy, ChessPlayer playerCopy,
                                               ChessPlayer enemyCopy, bool checkMovesValidity, bool checkSpecialMoves)
    {
        AvailableMoves.Clear();
        Vector2Int newSquare = Vector2Int.zero;

        for (int i = 0; i < possibleDirections.GetLength(0); i++)
        {
            if (i == 1 && MovedFirstTime)
            {
                break;
            }

            int newX = SquareIndex.x + possibleDirections[i, 0];
            int newY = SquareIndex.y + possibleDirections[i, 1];

            newSquare.Set(newX, newY);

            if (grid.CheckIfSquareIndexIsValid(newSquare))
            {
                Piece piece = grid.GetPieceOnSquareIndex(newSquare);
                Move  move  = CheckPromotionFlag(newSquare, piece);

                if (checkMovesValidity && piece == null)
                {
                    Piece attackedPieceCopy = piece == null ? null : gridCopy.GetPieceOnSquareIndex(piece.SquareIndex);
                    Move  moveCopy          = new Move(gridCopy.GetPieceOnSquareIndex(SquareIndex), newSquare, attackedPieceCopy, move.PromotionFlag);
                    bool  areMovesValid     = CheckIfMoveIsValid(gridCopy, playerCopy, enemyCopy, moveCopy);

                    if (!areMovesValid)
                    {
                        continue;
                    }
                }

                if (piece == null)
                {
                    AvailableMoves.Add(move);
                }
                else
                {
                    break;
                }
            }
        }

        PieceAttack(grid, gridCopy, playerCopy, enemyCopy, checkMovesValidity);
        EnPassant(grid, gridCopy, playerCopy, enemyCopy, checkMovesValidity);
    }
コード例 #8
0
    public override void GeneratePossibleMoves(ChessGridInfo grid, ChessGridInfo gridCopy, ChessPlayer playerCopy,
                                               ChessPlayer enemyCopy, bool checkMovesValidity, bool checkSpecialMoves)
    {
        AvailableMoves.Clear();
        Vector2Int newSquare = Vector2Int.zero;

        for (int i = 0; i < possibleDirections.GetLength(0); i++)
        {
            int newX = SquareIndex.x + possibleDirections[i, 0];
            int newY = SquareIndex.y + possibleDirections[i, 1];

            newSquare.Set(newX, newY);

            if (grid.CheckIfSquareIndexIsValid(newSquare))
            {
                Piece piece = grid.GetPieceOnSquareIndex(newSquare);
                Move  move  = new Move(this, newSquare, piece);

                if (checkMovesValidity && piece != null && piece.PieceType == PieceType.King)
                {
                    continue;
                }

                if (checkMovesValidity && (piece == null || (piece != null && piece.TeamColor != TeamColor)))
                {
                    Piece attackedPieceCopy = piece == null ? null : gridCopy.GetPieceOnSquareIndex(piece.SquareIndex);
                    Move  moveCopy          = new Move(gridCopy.GetPieceOnSquareIndex(SquareIndex), newSquare, attackedPieceCopy);
                    bool  areMovesValid     = CheckIfMoveIsValid(gridCopy, playerCopy, enemyCopy, moveCopy);

                    if (!areMovesValid)
                    {
                        continue;
                    }
                }

                if (piece == null)
                {
                    AvailableMoves.Add(move);
                }
                else if (piece != null && TeamColor != piece.TeamColor)
                {
                    AvailableMoves.Add(move);
                }
            }
        }
    }
コード例 #9
0
    private void PieceAttack(ChessGridInfo grid, ChessGridInfo gridCopy, ChessPlayer playerCopy,
                             ChessPlayer enemyCopy, bool checkMovesValidity)
    {
        Vector2Int newSquare = Vector2Int.zero;

        for (int i = 0; i < possibleAttacks.GetLength(0); i++)
        {
            int newX = SquareIndex.x + possibleAttacks[i, 0];
            int newY = SquareIndex.y + possibleAttacks[i, 1];

            newSquare.Set(newX, newY);

            if (grid.CheckIfSquareIndexIsValid(newSquare))
            {
                Piece piece = grid.GetPieceOnSquareIndex(newSquare);
                Move  move  = CheckPromotionFlag(newSquare, piece);

                if (checkMovesValidity && piece != null && piece.PieceType == PieceType.King)
                {
                    continue;
                }

                if (checkMovesValidity && (piece != null && piece.TeamColor != TeamColor))
                {
                    Piece attackedPieceCopy = piece == null ? null : gridCopy.GetPieceOnSquareIndex(piece.SquareIndex);
                    Move  moveCopy          = new Move(gridCopy.GetPieceOnSquareIndex(SquareIndex), newSquare, attackedPieceCopy, move.PromotionFlag);
                    bool  areMovesValid     = CheckIfMoveIsValid(gridCopy, playerCopy, enemyCopy, moveCopy);

                    if (!areMovesValid)
                    {
                        continue;
                    }
                }

                if (piece != null && TeamColor != piece.TeamColor)
                {
                    AvailableMoves.Add(move);
                }
            }
        }
    }
コード例 #10
0
    private void EnPassant(ChessGridInfo grid, ChessGridInfo gridCopy, ChessPlayer playerCopy,
                           ChessPlayer enemyCopy, bool checkMovesValidity)
    {
        int[,] directions = { { -1, 0 }, { 1, 0 } };
        Vector2Int newSquare = Vector2Int.zero;

        for (int i = 0; i < directions.GetLength(0); i++)
        {
            int newX = SquareIndex.x + directions[i, 0];
            int newY = SquareIndex.y + directions[i, 1];

            newSquare.Set(newX, newY);

            if (grid.CheckIfSquareIndexIsValid(newSquare))
            {
                Piece      piece  = grid.GetPieceOnSquareIndex(newSquare);
                Vector2Int square = new Vector2Int(SquareIndex.x + enPassantMoves[i, 0], SquareIndex.y + enPassantMoves[i, 1]);
                Move       move   = CheckPromotionFlag(square, piece);

                if (checkMovesValidity && piece != null && piece.PieceType == PieceType.Pawn && piece == grid.PieceMovedInPreviousTurn &&
                    Mathf.Abs(piece.SquareIndex.y - piece.PreviousSquareIndex.y) == 2 && piece.SquareIndex.x == piece.PreviousSquareIndex.x)
                {
                    Piece attackedPieceCopy = piece == null ? null : gridCopy.GetPieceOnSquareIndex(piece.SquareIndex);
                    Move  moveCopy          = new Move(gridCopy.GetPieceOnSquareIndex(SquareIndex), square, attackedPieceCopy, move.PromotionFlag);
                    bool  areMovesValid     = CheckIfMoveIsValid(gridCopy, playerCopy, enemyCopy, moveCopy);

                    if (!areMovesValid)
                    {
                        continue;
                    }
                }

                if (piece != null && piece.PieceType == PieceType.Pawn && piece == grid.PieceMovedInPreviousTurn &&
                    Mathf.Abs(piece.SquareIndex.y - piece.PreviousSquareIndex.y) == 2 && piece.SquareIndex.x == piece.PreviousSquareIndex.x)
                {
                    AvailableMoves.Add(move);
                    break;
                }
            }
        }
    }
コード例 #11
0
    private int EvaluateGrid(ChessGridInfo grid, ChessPlayer player, ChessPlayer enemy)
    {
        int  score         = 0;
        bool isKingInCheck = player.IsKingInCheck(enemy);

        if (!isKingInCheck && player.AllPossibleMoves.Count == 0)
        {
            return(0);
        }

        if (player.TeamColor == TeamColor.White && player.AllPossibleMoves.Count == 0 && isKingInCheck)
        {
            return(BLACK_VICTORY);
        }

        if (player.TeamColor == TeamColor.Black && player.AllPossibleMoves.Count == 0 && isKingInCheck)
        {
            return(WHITE_VICTORY);
        }

        Vector2Int square = Vector2Int.zero;

        for (int i = 0; i < ChessGridInfo.GRID_SIZE; i++)
        {
            for (int j = 0; j < ChessGridInfo.GRID_SIZE; j++)
            {
                square.Set(j, i);
                Piece piece = grid.GetPieceOnSquareIndex(square);

                if (piece != null)
                {
                    if (piece.TeamColor == TeamColor.White)
                    {
                        score += PiecePositionEvaluation.PieceValue[piece.PieceType];
                    }
                    else
                    {
                        score -= PiecePositionEvaluation.PieceValue[piece.PieceType];
                    }

                    score += PiecePositionEvaluation.PositionEvaluation[(piece.PieceType, piece.TeamColor)][i, j];
コード例 #12
0
    public void GenerateAllPossibleMoves(ChessGridInfo grid, bool checkMovesValidity, bool checkSpecialMoves)
    {
        ChessGridInfo gridCopy   = null;
        ChessPlayer   enemyCopy  = null;
        ChessPlayer   playerCopy = null;

        if (checkMovesValidity)
        {
            TeamColor opponentColor = TeamColor == TeamColor.White ? TeamColor.Black : TeamColor.White;
            playerCopy = new ChessPlayer(null, TeamColor);
            enemyCopy  = new ChessPlayer(null, opponentColor);
            gridCopy   = opponentColor == TeamColor.White ? ChessGridInfo.CopyGrid(grid, enemyCopy, playerCopy)
                : ChessGridInfo.CopyGrid(grid, playerCopy, enemyCopy);
        }

        AllPossibleMoves.Clear();
        for (int i = 0; i < ActivePieces.Count; i++)
        {
            ActivePieces[i].GeneratePossibleMoves(grid, gridCopy, playerCopy, enemyCopy, checkMovesValidity, checkSpecialMoves);
            AllPossibleMoves.AddRange(ActivePieces[i].AvailableMoves);
        }
    }
コード例 #13
0
    public static ChessGridInfo CopyGrid(ChessGridInfo grid, ChessPlayer whitePlayer, ChessPlayer blackPlayer)
    {
        ChessGridInfo newGrid = new ChessGridInfo();
        Vector2Int    square  = Vector2Int.zero;

        for (int i = 0; i < GRID_SIZE; i++)
        {
            for (int j = 0; j < GRID_SIZE; j++)
            {
                square.Set(j, i);
                Piece pieceOnGrid = grid.GetPieceOnSquareIndex(square);

                if (pieceOnGrid != null)
                {
                    Piece copy = ChessGameController.PieceFactory.CreatePiece(pieceOnGrid.GetType().ToString());
                    copy.SetData(pieceOnGrid.SquareIndex, pieceOnGrid.PreviousSquareIndex, pieceOnGrid.PieceType, pieceOnGrid.TeamColor,
                                 pieceOnGrid.MovedFirstTime, pieceOnGrid.Movement, null);
                    newGrid.SetChessPieceOnGrid(copy, square);

                    if (copy.TeamColor == TeamColor.White)
                    {
                        whitePlayer?.AddPiece(copy);
                    }

                    if (copy.TeamColor == TeamColor.Black)
                    {
                        blackPlayer?.AddPiece(copy);
                    }
                }
            }
        }

        newGrid.SelectedPiece            = grid.SelectedPiece;
        newGrid.PieceMovedInPreviousTurn = grid.PieceMovedInPreviousTurn;
        return(newGrid);
    }
コード例 #14
0
    public static Piece CreateChessPiece(Vector2Int squareIndex, PieceType pieceType, ChessGridInfo grid, ChessPlayer player)
    {
        Piece piece = PieceFactory.CreatePiece(pieceType.ToString());

        grid.SetChessPieceOnGrid(piece, squareIndex);
        return(piece);
    }
コード例 #15
0
ファイル: Piece.cs プロジェクト: wiktoriakeller/ChessGame
 public abstract void GeneratePossibleMoves(ChessGridInfo grid, ChessGridInfo gridCopy, ChessPlayer playerCopy, ChessPlayer enemyCopy,
                                            bool checkMovesValidity, bool checkSpecialMoves);
コード例 #16
0
ファイル: Board.cs プロジェクト: wiktoriakeller/ChessGame
 private void Awake()
 {
     TurnIsActive   = false;
     SquareSelector = GetComponent <ChessSquareSelector>();
     ChessGrid      = new ChessGridInfo();
 }
コード例 #17
0
ファイル: King.cs プロジェクト: wiktoriakeller/ChessGame
    private void Castling(ChessGridInfo grid, ChessGridInfo gridCopy, ChessPlayer enemyCopy)
    {
        if (MovedFirstTime)
        {
            return;
        }

        enemyCopy.GenerateAllPossibleMoves(gridCopy, false, false);

        if (enemyCopy.IsFieldUnderAttack(SquareIndex))
        {
            return;
        }

        int   kingRow   = SquareIndex.y;
        Piece leftRook  = grid.GetPieceOnSquareIndex(new Vector2Int(0, kingRow));
        Piece rightRook = grid.GetPieceOnSquareIndex(new Vector2Int(ChessGridInfo.GRID_SIZE - 1, kingRow));

        if (leftRook != null && leftRook.PieceType == PieceType.Rook && leftRook.TeamColor == TeamColor &&
            !leftRook.MovedFirstTime && leftRook.SquareIndex.y == SquareIndex.y)
        {
            bool       isLeftCastlingPossible = true;
            Vector2Int square = Vector2Int.zero;

            for (int i = leftRook.SquareIndex.x + 1; i < SquareIndex.x; i++)
            {
                square.Set(i, kingRow);
                if (gridCopy.GetPieceOnSquareIndex(square) != null ||
                    (i > 1 && enemyCopy.IsFieldUnderAttack(square)))
                {
                    isLeftCastlingPossible = false;
                    break;
                }
            }

            if (isLeftCastlingPossible)
            {
                Move move = new Move(this, new Vector2Int(2, kingRow), null, false, true, leftRook, new Vector2Int(3, kingRow));
                AvailableMoves.Add(move);
            }
        }

        if (rightRook != null && rightRook.PieceType == PieceType.Rook && rightRook.TeamColor == TeamColor &&
            !rightRook.MovedFirstTime && rightRook.SquareIndex.y == SquareIndex.y)
        {
            bool       isRightCastlingPossible = true;
            Vector2Int square = Vector2Int.zero;

            for (int i = SquareIndex.x + 1; i < rightRook.SquareIndex.x; i++)
            {
                square.Set(i, kingRow);
                if (gridCopy.GetPieceOnSquareIndex(square) != null || enemyCopy.IsFieldUnderAttack(square))
                {
                    isRightCastlingPossible = false;
                    break;
                }
            }

            if (isRightCastlingPossible)
            {
                Move move = new Move(this, new Vector2Int(6, kingRow), null, false, true, rightRook, new Vector2Int(5, kingRow));
                AvailableMoves.Add(move);
            }
        }
    }