[fix] Non heuristic moves...

This commit is contained in:
2026-03-27 12:17:25 +01:00
parent 223fc91b19
commit 025f0457c7
16 changed files with 1157 additions and 7 deletions
+47 -4
View File
@@ -121,6 +121,7 @@ bool checkGameEnd();
void updateThinkingVisuals(int8_t pColor, int8_t column);
void animateDrop(int col, int player);
void moveDiscToCol(int startCol, int targetCol, int player, int speed);
int evaluateBoard(int8_t aiP, int8_t huP);
int minimax(int depth, int alpha, int beta, bool isMax, int8_t aiP, int8_t huP, int8_t rootCol);
void performAiMove(int8_t aiP);
void randomizeDemoPlies();
@@ -265,6 +266,39 @@ int8_t scanBoard() {
return 0;
}
int evaluateBoard(int8_t aiP, int8_t huP) {
int score = 0;
// Center column bonus
for (int r = 0; r < ROWS; r++) {
if (board[3][r] == aiP) score += 3;
else if (board[3][r] == huP) score -= 3;
}
// Score a window of 4 cells by piece counts
auto scoreWindow = [&](int c, int r, int dc, int dr) -> int {
int ai = 0, hu = 0;
for (int i = 0; i < 4; i++) {
int8_t v = board[c + i * dc][r + i * dr];
if (v == aiP) ai++;
else if (v == huP) hu++;
}
if (ai > 0 && hu > 0) return 0;
if (ai == 3) return 50;
if (ai == 2) return 5;
if (hu == 3) return -50;
if (hu == 2) return -5;
return 0;
};
for (int r = 0; r < 6; r++) for (int c = 0; c < 4; c++) score += scoreWindow(c, r, 1, 0);
for (int r = 0; r < 3; r++) for (int c = 0; c < 7; c++) score += scoreWindow(c, r, 0, 1);
for (int r = 0; r < 3; r++) for (int c = 0; c < 4; c++) score += scoreWindow(c, r, 1, 1);
for (int r = 3; r < 6; r++) for (int c = 0; c < 4; c++) score += scoreWindow(c, r, 1, -1);
return score;
}
bool checkGameEnd() {
winnerPlayer = scanBoard();
bool won = winnerPlayer != 0;
@@ -331,7 +365,7 @@ int minimax(int depth, int alpha, int beta, bool isMax, int8_t aiP, int8_t huP,
int8_t win = scanBoard();
if (win == aiP) return 1000 + depth;
if (win == huP) return -1000 - depth;
if (depth == 0 || isBoardFull()) return 0;
if (depth == 0 || isBoardFull()) return evaluateBoard(aiP, huP);
int best = isMax ? -10000 : 10000;
for (int c : colOrder) {
@@ -356,13 +390,22 @@ void performAiMove(int8_t aiP) {
int originalPly = currentLookAhead;
if (gameState == DEMO) currentLookAhead = demoPly[aiP - 1];
// Phase 1: always take an instant win or block an opponent's win
// Phase 1a: check ALL columns for instant AI win
bool found = false;
for (int c = 0; c < COLS && !found; c++) {
int r = getFirstEmptyRow(c);
if (r != -1) {
board[c][r] = aiP; if (scanBoard() == aiP) { board[c][r]=0; bestCol=c; found=true; break; }
board[c][r] = huP; if (scanBoard() == huP) { board[c][r]=0; bestCol=c; found=true; break; }
board[c][r] = aiP;
if (scanBoard() == aiP) { board[c][r] = 0; bestCol = c; found = true; break; }
board[c][r] = 0;
}
}
// Phase 1b: check ALL columns for opponent block
for (int c = 0; c < COLS && !found; c++) {
int r = getFirstEmptyRow(c);
if (r != -1) {
board[c][r] = huP;
if (scanBoard() == huP) { board[c][r] = 0; bestCol = c; found = true; break; }
board[c][r] = 0;
}
}