
Алгоритм MiniMax
int MiniMax(TPlaying_Field* field, int depth, bool isMaximizing, CellState currentPlayer) {
// Терминальные условия
if (depth == 0 || CheckWin(field, PLAYER1) || CheckWin(field, PLAYER2)) {
return Evaluation(field);
}
auto moves = GenerateMoves(field, currentPlayer);
if (moves.empty()) return Evaluation(field);
if (isMaximizing) {
int maxEval = std::numeric_limits<int>::min();
for (const auto& move : moves) {
TPlaying_Field newField = *field;
// Пытаемся найти фишку для перемещения
bool moved = false;
for (int i = 0; i < NUM_ROWS && !moved; ++i) {
for (int j = 0; j < NUM_COLS && !moved; ++j) {
if (newField.board[i][j] == currentPlayer) {
if (abs(i - move.first) <= 1 && abs(j - move.second) <= 1) {
MakeMove(&newField, i, j, move.first, move.second, currentPlayer);
moved = true;
}
}
}
}
// Если не нашли фишку для перемещения - ставим новую
if (!moved) {
newField.board[move.first][move.second] = currentPlayer;
CaptureOpponentPieces(move.first, move.second, currentPlayer, &newField);
}
int eval = MiniMax(&newField, depth - 1, false, (currentPlayer == PLAYER1) ? PLAYER2 : PLAYER1);
maxEval = std::max(maxEval, eval);
}
return maxEval;
}
else {
int minEval = std::numeric_limits<int>::max();
for (const auto& move : moves) {
TPlaying_Field newField = *field;
bool moved = false;
for (int i = 0; i < NUM_ROWS && !moved; ++i) {
for (int j = 0; j < NUM_COLS && !moved; ++j) {
if (newField.board[i][j] == currentPlayer) {
if (abs(i - move.first) <= 1 && abs(j - move.second) <= 1) {
MakeMove(&newField, i, j, move.first, move.second, currentPlayer);
moved = true;
}
}
}
}
if (!moved) {
newField.board[move.first][move.second] = currentPlayer;
CaptureOpponentPieces(move.first, move.second, currentPlayer, &newField);
}
int eval = MiniMax(&newField, depth - 1, true, (currentPlayer == PLAYER1) ? PLAYER2 : PLAYER1);
minEval = std::min(minEval, eval);
}
return minEval;
}
}
Параметры:
field — текущее состояние поля.
depth — глубина рекурсии (уменьшается с каждым уровнем).
isMaximizing — фаз максимизации (ИИ) или минимизации (игрок).
currentPlayer — текущий игрок (PLAYER1 или PLAYER2).
Логика работы:
Терминальные условия:
Если depth = 0 или найдена победа/поражение — возвращает оценку поля.
Генерация ходов:
Для каждого возможного хода создает копию поля и делает ход.
Рекурсивный вызов:
Для ИИ (isMaximizing = true) выбирает ход с максимальной оценкой.
Для игрока (isMaximizing = false) — с минимальной.
Возвращает: Лучшую оценку для текущего состояния поля.