C#Tic-Tac-Toe Minimax

时间:2016-04-25 08:12:20

标签: c# winforms minimax alpha-beta-pruning

我正在努力为tictactoe制作一个极小极大的AI。我的目标是它应该足够大的董事会。但是,我很难绕过如何实现算法。我已经阅读了无数不同的算法描述,但我似乎还没有能够使它工作。我的结果是一个令人难以置信的愚蠢AI。这是我的代码。

编辑:我想知道的主要观点是我如何让AI值得胜利,而不是在赢得胜利。截至目前,它并不关心我将赢得下一回合。

namespace TicTacToe_AI
{
public class Move //A class for moves
{
    public int x, y, value, MoveNumber;
    void SetMove(int a, int b)
    {
        x = a;
        y = b;
    }

    public Move(int a, int b)
    {
        SetMove(a, b);
    }
    public Move()
    { }
}

class AI //AIClass
{
    //The minimax algorithm
    public Move CalculateMoves(int[,] Board, int BoardSize, int Depth, Move BestMoveAI, Move BestMovePlayer, int OriginalDepth, int CurrentTurn) 
    {
        Depth--; //Decrease the depth for each iteration
        bool Alpha = false; //Alpha-beta pruning - needs improvement
        bool Beta = false;
        bool WinningMove = false; 
        if (CurrentTurn == 1) CurrentTurn = 2;
        if (CurrentTurn == 2) CurrentTurn = 1;
        List<Move> DifferentMoves = new List<Move>();
        List<Move> PossibleMoves = new List<Move>();
        for (int i = 0; i < BoardSize; i++) //Add all possible moves to a list
        {
            for (int j = 0; j < BoardSize; j++)
            {
                if (Board[i, j] == 0)
                {
                    Move Possible = new Move(i, j);
                    PossibleMoves.Add(Possible);
                }
            }
        }
        if (CurrentTurn == 2 && Depth >= 0 && Depth < BestMoveAI.MoveNumber) Alpha = true; //Alpha-beta pruning
        if (CurrentTurn == 1 && Depth >= 0 && Depth < BestMovePlayer.MoveNumber) Beta = true;
        if(Alpha || Beta)
        {

            foreach (Move TryMove in PossibleMoves) //Try every possible move to see if they are a winning move
            {
                int[,] Trying = new int[BoardSize, BoardSize];
                Trying = (int[,])Board.Clone();
                Trying[TryMove.x, TryMove.y] = CurrentTurn;
                TryMove.MoveNumber = OriginalDepth - Depth;
                if (Form1.Win(Trying) == 2)
                {
                    TryMove.value = -1;
                    DifferentMoves.Add(TryMove);
                    if (Depth + 1 == OriginalDepth)
                    {
                        if (TryMove.MoveNumber < BestMoveAI.MoveNumber) BestMoveAI = TryMove;
                        WinningMove = true;
                        break;
                    }
                    else
                    {
                        WinningMove = true;
                        if (TryMove.MoveNumber < BestMoveAI.MoveNumber) BestMoveAI = TryMove;
                        return TryMove;
                    }
                }
                else if (Form1.Win(Trying) == 1)
                {
                    WinningMove = true;
                    TryMove.value = 1;
                    BestMovePlayer = TryMove;
                    DifferentMoves.Add(TryMove);
                    return TryMove;
                }
            }

            if (!WinningMove) // If no winning move was found, try recursively searching for a winning move
            {
                if (Alpha || Beta)
                {
                    foreach (Move TryMove2 in PossibleMoves)
                    {
                        int[,] TestMove = new int[BoardSize, BoardSize];
                        TestMove = (int[,])Board.Clone();
                        TestMove[TryMove2.x, TryMove2.y] = CurrentTurn;
                        TryMove2.value = CalculateMoves(TestMove, BoardSize, Depth, BestMoveAI, BestMovePlayer, OriginalDepth, CurrentTurn).value;
                        DifferentMoves.Add(TryMove2);
                    }
                }
            }

        }
        //Find the best possible move and return it
        BestMoveAI.value = 0;
        BestMoveAI.MoveNumber = OriginalDepth;
        BestMovePlayer.value = 0;
        BestMovePlayer.MoveNumber = OriginalDepth;
        if (CurrentTurn == 2) 
        {
            foreach (Move AllMoves in DifferentMoves)
            {
                if (AllMoves.value <= BestMoveAI.value && AllMoves.MoveNumber <= BestMoveAI.MoveNumber)
                {
                    BestMoveAI = AllMoves;
                }
            }
            return BestMoveAI;
        }
        else if(CurrentTurn == 1)
        {
            foreach (Move AllMoves in DifferentMoves)
            {
                if (AllMoves.value >= BestMovePlayer.value && AllMoves.MoveNumber <= BestMovePlayer.MoveNumber)
                {
                    BestMovePlayer = AllMoves;
                }
            }
            return BestMovePlayer;
        }
        Move BadMove = new Move(); 
        BadMove.value = 0;
        BadMove.MoveNumber = Depth;
        return BadMove;




    }
}

}

0 个答案:

没有答案