gpt4 book ai didi

c++ - C++ 井字游戏的 AI 问题

转载 作者:行者123 更新时间:2023-11-28 07:41:04 24 4
gpt4 key购买 nike

所以我的井字游戏的 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 循环是垃圾。想一想,如果您的规则做出了错误的选择(即尝试在填充的方 block 上进行游戏),那么再次做出相同的错误选择将无济于事。事实上,这就是你得到“卡住”的原因。您需要重新组织代码的逻辑。我建议,如果您的 AI 选择了一个非法方 block ,那么您应该回退到您的随机选择代码,那么至少您会得到一个合法的移动。

像这样

// 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,那么我知道没有选择任何规则,我必须随机选择。如果确实选择了一条规则,但它选择了一个非空方 block ,那么我也会随机选择。我在代码末尾测试了这两种情况。

您必须仔细考虑您编写的代码到底做了什么。只在一个地方放一个 do while 循环是不对的,因为它在另一个地方有效。

关于c++ - C++ 井字游戏的 AI 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15858844/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com