Как реализовать алгоритм 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);
}
}
}