如何实现negamax的makemove功能
我现在正在unity3d的checkers游戏上工作。 我一直在尝试使用negamax算法在一段时间内实现单个玩家与人工智能。 negamax代码运行良好,但在克隆板上进行临时移动的功能正是遇到问题的地方。 我想知道如何做到这一点。
Negamax功能
private static int evalBoard(checkerMan[,] board, bool turn)
{
int whiteCount = 0;
int blackCount = 0;
int whoToMove;
if (turn = boardManager.Instance.isWhiteTurn)
{
whoToMove = -1;
}
else
{
whoToMove = 1;
}
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if(board[i, j]!=null)
if (board[i, j].isWhite)
{
whiteCount++;
}
else
{
blackCount++;
}
}
}
return (whiteCount - blackCount) * whoToMove;
}
public List<bool[,]> getAllValidMoves(checkerMan[,] checks, bool color)
{
List<bool[,]> validMoves = new List<bool[,]>();
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if(checks[i, j] != null && checks[i, j].isWhite==color)
{
if(checks[i, j].isForcedToMove())
{
if checks[i, j].isKing)
{
ArrayList a = checks[i, j].kingKillMoves(i,j);
validMoves.Add((bool[,])a[0]);
checks[i, j].setMove((bool[,])a[0]);
}
else
{
validMoves.Add(checks[i, j].KillMoves(i, j));
checks[i, j].setMove(checks[i, j].KillMoves(i, j));
}
}
else
{
if(checks[i, j].isKing)
{
validMoves.Add(checks[i, j].KingPossibleMove());
checks[i, j].setMove(checks[i, j].KingPossibleMove());
}
else
{
validMoves.Add(checks[i, j].possibleMove());
checks[i, j].setMove(checks[i, j].possibleMove());
}
}
}
}
}
return validMoves;
}
private static bool[,] GetBestMove(checkerMan[,] board, bool color,int depth)
{
aiPlaying = true;
int highestScore = int.MinValue;
checkerMan[,] tmp = boardManager.Instance.deppCopy(board);
List<bool[,]>validMoves=
boardManager.Instance.getAllValidMoves(tmp,color);
List<bool[,]> bestMove = new List<bool[,]>();
System.Random rand = new System.Random();
foreach (bool[,] b in validMoves)
{
boardManager.Instance.applyMoves(tmp, b, color);
int score = -NegaMax(tmp, !color, depth);
Debug.Log("score "+score+" highestScore "+highestScore);
if (score > highestScore)
{
bestMove.Clear();
highestScore = score;
bestMove.Add(b);
}
else if(score == highestScore)
{
bestMove.Add(b);
}
}
return bestMove[rand.Next(bestMove.Count)];
}
private static int NegaMax(checkerMan[,] board, bool color, int depth)
{
int highestScore = int.MinValue;
List<bool[,]> validMoves = boardManager.Instance.getAllValidMoves(board, color);
if (depth == 0 || validMoves==null)
{
return evalBoard(board,color);
}
foreach (bool[,] b in validMoves)
{
boardManager.Instance.applyMoves(board, b, color);
int score = -NegaMax(board, !color, depth - 1);
highestScore = Mathf.Max(highestScore, score);
}
return highestScore;
}
问题的功能是这样的:
public void applyMoves(checkerMan[,] board,bool[,] moves, bool color)
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if (moves[i, j])
{
for (int k = i; k < 8; k++)
{
for (int l = j; l < 8; l++)
{
if (board[k, l] != null && board[k, l].isWhite == color && board[k,l].moves[i, j] )
{
board[k, l].setPosition(i, j);
}
}
}
}
}
}
}
private checkerMan[,] deppCopy(checkerMan[,] original)
{
checkerMan[,] clone = new checkerMan[8, 8];
for (int k = 0; k < 8; k++)
{
for (int l = 0; l < 8; l++)
{
if(original[k, l]!= null)
{
clone[k, l] = (checkerMan)Instantiate(original[k, l]);
}
}
}
return clone;
}
需要注意的是,我的主板是一个8 * 8多维布尔类型的checkerMan数组
using UnityEngine;
using System.Collections;
public class checkerMan : MonoBehaviour
{
public bool isWhite;
public bool isKing;
public int CurrentX { set; get; }
public int CurrentY { set; get; }
public bool[,] moves { set; get; }
public void setPosition(int x, int y)
{
CurrentX = x;
CurrentY = y;
}
public void setMove(bool[,] move)
{
moves = move;
}
public virtual bool[,] possibleMove()
{
return new bool[8, 8];
}
public virtual bool isForcedToMove()
{
return false;
}
public virtual bool[,] KillMoves(int a, int b)
{
return new bool[8, 8];
}
public virtual bool[,] KingPossibleMove()
{
return new bool[8, 8];
}
public virtual ArrayList kingKillMoves(int i, int j)
{
return new ArrayList();
}
}
链接地址: http://www.djcxy.com/p/56359.html