искусственный интеллект — Проблемы с ИИ для игры в крестики-нолики в Stack Overflow

Так что у меня есть несколько проблем с ИИ моей игры в крестики-нолики. ИИ должен быть чисто оборонительным, поэтому он всегда будет блокировать вас. Обычно это работает изначально с моим первым случаем, так что, например, если я играю верхний левый, то верхний средний, он всегда будет верхним правым. Другие случаи, например, если я играю на двух диагонали, могут заморозить игру или дать мне второй ход. Эти проблемы возникли только после того, как я реализовал свой неисправный умный ИИ. Первоначально у программы был «тупой ИИ», который выбирал случайные места, как вы увидите внизу кода. Более того, я думаю, что проблема в том, что некоторые из условий блокировки могут конфликтовать друг с другом и вызывать проблемы. Как я могу это исправить? Соответствующий код выглядит следующим образом:
Координаты основаны на сетке крестики-нолики, где верхний левый угол равен (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();
}

0

Решение

Циклы do while — это мусор. Подумайте об этом, если ваши правила сделали неправильный выбор (т. Е. Пытались играть на заполненном поле), а затем сделайте так же Неправильный выбор снова не поможет. На самом деле, именно поэтому вы получаете «заморозки». Вам нужно реорганизовать логику вашего кода. Я бы посоветовал, что если ваш ИИ выберет недопустимый квадрат, вы должны вернуться к своему коду случайного выбора, тогда, по крайней мере, вы получите законный ход.

Что-то вроде этого

// 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 в одном месте, потому что он работал в другом месте, неправильно.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector