我正在使用minimax编写Connect 4游戏,但我的下一步检查功能有时会给我意想不到的结果。你能告诉我我的算法是否正确吗?
例如,如果我的电路板看起来像这样
0000000
0000000
0000000
0000000
1000000
2002120
对于玩家2,它将返回0列为真。
bool Board::check2(int player, int& bestMove)
{
for (int i=0; i<WIDTH; i++)
{
if(addToColumn(i, player))
{
if (checkNext(2, i, player))
{
bestMove=i;
removeFromColumn(i, player);
return true;
}
removeFromColumn(i, player);
}
}
return false;
}
bool Board::checkNextVertical(int size, int column, int player1)
{
int counter=0;
int player2;
if (player1==1)
{
player2=2;
}
else
player2=1;
for (int i=0 ; i<DEPTH; i++)
{
if (arrBoard[column][i]==player1)
{
counter++;
}
if (arrBoard[column][i]==player2)
{
return false;
}
if (counter==size)
{
return true;
}
}
return false;
}
bool Board::checkNextHorizontal(int size, int column, int player1)
{
int counter=0;
int player2;
if (player1==1)
{
player2=2;
}
else
player2=1;
for (int i=0 ; i<DEPTH; i++)
{
if (arrBoard[i][column]==player1)
{
for (int j = 0; j<WIDTH; j++)
{
if (arrBoard[i][j]==player1)
{
counter++;
}
if (arrBoard[i][j]!=player1)
{
counter=0;
}
if (counter==size)
{
return true;
}
}
}
}
return false;
}
bool Board::checkNext(int size, int column, int player)
{
if (checkNextVertical(size, column, player))
{
// printBoard();
return true;
}
if (checkNextHorizontal(size, column, player))
{
// printBoard();
return true;
}
return false;
}
答案 0 :(得分:0)
欢迎来到论坛。
您发布的代码存在一些问题:
您的checkNextVertical
功能似乎正在尝试水平检查,而checkNextHorizontal
功能似乎试图水平和垂直检查。
如果您发现同时使用arrBoard[column][i]
和arrBoard[i][column]
。我相信你会同意其中只有一个是正确的。了解哪个是正确的很重要,否则您的代码最终会尝试访问数组中无效的位置,并且您会遇到意外行为,例如j
中的checkNextHorizontal
循环功能目前正在这样做。
它应该用作array[y / depth / row][x / width / column]
- 或者你将要记住的任何东西。
就个人而言,这段代码似乎令人困惑:
int player2;
if (player1==1)
{
player2=2;
}
else
player2=1;
player2=1
似乎试图在圆孔中推一个方形钉。您可以使用int player
并将其设置为1
或2
以便于阅读吗?
我完全赞同Joachim - 如果你遇到这些问题,那么用数据填充数组总是一个好主意,然后使用调试器逐步执行代码并检查所访问的数据是否是你的数据期待被访问。
或者,因为它是一个connect4游戏,我假设在某些时候你知道最后一次移动的列,在这种情况下你可以使用这个功能来检查它是否是一个获胜的举动。你只需要告诉它最后一步是哪一列,以及赢得所需的“大小”。如果您确实使用它,我仍然建议您使用调试器逐步执行它,以便您可以了解阵列访问。注意:你的代码没有对角检查 - 所以这也不是。如果你想这样做,需要一些额外的逻辑:
bool winningMove(int column, int size)
{
bool winnerWinnerChickenDinner = false;
int player = 0;
int row = 0;
// Who was the last player to go in this column
// i.e. find the top non-zero entry
for (int i = 0; i < DEPTH; i++)
{
if (arrBoard[i][column] != 0)
{
player = arrBoard[i][column];
row = i;
break;
}
}
// If we found a player, check if it was a winning move
if (player != 0)
{
int count = 0;
// Loop twice, first horizontally, then vertically
for (int i = 0; i < 2 && !winnerWinnerChickenDinner; i++)
{
bool horizontal = (i == 0);
for (int j = 0; j < (horizontal ? WIDTH : DEPTH); j++)
{
// Check if we have 'size' consecutive entries by the same player
// (When we check horizontally, use arrBoard[row][j] to check the row)
// (When we check vertically, use arrBoard[j][column] to check the column)
if (arrBoard[(horizontal ? row : j)][(horizontal ? j : column)] == player)
{
if (++count == size)
{
winnerWinnerChickenDinner = true;
break;
}
}
else
{
count = 0;
}
}
}
}
return winnerWinnerChickenDinner;
}
旧游戏是最好的 - Connect4很棒,祝你好运。