🎮 Minimax Game AI

Generic game-playing AI with alpha-beta pruning and iterative deepening

Overview

A functor-based game AI framework that plays any two-player zero-sum game optimally. The engine uses minimax search with alpha-beta pruning to explore game trees, iterative deepening for time-bounded play, and a transposition table for memoizing previously seen positions.

Two complete games are included: Tic-Tac-Toe (solved — AI never loses) and Connect Four (deep search with heuristic evaluation).

Concepts Demonstrated

The GAME Interface

module type GAME = sig
  type state                        (* board representation *)
  type move                         (* legal action *)
  type player = Maximizer | Minimizer

  val initial : state               (* starting position *)
  val current_player : state -> player
  val legal_moves : state -> move list
  val apply_move : state -> move -> state
  val is_terminal : state -> bool
  val evaluate : state -> float     (* heuristic: +∞ max wins, -∞ min wins *)
  val hash : state -> int           (* for transposition table *)
end

(* The functor builds a complete AI from any GAME *)
module MakeAI (G : GAME) : sig
  val best_move : G.state -> depth:int -> G.move
  val best_move_timed : G.state -> seconds:float -> G.move
end

Alpha-Beta Pruning

(* Minimax without pruning: explore ALL branches — O(b^d) *)
(* Alpha-beta: skip branches that can't improve the result *)

(*   α = best score Maximizer can guarantee so far
     β = best score Minimizer can guarantee so far
     When α ≥ β, the remaining branches are irrelevant — prune *)

(* With good move ordering, alpha-beta reduces branching:
   O(b^d) → O(b^(d/2)) — effectively doubles search depth *)

let rec alphabeta state depth alpha beta =
  if depth = 0 || is_terminal state then evaluate state
  else match current_player state with
  | Maximizer ->
    legal_moves state |> List.fold_left (fun alpha move ->
      let score = alphabeta (apply_move state move) (depth-1) alpha beta in
      if score >= beta then beta  (* prune! *)
      else max alpha score
    ) alpha
  | Minimizer -> (* symmetric *)

Included Games

GameBoardBranchingAI Strength
Tic-Tac-Toe3×3~4 avgPerfect play (solved)
Connect Four7×6~7 avgStrong with iterative deepening

Related Modules