В настоящее время я работаю над игрой Othello / Reversi на C ++. У меня это «закончено», за исключением того, что алгоритм Minimax, который я использую для компьютерного игрока, очень медленный, когда я устанавливаю его на глубину, которая создает полусложный ИИ.
Базовая настройка моей игры такова, что доска представлен двумерным массивом, в котором каждой ячейке на доске присвоено значение в массиве ( xMarker
, oMarker
или подчеркивание
).
Вот алгоритм минимакса на данный момент:
signed int Computer::simulate(Board b, int depth, int tempMarker) {
if (depth > MAX_DEPTH || b.gameOver()) {
int oppMarker = (marker == xMarker) ? oMarker : xMarker;
return b.countForMarker(marker) - b.countForMarker(oppMarker);
}
//if we're simulating our turn, we want to find the highest value (so we set our start at -64)
//if we're simulating the opponent's turn, we want to find the lowest value (so we set our start at 64)
signed int start = (tempMarker == marker) ? -64 : 64;
for (int x = 0; x < b.size; x++) {
for (int y = 0; y < b.size; y++) {
if (b.markerArray[x][y] == underscore) {
Board *c = b.duplicate();
if(c->checkForFlips(Point(x,y), tempMarker, true) > 0) {
int newMarker = (tempMarker == xMarker) ? oMarker : xMarker;
int r = simulate(*c, depth+1, newMarker);
//'marker' is the marker assigned to our player (the computer), if it's our turn, we want the highest value
if (tempMarker == marker) {
if(r > start) start = r;
} else {
//if it's the opponent's turn, we want the lowest value
if(r < start) start = r;
}
}
delete c;
}
}
}
return start;
}
Функция checkForFlips ()
возвращает количество флипов, которые могут возникнуть в результате воспроизведения в данной ячейке. MAX_DEPTH на данный момент установлен на 6, и это довольно медленно (может быть, около 10-15 секунд на игру)
Единственная идея, которую я придумал до сих пор, - это сохранять дерево каждый раз, а затем поднимать с того места, где я остановился, но я не уверен, как это реализовать, и будет ли это слишком эффективно. Мы будем благодарны за любые идеи или предложения!