因此,我的井字游戏的AI出现了一些问题。 AI纯粹是防御性的,因此它将始终阻止您。通常在我的第一种情况下就可以正常工作,因此例如,如果我演奏左上角,然后演奏中上角,则它将始终占据右上角。其他情况,例如如果我打两条对角线,可能会冻结游戏,或者让我再转一圈。这些问题只有在我实施了错误的智能AI之后才出现。最初,该程序具有一个“哑AI”,可以选择随机点,如代码底部所示。而且,我认为问题在于某些阻塞条件可能彼此冲突并引起问题。我怎样才能解决这个问题?相关代码如下:
坐标基于井字格网,其中左上角为(0,0),右下角为(2,2)
void Game::AIGetNextMoveRand()
{
//top row
if(GetSquareState(0,0) == O && GetSquareState(1,0) == O)
{
do
{
AIMoveX = 2;
AIMoveY = 0;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
else if(GetSquareState(2,0) == O && GetSquareState(1,0) == O)
{
do
{
AIMoveX = 0;
AIMoveY = 0;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
//middle row
else if(GetSquareState(0,1) == O && GetSquareState(1,1) == O)
{
do
{
AIMoveX = 2;
AIMoveY = 1;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
else if(GetSquareState(2,1) == O && GetSquareState(1,1) == O)
{
do
{
AIMoveX = 0;
AIMoveY = 1;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
// bottom row
else if(GetSquareState(0,2) == O && GetSquareState(1,2) == O)
{
do
{
AIMoveX = 2;
AIMoveY = 2;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
else if(GetSquareState(2,2) == O && GetSquareState(1,2) == O)
{
do
{
AIMoveX = 0;
AIMoveY = 2;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
// vert 0
else if(GetSquareState(0,0) == O && GetSquareState(0,1) == O)
{
do
{
AIMoveX = 0;
AIMoveY = 2;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
else if(GetSquareState(0,2) == O && GetSquareState(0,1) == O)
{
do
{
AIMoveX = 0;
AIMoveY = 0;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
// vert 1
else if(GetSquareState(1,0) == O && GetSquareState(1,1) == O)
{
do
{
AIMoveX = 1;
AIMoveY = 2;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
else if(GetSquareState(1,2) == O && GetSquareState(1,1) == O)
{
do
{
AIMoveX = 1;
AIMoveY = 0;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
//vert 2
else if(GetSquareState(2,2) == O && GetSquareState(2,1) == O)
{
do
{
AIMoveX = 2;
AIMoveY = 0;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
else if(GetSquareState(2,0) == O && GetSquareState(2,1) == O)
{
do
{
AIMoveX = 2;
AIMoveY = 2;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
// diagonal 1
else if(GetSquareState(0,0) == O && GetSquareState(1,1) == O)
{
do
{
AIMoveX = 2;
AIMoveY = 2;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
else if(GetSquareState(2,2) == O && GetSquareState(1,1) == O)
{
do
{
AIMoveX = 0;
AIMoveY = 0;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
//diagonal 2
else if(GetSquareState(0,2) == O && GetSquareState(1,1) == O)
{
do
{
AIMoveX = 0;
AIMoveY = 2;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
else if(GetSquareState(0,2) == O && GetSquareState(1,1) == O)
{
do
{
AIMoveX = 2;
AIMoveY = 0;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
// mid 0
else if(GetSquareState(0,0) == O && GetSquareState(2,0) == O)
{
do
{
AIMoveX = 1;
AIMoveY = 0;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
//mid 1
else if(GetSquareState(1,0) == O && GetSquareState(2,1) == O)
{
do
{
AIMoveX = 1;
AIMoveY = 1;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
// mid 2
else if(GetSquareState(0,2) == O && GetSquareState(2,2) == O)
{
do
{
AIMoveX = 1;
AIMoveY = 2;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
//diag 1
else if(GetSquareState(0,0) == O && GetSquareState(2,2) == O)
{
do
{
AIMoveX = 1;
AIMoveY = 1;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
//diag 2
else if(GetSquareState(2,0) == O && GetSquareState(0,2) == O)
{
do
{
AIMoveX = 1;
AIMoveY = 1;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
else
{
do
{
AIMoveX = rand() % 3;
AIMoveY = rand() % 3;
}while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
}
void Game::DoAITurnRand()
{
AIGetNextMoveRand();
SetSquareState(AIMoveX,AIMoveY,activePlayer);
EndTurn();
}
最佳答案
do while循环是垃圾。考虑一下您的规则是否做出了错误的选择(即尝试在实心方块上进行游戏),然后再次做出相同的错误选择将无济于事。实际上,这就是为什么您获得“冻结”的原因。您需要重新组织代码的逻辑。我建议,如果您的AI选择了一个非法的正方形,那么您应该退回到您的随机选择代码,那么至少您会得到合法的举动。
像这样
// no move selected yet
AIMoveX = -1;
AIMoveY = -1;
// AI rules
if(GetSquareState(0,0) == O && GetSquareState(1,0) == O)
{
AIMoveX = 2;
AIMoveY = 0;
}
else if(GetSquareState(2,0) == O && GetSquareState(1,0) == O)
{
AIMoveX = 0;
AIMoveY = 0;
}
// lots more rules
...
// check for fallback to random move
if ((AIMoveX == -1 && AIMoveY == -1) // if no rules applied
|| GetSquareState(AIMoveX,AIMoveY) != EMPTY) // or if the square is not empty
{
// pick a random square
do
{
AIMoveX = rand() % 3;
AIMoveY = rand() % 3;
}
while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}
我最初将AIMoveX和AIMoveY设置为-1,以指示尚未选择任何规则。如果在通过所有规则后它们仍然为-1,那么我知道没有选择任何规则,因此我必须做出随机选择。如果确实选择了一条规则,但它选择了一个非空的正方形,那么我也会做出随机选择。我在代码末尾测试了这两个条件。
您必须仔细考虑所编写的代码的实际作用。仅将do while循环放在一个地方,因为它在另一个地方工作是不正确的。
关于c++ - C++井字游戏的AI问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15858844/