[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
+54 -2
View File
@@ -166,12 +166,57 @@ function scanBoard(b) {
return [0, []];
}
function evaluateBoard(b, aiP, huP) {
let score = 0;
// Center column bonus
for (let r = 0; r < ROWS; r++) {
if (b[3][r] === aiP) score += 3;
else if (b[3][r] === huP) score -= 3;
}
// Score a window of 4 cells by piece counts
function scoreWindow(c, r, dc, dr) {
let ai = 0, hu = 0;
for (let i = 0; i < 4; i++) {
const v = b[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;
}
// Horizontal
for (let r = 0; r < ROWS; r++)
for (let c = 0; c <= COLS - 4; c++)
score += scoreWindow(c, r, 1, 0);
// Vertical
for (let r = 0; r <= ROWS - 4; r++)
for (let c = 0; c < COLS; c++)
score += scoreWindow(c, r, 0, 1);
// Diagonal up-right
for (let r = 0; r <= ROWS - 4; r++)
for (let c = 0; c <= COLS - 4; c++)
score += scoreWindow(c, r, 1, 1);
// Diagonal down-right
for (let r = 3; r < ROWS; r++)
for (let c = 0; c <= COLS - 4; c++)
score += scoreWindow(c, r, 1, -1);
return score;
}
// --- AI -----------------------------------------------------
function minimax(b, depth, alpha, beta, isMax, aiP, huP) {
const [winner] = scanBoard(b);
if (winner === aiP) return 1000 + depth;
if (winner === huP) return -1000 - depth;
if (depth === 0 || isBoardFull(b)) return 0;
if (depth === 0 || isBoardFull(b)) return evaluateBoard(b, aiP, huP);
let best = isMax ? -10000 : 10000;
for (const c of COL_ORDER) {
@@ -196,12 +241,19 @@ function performAiMove(b, aiP, lookAhead, isDemo = false, dPly = 4) {
const huP = aiP === 1 ? 2 : 1;
const ply = isDemo ? dPly : lookAhead;
// Phase 1: instant win / block
// Phase 1a: check ALL columns for instant AI win
for (let c = 0; c < COLS; c++) {
const r = getFirstEmptyRow(b, c);
if (r === -1) continue;
b[c][r] = aiP;
if (scanBoard(b)[0] === aiP) { b[c][r] = 0; return c; }
b[c][r] = 0;
}
// Phase 1b: check ALL columns for opponent block
for (let c = 0; c < COLS; c++) {
const r = getFirstEmptyRow(b, c);
if (r === -1) continue;
b[c][r] = huP;
if (scanBoard(b)[0] === huP) { b[c][r] = 0; return c; }
b[c][r] = 0;