Я программирую тиктактое 5х5.
Я получаю неожиданную ошибку времени выполнения, которая возвращает ROW / COL больше 4.
Играет за игрока:
Игрок: 3,3
Компьютер: 0,0
Игрок: 1,3
Компьютер: 0,3
Игрок: 3,1
Компьютер: 0,1
Игрок: 0,2
Компьютер: 140735274172144, 4204747 <- после блокировки шансов на выигрыш компьютера моя таблица транспонирования генерирует это как лучший ход.
Мой код:
void doCompMove(TicTacToe& t, bool firstMove) {
TicTacToe::row_index bestRow;
TicTacToe::column_index bestCol;
#ifndef ANALYSE
static int gameNum(0);
if (!(firstMove))
#else
Stopwatch sw;
sw.start();
#endif
t.clearTrans();
t.chooseMove(TicTacToe::COMPUTER, bestRow, bestCol);
#ifndef ANALYSE
else {
bestRow=gameNum%5;
bestCol=(gameNum/5)%5;
++gameNum;
}
#else
sw.stop();
//if(bestRow > 4) bestRow=rand()%5;
//if(bestCol > 4) bestCol=rand()%5;
cout<<"Tijdsduur: "<<sw<<endl;
cout<<"Transposition table size is: "<<t.getTransSize()<<endl;
cout<<"Moves considered: "<<t.getAndResetMovesConsidered()<<endl;
#endif
cout<<"Computer plays: ROW = "<<bestRow<<" COL = "<<bestCol<<endl;
t.playMove(TicTacToe::COMPUTER, bestRow, bestCol);
}
Это функция chooseMove:
TicTacToe::PositionVal TicTacToe::chooseMove(Side s, row_index& bestRow, column_index& bestColumn,
PositionVal alpha, PositionVal beta, int depth) {
#ifdef ANALYSE
++movesConsidered;
#endif
static const int MAX_TABLE_DEPTH(5); //7
static const int MIN_TABLE_DEPTH(3); //5
if(depth>MAX_TABLE_DEPTH)
return UNCLEAR;
Position thisPosition(board);
if (depth>=MIN_TABLE_DEPTH && depth<=MAX_TABLE_DEPTH) {
MapItr itr(transpositions.find(thisPosition));
if (itr!=transpositions.end())
return (*itr).second;
}
Side opp(s==COMPUTER ? HUMAN : COMPUTER);
PositionVal simpleEval(positionValue());
if (simpleEval!=UNCLEAR)
return simpleEval;
PositionVal bestValue(s==COMPUTER ? alpha : beta);
for (row_index row(0); alpha<beta && row<board.numrows(); ++row)
for (column_index column(0); alpha<beta && column<board.numcols(); ++column)
if (squareIsEmpty(row, column)) {
place(row, column, s);
row_index dr;
column_index dc;
PositionVal reply(chooseMove(opp, dr, dc, alpha, beta, depth+1));
place(row, column, EMPTY);
if (s==COMPUTER && reply>bestValue || s==HUMAN && reply<bestValue) {
bestValue=reply;
if (s==COMPUTER)
alpha=bestValue;
else
beta=bestValue;
bestRow=row;
bestColumn=column;
}
}
if (depth>=MIN_TABLE_DEPTH && depth<=MAX_TABLE_DEPTH) {
transpositions[thisPosition]=bestValue;
}
return bestValue;
}
Возможно ли, чтобы таблица транспонирования достигла максимального размера?
MapItr itr(transpositions.find(thisPosition));
if (itr!=transpositions.end())
return (*itr).second;
Похоже, ваш код имеет путь, который не выбирает движение. Таким образом, вы получите результат мусора.
Это легко определить, просто измените следующее:
void doCompMove(TicTacToe& t, bool firstMove) {
TicTacToe::row_index bestRow = -1;
TicTacToe::column_index bestCol = -1;
И посмотри, какой у тебя будет результат.
После этого вам нужно найти дыру в логике.
Других решений пока нет …