# 井字游戏的Minimax算法进入无穷递归循环

``````//The initial function that returns the optimal move for AI to execute.
public int[] GetMove()
{
int aBestScore = -mInfinity;
int[] aMoveInfo = new int[2];

SyncValues();
int aLength = mAIPosInfo.GetLength(0);
mBreakPoint = mBreakLimit;
int aTest = -1;

//Initial loop that tests the first move and gets into the recursion
for (int i = 0; i < aLength; i++)
{
for (int j = 0; j < aLength; j++)
{
aTest++;
if (mAIPosInfo[i, j].mFilledPiece == PieceId.Empty)
{
mAIPosInfo[i, j].mFilledPiece = mAIPiece;

int aScore = MiniMax(mAIPosInfo, 0, 0, 0, false, i, j);
mAIPosInfo[i, j].mFilledPiece = PieceId.Empty;

if (aScore > aBestScore)
{
aBestScore = aScore;
aMoveInfo[0] = i;
aMoveInfo[1] = j;
}

}
}
}

return aMoveInfo;
}

//The MINI MAX ALGORITHM
private int MiniMax(AIPosInfo[,] pPosInfo, int pDepth, bool pMaximizingPlayer, int pRowId, int pColId)
{

int aScore = CheckScore(pMaximizingPlayer, pPosInfo, pRowId, pColId);

if (pDepth >= mDepthLimit || aScore != -5) //-5 is value returned for still playing
{
return aScore;
}

//Maximizing player turn..the AI Turn!!!
if (pMaximizingPlayer)
{
int aMaxEval = -mInfinity;
int aLength = pPosInfo.GetLength(0);

for (int i = 0; i < aLength; i++)
{
for (int j = 0; j < aLength; j++)
{
if (pPosInfo[i, j].mFilledPiece == PieceId.Empty)
{
pPosInfo[i, j].mFilledPiece = mAIPiece;

int aEvalve = MiniMax(pPosInfo, pDepth + 1, false, i, j);

pPosInfo[i, j].mFilledPiece = PieceId.Empty;

aMaxEval = Mathf.Max(aEvalve, aMaxEval);

}
}
}
return aMaxEval;
}
else   //THE HUMAN PLAYER'S TURN
{
int aLength = pPosInfo.GetLength(0);
int aMinEval = mInfinity;

for (int i = 0; i < aLength; i++)
{
for (int j = 0; j < aLength; j++)
{
if (pPosInfo[i, j].mFilledPiece == PieceId.Empty)
{

pPosInfo[i, j].mFilledPiece = mHumanPiece;

int aEval = MiniMax(pPosInfo, pDepth + 1, true, i, j);

pPosInfo[i, j].mFilledPiece = PieceId.Empty;

aMinEval = Mathf.Min(aEval, aMinEval);

}

}
}
return aMinEval;

}
}
``````

CheckScore和CheckWin功能，字典具有此信息

``````    mScoreInfo.Add(PieceId.Cross, 1); //AI

private int CheckScore(bool pMaximizing, AIPosInfo[,] pPosInfo, int pRowId, int pColId)
{
PieceId aPieceId;
int aValue;
if (pMaximizing)
{
aPieceId = mAIPiece;
}
else
{
aPieceId = mHumanPiece;
}

PieceId aResult = CheckWin(pRowId, pColId, aPieceId, pPosInfo, true);

if (mScoreInfo.TryGetValue(aResult, out aValue))
{

return aValue;
}
else
{
Debug.LogError("Undefined Variable in PieceId enum");
return 0;
}

}

public PieceId CheckWin(int pRowId, int pColId, PieceId pPieceId, AIPosInfo[,] pPosArray, bool pAI)//The functionalities for the last parameter was removed because it wasn't needed.
{

var aPosArray = pPosArray;

bool aHorMatch = true;
bool aVerMatch = true;

for (int i = 0; i < BoardSetup.mInstance.mDegree; i++)
{

if (aPosArray[pRowId, i].mFilledPiece != pPieceId)
{
aHorMatch = false;
//Debug.LogError("Not Horizontal");
}

if (aPosArray[i, pColId].mFilledPiece != pPieceId)
{
aVerMatch = false;
//Debug.LogError("Not Vertical");
}

if (aPosArray[i, i].mFilledPiece != pPieceId)
{
//  Debug.LogError("Not Diagonal 1");
}

if (aPosArray[i, (BoardSetup.mInstance.mDegree - 1) - i].mFilledPiece != pPieceId)
{
//Debug.LogError("Not Diagonal 2");
}
}

if (aHorMatch ||
aVerMatch ||
{

return pPieceId;
}
else
{
var aBoardInfo = BoardSetup.mInstance.mPosInfo;
bool aCheckFill = true;
for (int i = 0; i < aBoardInfo.Count; i++)
{
if (aBoardInfo[i].mFilledPiece == PieceId.Empty)
{
aCheckFill = false;
}
}

if (aCheckFill)
{

Debug.Log("Game Tied");

return PieceId.Draw;
}
}

return PieceId.Playing;

}
``````