+ let color = get_color (get_turn state) in

+ let moves a = List.map (fun b -> (a, b)) (free_neighbors state a) in

+ List.flatten (List.map moves (movables state color))

+ let color = get_color (get_turn state) in

+ let flies a = List.map (fun b -> (a, b)) (free_dots state) in

+ List.flatten (List.map flies (movables state color))

+ let black = (get_count state Black)

+ and white = (get_count state White) in

+ if can_put state then black - white

+ else if black < 3 then min_int

+ else if white < 3 then max_int

+ | Put of int (* index *)

+ | Move of int * int (* from, goal *)

+ | Fly of int * int (* from, goal *)

+ | Capture of int (* optional capture index *)

+let string_of_move = function

+ | Put i -> Printf.sprintf "put %d" i

+ | Move (f, g) -> Printf.sprintf "move %d %d" f g

+ | Fly (f, g) -> Printf.sprintf "fly %d %d" f g

+ | Capture i -> Printf.sprintf "capture %d" i

+ | Root of state * ab_node list (* state, children *)

+ | Node of state * move * ab_node list (* state, move, children *)

+let can_capture state move = match move with

+ | Put i -> in_mill state i

+ | Move (from, goal) -> in_mill state goal

+ | Fly (from, goal) -> in_mill state goal

+let rec build state last_move depth =

+ Printf.printf "build %s %d\n%!" (string_of_move last_move) depth;

+ build s (Put i) (pred depth)

+ let children = List.map aux (free_dots state) in

+ Node (state, last_move, children)

+ build s (Fly (from, goal)) (pred depth)

+ let children = List.map aux (all_flies state) in

+ Node (state, last_move, children)

+ build s (Move (from, goal)) (pred depth)

+ let children = List.map aux (all_moves state) in

+ Node (state, last_move, children)

+ build s (Capture i) (pred depth)

+ let color = get_color (get_turn state) in

+ let children = List.map aux (capturables state color) in

+ Node (state, last_move, children)

+ if depth = 0 then Leaf state

+ else if can_capture state last_move then build_capture ()

+ else if can_put state then build_put ()

+ else if can_fly state then build_fly ()

+let build_tree state depth = build state Init depth

+ if depth > 0 then (Printf.printf "+"; indent (pred depth))

+ let rec p depth = function

+ | Root (state, list) ->

+ Printf.printf "root\n";

+ List.iter (p (succ depth)) list

+ | Node (state, move, list) ->

+ Printf.printf "%s\n" (string_of_move move);

+ List.iter (p (succ depth)) list

+ let tree = build_tree (make()) 4 in

+let select node alpha beta =

+ let state = match node with

+ let children = match node with

+ let leaf = function Leaf _ -> true | _ -> false in

+ let max (a, score_a) (b, score_b) =

+ if score_a > score_b then (a, score_a)

+ and min (a, score_a) (b, score_b) =

+ if score_a < score_b then (a, score_a)

+ if leaf node then node, (estimate state)

+ else if (get_turn state) mod 2 = 1 then

+ let alpha = ref alpha in

+ for i = 0 to (List.length children) -1 do

+function alphabeta(node, depth, alpha, beta, Player)

+ if depth = 0 or node is a terminal node

+ return the heuristic value of node

+ alpha := max(alpha, alphabeta(child, depth-1, alpha, beta, not(Player) ))

+ break (* Beta cut-off *)

+ beta := min(beta, alphabeta(child, depth-1, alpha, beta, not(Player) ))

+ break (* Alpha cut-off *)

+alphabeta(origin, depth, -infinity, +infinity, MaxPlayer)