[fix] Non heuristic moves...
This commit is contained in:
+47
-4
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user