我正在尝试为连续四个(或 connect4 或连接四个)游戏实现 MinMax 算法。
我想我明白了,它应该建立一个有一定深度的可能板树,评估它们并返回它们的分数,然后我们只取这些分数的最大值。
因此,aiChooseCol()
通过调用检查每个可能列的分数MinMax()
并返回具有最高分数的列。
现在我不确定,这是正确的打电话方式MinMax()
吗?
检查是否正确temp = Math.Max(temp, 1000);
?
我还没有制作启发式函数,但这至少应该识别一个获胜的列并选择它,但目前它只是选择左边的第一个空闲列......我不知道我做错了什么。
private int AiChooseCol()
{
int best = -1000;
int col=0;
for (int i = 0; i < m_Board.Cols; i++)
{
if (m_Board.CheckIfColHasRoom(i))
{
m_Board.FillSignInBoardAccordingToCol(i, m_Sign);
int t = MinMax(5, m_Board, board.GetOtherPlayerSign(m_Sign));
if (t > best)
{
best = t;
col = i;
}
m_Board.RemoveTopCoinFromCol(i);
}
}
return col;
}
private int MinMax(int Depth, board Board, char PlayerSign)
{
int temp=0;
if (Depth <= 0)
{
// return from heurisitic function
return temp;
}
char otherPlayerSign = board.GetOtherPlayerSign(PlayerSign);
char checkBoard = Board.CheckBoardForWin();
if (checkBoard == PlayerSign)
{
return 1000;
}
else if (checkBoard == otherPlayerSign)
{
return -1000;
}
else if (!Board.CheckIfBoardIsNotFull())
{
return 0; // tie
}
if (PlayerSign == m_Sign) // maximizing Player is myself
{
temp = -1000;
for (int i = 0; i < Board.Cols; i++)
{
if (Board.FillSignInBoardAccordingToCol(i, PlayerSign)) // so we don't open another branch in a full column
{
var v = MinMax(Depth - 1, Board, otherPlayerSign);
temp = Math.Max(temp, v);
Board.RemoveTopCoinFromCol(i);
}
}
}
else
{
temp = 1000;
for (int i = 0; i < Board.Cols; i++)
{
if (Board.FillSignInBoardAccordingToCol(i, PlayerSign)) // so we don't open another branch in a full column
{
var v = MinMax(Depth - 1, Board, otherPlayerSign);
temp = Math.Min(temp, v);
Board.RemoveTopCoinFromCol(i);
}
}
}
return temp;
}
一些注意事项:
FillSignInBoardAccordingToCol()
如果成功则返回布尔值。
该board
类型有一个char[,]
包含实际棋盘和玩家标志的数组。
此代码在 AI Player 类中。