Как реализовать алгоритм minimax?

Делаю игру крестики нолики 3×3 в Unity, на языке C#, хочу добавить бота с алгоритмом minimax, чтобы игрок практически не мог его победить.

Подскажите как это сделать.

Код игры:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class GameController : MonoBehaviour
{
    public string[,] tictactoeArray = new string[,]{ { "?", "?", "?" }, 
                                                     { "?", "?", "?" }, 
                                                     { "?", "?", "?" } };
    //row 1
    public GameObject tictactoeBatton00 = new GameObject();
    public GameObject tictactoeBatton01 = new GameObject();
    public GameObject tictactoeBatton02 = new GameObject();
    //row 2
    public GameObject tictactoeBatton10 = new GameObject();
    public GameObject tictactoeBatton11 = new GameObject();
    public GameObject tictactoeBatton12 = new GameObject();
    //row 3
    public GameObject tictactoeBatton20 = new GameObject();
    public GameObject tictactoeBatton21 = new GameObject();
    public GameObject tictactoeBatton22 = new GameObject();

    public GameObject X = new GameObject();
    public GameObject O = new GameObject();

    public GameObject playAgainButtonObj;
    public Button playAgainButton;
    public Text message;

    bool gameEnd;

    int round = 0;

    // Start is called before the first frame update
    void Start()
    {
        message.enabled = false;
        playAgainButtonObj.SetActive(false);
        gameEnd = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0) && ! gameEnd)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {

                if (hit.transform.name == tictactoeBatton00.name && tictactoeArray[0, 0]=="?") {;
                    if (round % 2 == 0)
                    {
                        tictactoeArray[0,0] = "X";
                        round++;
                        Instantiate(X, new Vector3(tictactoeBatton00.transform.position.x, tictactoeBatton00.transform.position.y, tictactoeBatton00.transform.position.z), Quaternion.identity);

                    }
                    else {
                        tictactoeArray[0,0] = "O";
                        round++;
                        Instantiate(O, new Vector3(tictactoeBatton00.transform.position.x, tictactoeBatton00.transform.position.y, tictactoeBatton00.transform.position.z), Quaternion.identity);
                    }
                    checkWiner();
                }
                else if (hit.transform.name == tictactoeBatton01.name && tictactoeArray[0, 1] == "?")
                {
                    if (round % 2 == 0)
                    {
                        tictactoeArray[0, 1] = "X";
                        round++;
                        Instantiate(X, new Vector3(tictactoeBatton01.transform.position.x, tictactoeBatton01.transform.position.y, tictactoeBatton01.transform.position.z), Quaternion.identity);

                    }
                    else
                    {
                        tictactoeArray[0, 1] = "O";
                        round++;
                        Instantiate(O, new Vector3(tictactoeBatton01.transform.position.x, tictactoeBatton01.transform.position.y, tictactoeBatton01.transform.position.z), Quaternion.identity);
                    }
                    checkWiner();
                }
                else if (hit.transform.name == tictactoeBatton02.name && tictactoeArray[0, 2] == "?")
                {
                    if (round % 2 == 0)
                    {
                        tictactoeArray[0, 2] = "X";
                        round++;
                        Instantiate(X, new Vector3(tictactoeBatton02.transform.position.x, tictactoeBatton02.transform.position.y, tictactoeBatton02.transform.position.z), Quaternion.identity);

                    }
                    else
                    {
                        tictactoeArray[0, 2] = "O";
                        round++;
                        Instantiate(O, new Vector3(tictactoeBatton02.transform.position.x, tictactoeBatton02.transform.position.y, tictactoeBatton02.transform.position.z), Quaternion.identity);
                    }
                    checkWiner();
                }
                else if (hit.transform.name == tictactoeBatton10.name && tictactoeArray[1, 0] == "?")
                {
                    if (round % 2 == 0)
                    {
                        tictactoeArray[1, 0] = "X";
                        round++;
                        Instantiate(X, new Vector3(tictactoeBatton10.transform.position.x, tictactoeBatton10.transform.position.y, tictactoeBatton10.transform.position.z), Quaternion.identity);

                    }
                    else
                    {
                        tictactoeArray[1, 0] = "O";
                        round++;
                        Instantiate(O, new Vector3(tictactoeBatton10.transform.position.x, tictactoeBatton10.transform.position.y, tictactoeBatton10.transform.position.z), Quaternion.identity);
                    }
                    checkWiner();
                }
                else if (hit.transform.name == tictactoeBatton11.name && tictactoeArray[1, 1] == "?")
                {
                    if (round % 2 == 0)
                    {
                        tictactoeArray[1, 1] = "X";
                        round++;
                        Instantiate(X, new Vector3(tictactoeBatton11.transform.position.x, tictactoeBatton11.transform.position.y, tictactoeBatton11.transform.position.z), Quaternion.identity);

                    }
                    else
                    {
                        tictactoeArray[1, 1] = "O";
                        round++;
                        Instantiate(O, new Vector3(tictactoeBatton11.transform.position.x, tictactoeBatton11.transform.position.y, tictactoeBatton11.transform.position.z), Quaternion.identity);
                    }
                    checkWiner();
                }
                else if (hit.transform.name == tictactoeBatton12.name && tictactoeArray[1, 2] == "?")
                {
                    if (round % 2 == 0)
                    {
                        tictactoeArray[1, 2] = "X";
                        round++;
                        Instantiate(X, new Vector3(tictactoeBatton12.transform.position.x, tictactoeBatton12.transform.position.y, tictactoeBatton12.transform.position.z), Quaternion.identity);

                    }
                    else
                    {
                        tictactoeArray[1, 2] = "O";
                        round++;
                        Instantiate(O, new Vector3(tictactoeBatton12.transform.position.x, tictactoeBatton12.transform.position.y, tictactoeBatton12.transform.position.z), Quaternion.identity);
                    }
                    checkWiner();
                }
                else if (hit.transform.name == tictactoeBatton20.name && tictactoeArray[2, 0] == "?")
                {
                    if (round % 2 == 0)
                    {
                        tictactoeArray[2, 0] = "X";
                        round++;
                        Instantiate(X, new Vector3(tictactoeBatton20.transform.position.x, tictactoeBatton20.transform.position.y, tictactoeBatton20.transform.position.z), Quaternion.identity);

                    }
                    else
                    {
                        tictactoeArray[2, 0] = "O";
                        round++;
                        Instantiate(O, new Vector3(tictactoeBatton20.transform.position.x, tictactoeBatton20.transform.position.y, tictactoeBatton20.transform.position.z), Quaternion.identity);
                    }
                    checkWiner();
                }
                else if (hit.transform.name == tictactoeBatton21.name && tictactoeArray[2, 1] == "?")
                {
                    if (round % 2 == 0)
                    {
                        tictactoeArray[2, 1] = "X";
                        round++;
                        Instantiate(X, new Vector3(tictactoeBatton21.transform.position.x, tictactoeBatton21.transform.position.y, tictactoeBatton21.transform.position.z), Quaternion.identity);

                    }
                    else
                    {
                        tictactoeArray[2, 1] = "O";
                        round++;
                        Instantiate(O, new Vector3(tictactoeBatton21.transform.position.x, tictactoeBatton21.transform.position.y, tictactoeBatton21.transform.position.z), Quaternion.identity);
                    }
                    checkWiner();
                }
                else if (hit.transform.name == tictactoeBatton22.name && tictactoeArray[2, 2] == "?")
                {
                    if (round % 2 == 0)
                    {
                        tictactoeArray[2, 2] = "X";
                        round++;
                        Instantiate(X, new Vector3(tictactoeBatton22.transform.position.x, tictactoeBatton22.transform.position.y, tictactoeBatton22.transform.position.z), Quaternion.identity);

                    }
                    else
                    {
                        tictactoeArray[2, 2] = "O";
                        round++;
                        Instantiate(O, new Vector3(tictactoeBatton22.transform.position.x, tictactoeBatton22.transform.position.y, tictactoeBatton22.transform.position.z), Quaternion.identity);
                    }
                    checkWiner();
                }



            }
        }
    }
     
    public void checkWiner() { 
        if ((tictactoeArray[0, 0] == "O" && tictactoeArray[0, 1] == "O" && tictactoeArray[0, 2] == "O")
            || (tictactoeArray[1, 0] == "O" && tictactoeArray[1, 1] == "O" && tictactoeArray[1, 2] == "O")
            || (tictactoeArray[2, 0] == "O" && tictactoeArray[2, 1] == "O" && tictactoeArray[2, 2] == "O")
            || (tictactoeArray[0, 0] == "O" && tictactoeArray[1, 0] == "O" && tictactoeArray[2, 0] == "O")
            || (tictactoeArray[0, 1] == "O" && tictactoeArray[1, 1] == "O" && tictactoeArray[2, 1] == "O")
            || (tictactoeArray[0, 2] == "O" && tictactoeArray[1, 2] == "O" && tictactoeArray[2, 2] == "O")
            || (tictactoeArray[0, 0] == "O" && tictactoeArray[1, 1] == "O" && tictactoeArray[2, 2] == "O")
            || (tictactoeArray[0, 2] == "O" && tictactoeArray[1, 1] == "O" && tictactoeArray[2, 0] == "O")
            ) 
        {
            playAgainButtonObj.SetActive(true);
            message.enabled = true;
            message.text = "Winer is O";
            gameEnd = true;
        }
        else if((tictactoeArray[0, 0] == "X" && tictactoeArray[0, 1] == "X" && tictactoeArray[0, 2] == "X")
            || (tictactoeArray[1, 0] == "X" && tictactoeArray[1, 1] == "X" && tictactoeArray[1, 2] == "X")
            || (tictactoeArray[2, 0] == "X" && tictactoeArray[2, 1] == "X" && tictactoeArray[2, 2] == "X")
            || (tictactoeArray[0, 0] == "X" && tictactoeArray[1, 0] == "X" && tictactoeArray[2, 0] == "X")
            || (tictactoeArray[0, 1] == "X" && tictactoeArray[1, 1] == "X" && tictactoeArray[2, 1] == "X")
            || (tictactoeArray[0, 2] == "X" && tictactoeArray[1, 2] == "X" && tictactoeArray[2, 2] == "X")
            || (tictactoeArray[0, 0] == "X" && tictactoeArray[1, 1] == "X" && tictactoeArray[2, 2] == "X")
            || (tictactoeArray[0, 2] == "X" && tictactoeArray[1, 1] == "X" && tictactoeArray[2, 0] == "X"))
        {
            playAgainButtonObj.SetActive(true);
            message.enabled = true;
            message.text = "Winer is X";
            gameEnd = true;
        }
        else if (round == 9)
        {
            playAgainButtonObj.SetActive(true);
            message.enabled = true;
            message.text = "No winer";
            gameEnd = true;
        }


    }

    public void playAgain() {
        tictactoeArray = new string[,]{ { "?", "?", "?" },
                                                     { "?", "?", "?" },
                                                     { "?", "?", "?" } };
        round = 0;
        message.enabled = false;
        playAgainButtonObj.SetActive(false);
        gameEnd = false;
        GameObject[] delObj = GameObject.FindGameObjectsWithTag("X");
        foreach(GameObject obj in delObj) 
        {
            Destroy(obj);
        }
        delObj = GameObject.FindGameObjectsWithTag("O");
        foreach (GameObject obj in delObj)
        {
            Destroy(obj);
        }
    }
}

Ответы (0 шт):