[fix] Add heuristic to Python code.
This commit is contained in:
+59
-2
@@ -269,6 +269,57 @@ def log_game(games: list[dict], game_menu_mode: int, level: int, winner: int, mo
|
||||
|
||||
# --- AI ---
|
||||
|
||||
def evaluate_board(board: list[list[int]], ai_p: int, hu_p: int) -> int:
|
||||
score = 0
|
||||
|
||||
# Center column bonus
|
||||
for r in range(ROWS):
|
||||
if board[3][r] == ai_p:
|
||||
score += 3
|
||||
elif board[3][r] == hu_p:
|
||||
score -= 3
|
||||
|
||||
# Score a window of 4 cells by piece counts
|
||||
def score_window(c: int, r: int, dc: int, dr: int) -> int:
|
||||
ai, hu = 0, 0
|
||||
for i in range(4):
|
||||
v = board[c + i * dc][r + i * dr]
|
||||
if v == ai_p:
|
||||
ai += 1
|
||||
elif v == hu_p:
|
||||
hu += 1
|
||||
if ai > 0 and 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 r in range(ROWS):
|
||||
for c in range(COLS - 3):
|
||||
score += score_window(c, r, 1, 0)
|
||||
# Vertical
|
||||
for r in range(ROWS - 3):
|
||||
for c in range(COLS):
|
||||
score += score_window(c, r, 0, 1)
|
||||
# Diagonal up-right
|
||||
for r in range(ROWS - 3):
|
||||
for c in range(COLS - 3):
|
||||
score += score_window(c, r, 1, 1)
|
||||
# Diagonal down-right
|
||||
for r in range(3, ROWS):
|
||||
for c in range(COLS - 3):
|
||||
score += score_window(c, r, 1, -1)
|
||||
|
||||
return score
|
||||
|
||||
|
||||
def minimax(
|
||||
board: list[list[int]], depth: int, alpha: int, beta: int,
|
||||
is_max: bool, ai_p: int, hu_p: int,
|
||||
@@ -279,7 +330,7 @@ def minimax(
|
||||
if winner == hu_p:
|
||||
return -1000 - depth
|
||||
if depth == 0 or is_board_full(board):
|
||||
return 0
|
||||
return evaluate_board(board, ai_p, hu_p)
|
||||
|
||||
best = -10000 if is_max else 10000
|
||||
for c in COL_ORDER:
|
||||
@@ -309,7 +360,7 @@ def perform_ai_move(
|
||||
hu_p = 2 if ai_p == 1 else 1
|
||||
ply = demo_ply if is_demo else look_ahead
|
||||
|
||||
# Phase 1: instant win / block
|
||||
# Phase 1a: check ALL columns for instant AI win
|
||||
for c in range(COLS):
|
||||
r = get_first_empty_row(board, c)
|
||||
if r != -1:
|
||||
@@ -317,6 +368,12 @@ def perform_ai_move(
|
||||
if scan_board(board)[0] == ai_p:
|
||||
board[c][r] = 0
|
||||
return c
|
||||
board[c][r] = 0
|
||||
|
||||
# Phase 1b: check ALL columns for opponent block
|
||||
for c in range(COLS):
|
||||
r = get_first_empty_row(board, c)
|
||||
if r != -1:
|
||||
board[c][r] = hu_p
|
||||
if scan_board(board)[0] == hu_p:
|
||||
board[c][r] = 0
|
||||
|
||||
Reference in New Issue
Block a user