I'd appreciate some help please folks with a (what should be) simple game in GDScript 2.0. I am making a tic-tac-toe game and Player 2 is an AI using the minimax algorith. However the AI is really dumb sometimes and just lets me win when it would have been so easy to block a winning line. I've been trying to debug this all day long and I am pulling my hair out. The complete project can be found at:
https://github.com/thearduinoguy/KitKatGo
Thanks.
var INFINITY = 10000000
var gridSize = 3
var game_depth = 50
var win_length = 3
#=================================================================================================
func minimax(grid: Array, size: int, length: int, depth: int, alpha: int, beta: int, is_maximizing: bool) -> int:
var winner = check_winner(grid, size, length)
if winner != EMPTY:
return (winner * (size - depth)) * (1 if depth % 2 == 0 else -1)
if depth >= game_depth:
return 0
if is_maximizing:
var best_value = -INFINITY
for r in range(size):
for c in range(size):
if grid[r * size + c] == EMPTY:
grid[r * size + c] = PLAYER_O
var value = minimax(grid, size, length, depth + 1, alpha, beta, false)
grid[r * size + c] = EMPTY
best_value = max(value, best_value)
alpha = max(alpha, best_value)
if beta <= alpha:
break
return best_value
else:
var best_value = INFINITY
for r in range(size):
for c in range(size):
if grid[r * size + c] == EMPTY:
grid[r * size + c] = PLAYER_X
var value = minimax(grid, size, length, depth + 1, alpha, beta, true)
grid[r * size + c] = EMPTY
best_value = min(value, best_value)
beta = min(beta, best_value)
if beta <= alpha:
break
return best_value
#=================================================================================================
func find_best_move(grid: Array, size: int, length: int) -> Vector2:
var best_value = -INFINITY
var best_move = Vector2(-1, -1)
for r in range(size):
for c in range(size):
if grid[r * size + c] == EMPTY:
grid[r * size + c] = PLAYER_O
var move_value = minimax(grid, size, length, 0, -INFINITY, INFINITY, true)
grid[r * size + c] = EMPTY
if move_value > best_value or (move_value == best_value and randf() > 0.5):
best_value = move_value
best_move = Vector2(c, r)
if best_value == INFINITY: # Early exit when we found the best possible move
break
if best_value == INFINITY: # This break is for the outer loop
break
return best_move