Ejemplo n.º 1
0
    private MinimaxResult MinimaxStep(BoardData p_board, Players p_player, int p_currentDepth)
    {
        GameResults t_gameResult = p_board.GetGameResult();

        if (t_gameResult != GameResults.Unfinished)
        {
            int t_score = t_gameResult == GameResults.Win ? MAX_SCORE : -MAX_SCORE;
            return(new MinimaxResult(t_score, null));
        }
        else if (p_currentDepth > MAX_DEPTH)
        {
            return(m_boardEvaluator.EvaluateBoard(p_board, p_player));
        }

        Move t_bestMove  = null;
        int  t_bestScore = 0;

        if (p_board.CurrentPlayer == Players.Human)
        {
            t_bestScore = -INFINITE;
        }
        else
        {
            t_bestScore = INFINITE;
        }

        List <Move> t_moves = new List <Move>();

        p_board.GetMoves(t_moves);

        foreach (Move t_move in t_moves)
        {
            BoardData     t_newBoard = p_board.GetNewBoard(t_move);
            MinimaxResult t_result   = MinimaxStep(t_newBoard, p_player, p_currentDepth + 1);

            if (p_board.CurrentPlayer == Players.Human)
            {
                if (t_bestScore < t_result.Score)
                {
                    t_bestScore = t_result.Score;
                    t_bestMove  = t_move;
                }
            }
            else
            {
                if (t_result.Score < t_bestScore)
                {
                    t_bestScore = t_result.Score;
                    t_bestMove  = t_move;
                }
            }
        }

        return(new MinimaxResult(t_bestScore, t_bestMove));
    }
Ejemplo n.º 2
0
    /*
     *      BoardsScores explanation:
     *
     * BoardScores are checked from the highest score to the lowest, if a
     * board fits in a BoardScores score, the that score is returned and
     * there is no further checking.
     * What a BoardScores score consists of is explained below:
     *
     * TERMINAL: board with two CHECK where the enemy will lose whatever move
     * he does.
     * X · O
     * · O ·
     * X · X
     *
     * TRIPLETRAP: board where by placing one more tile there would be three CHECK
     * X · @   @ = By placing another X here there would be three CHECK
     * · · ·
     * X O ·
     *
     * DOUBLETRAP: same as before, but by placing the said tile there would be two CHECK
     * · · @  @ = By placing another X here there would be three CHECK
     * · · ·
     * X O X
     *
     * EASYTRAP: DOUBLETRAP that is at the same time a CHECK
     * · · ·
     * · O ·
     * X · X
     *
     * CHECK: board where by placing one more tile the game would be a win
     * O · ·
     * X X ·
     * O · ·
     *
     * CORNER: board where the tile is in a corner
     * X · ·
     * · · ·
     * · · ·
     */

    public MinimaxResult EvaluateBoard(BoardData p_board, Players p_player)
    {
        int   t_score             = 0;
        Tiles t_currentPlayerTile = p_board.HumanTile;

        if (Players.AI == p_player)
        {
            t_currentPlayerTile = p_board.HumanTile ^ (Tiles)1;
        }

        GameResults t_gameResult = p_board.GetGameResult();

        if (t_gameResult == GameResults.Tie)
        {
            t_score = 0;
        }
        else if (t_gameResult == GameResults.Unfinished)
        {
            t_score = ScoreUnfinishedBoard(p_board, t_currentPlayerTile);
        }
        else
        {
            if (t_gameResult == GameResults.Win)
            {
                t_score = Minimax.MAX_SCORE;
            }
            else
            {
                t_score = -Minimax.MAX_SCORE;
            }
        }

        if (p_player == Players.AI)
        {
            t_score *= -1;
        }
        return(new MinimaxResult(t_score, null));
    }