我正在尝试实现MiniMax以创建TicTacToe AI。我正在使用C#和Unity。我正在关注CodingTrain's video。该教程使用JavaScript,但是我遵循C#。我曾尝试从他的网站查看MiniMax代码,但无法弄清楚为什么我的“翻译”无效:
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public SpriteRenderer[] sprites;
char[] board = new char[] { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
Dictionary<char, Color> boardColor = new Dictionary<char, Color>()
{
{ ' ', Color.white },
{ 'O', Color.red },
{ 'X', Color.blue }
};
char ai = 'O';
char player = 'X';
Camera cam;
bool gameOver = false;
bool playerTurn;
private void Awake()
{
playerTurn = Random.value > .5f;
cam = Camera.main;
}
private void Start()
{
DrawBoard();
}
private void Update()
{
if (gameOver) return;
if (playerTurn)
PlayerMove();
else
CompMove();
DrawBoard();
if (IsWinner(player))
{
print("Good job, you won!");
gameOver = true;
}
else if (IsWinner(ai))
{
print("Too bad, you lost!");
gameOver = true;
}
else if (BoardIsFull())
{
print("Close one, it's a tie!");
gameOver = true;
}
}
void PlayerMove()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit2D hit = Physics2D.Raycast(cam.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (hit)
{
int pos = hit.transform.GetComponent<SpritePos>().pos;
if (SpaceIsFree(pos))
{
InsertLetter(player, pos);
playerTurn = false;
}
}
}
}
void CompMove()
{
float bestScore = -Mathf.Infinity;
int bestMove = 0;
for (int i = 0; i < board.Length; i++)
if(SpaceIsFree(i))
{
board[i] = ai;
float score = Minimax(board, 0, false);
board[i] = ' ';
bestScore = Mathf.Max(score, bestScore);
bestMove = i;
}
InsertLetter(ai, bestMove);
playerTurn = true;
}
float Minimax(char[] board, int depth, bool isMaximizer)
{
if (IsWinner(ai))
return 1;
if (IsWinner(player))
return -1;
if (BoardIsFull())
return 0;
if (isMaximizer)
{
float bestScore = -Mathf.Infinity;
for (int i = 0; i < board.Length; i++)
{
if (SpaceIsFree(i))
{
board[i] = ai;
float score = Minimax(board, depth + 1, false);
board[i] = ' ';
bestScore = Mathf.Max(score, bestScore);
}
}
return bestScore;
}
else
{
float bestScore = Mathf.Infinity;
for (int i = 0; i < board.Length; i++)
{
if (SpaceIsFree(i))
{
board[i] = player;
float score = Minimax(board, depth + 1, true);
board[i] = ' ';
bestScore = Mathf.Min(score, bestScore);
}
}
return bestScore;
}
}
void InsertLetter(char letter, int pos)
{
board[pos] = letter;
}
bool SpaceIsFree(int pos)
{
return board[pos] == ' ';
}
bool IsWinner(char letter)
{
return (board[0] == letter && board[1] == letter && board[2] == letter) ||
(board[4] == letter && board[5] == letter && board[6] == letter) ||
(board[0] == letter && board[1] == letter && board[2] == letter) ||
(board[0] == letter && board[3] == letter && board[6] == letter) ||
(board[1] == letter && board[4] == letter && board[7] == letter) ||
(board[2] == letter && board[5] == letter && board[8] == letter) ||
(board[0] == letter && board[4] == letter && board[8] == letter) ||
(board[6] == letter && board[4] == letter && board[2] == letter);
}
void DrawBoard()
{
for (int i = 0; i < board.Length; i++)
sprites[i].color = boardColor[board[i]];
}
bool BoardIsFull()
{
foreach (char space in board)
if (space == ' ')
return false;
return true;
}
}
它似乎始于右下角,然后每次都向左走。
答案 0 :(得分:1)
如注释中所述,您没有考虑bestScore
,因此bestMove
始终只是循环后的最后一个空闲i
。
您可能宁愿做类似的事情(不必深入研究其余部分)
void CompMove()
{
float bestScore = -Mathf.Infinity;
int bestMove = 0;
for (int i = 0; i < board.Length; i++)
{
if(SpaceIsFree(i))
{
board[i] = ai;
float score = Minimax(board, 0, false);
board[i] = ' ';
if(score > bestScore)
{
bestScore = score;
bestMove = i;
}
}
}
InsertLetter(ai, bestMove);
playerTurn = true;
}