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

-type node = Node of state * move * node list (* state, move, children *)

+type node = Node of state * move * node lazy_t list (* state, move, children *)

let string_of_node = function

| Node (_, move, _) -> "Node(_, " ^ (string_of_move move) ^ ", _)"

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

Node (state, last_move, children)

- if can_capture state last_move then build_capture ()

- else if depth <= 0 then Node (state, last_move, [])

- else if can_put state then build_put ()

- else if can_fly state then build_fly ()

+ if can_capture state last_move then Lazy.lazy_from_fun build_capture

+ else if depth <= 0 then lazy (Node (state, last_move, []))

+ else if can_put state then Lazy.lazy_from_fun build_put

+ else if can_fly state then Lazy.lazy_from_fun build_fly

+ else Lazy.lazy_from_fun build_move

+let print_force_stat () = Printf.eprintf "force called %d times\n%!" !force_count

+let reset_force () = force_count := 0

+ let rec f node = match force node with

+ Node (state, move, list) ->

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

- let rec p depth ~~= function~~

+ let rec p depth node = match force node with

Node (state, move, list) ->

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

let count_positions node =

- let rec count node = match node with

+ let rec count node = match force node with

| Node (_, _, children) ->

let counts = List.map count children in

| Node (s, move, []) -> heuristic s

| Node (s, move, children) ->

if (get_turn s) mod 2 = 0 then min_score children

let find_best state lastmove depth playouts =

let root = build state lastmove depth in

- let positions = count_positions root in

- let nplayouts = playouts / positions in

- let children = match root with Node (_, _, c) -> c in

- let scores = List.map (score (estimate_hybrid nplayouts)) children in

+(* print_force_stat ();*)

+(* let positions = count_positions root in*)

+(* let nplayouts = playouts / positions in*)

+ let children = match force root with Node (_, _, c) -> c in

+ let scores = List.map (score (estimate_basic)) children in

let better = if (get_turn state) mod 2 = 0 then (<) else (>) in

let init = if (get_turn state) mod 2 = 0 then max_int else min_int in

let rec select nodes scores selected score =

if better s score then select (List.tl nodes) (List.tl scores) n s

else select (List.tl nodes) (List.tl scores) selected score

- select children scores (Node (state, lastmove, [])) init

+ let thunk = select children scores (lazy (Node (state, lastmove, []))) init

val mutable last_move = Init

- let selected = find_best state Init ~~2~~ 15000 in

+ let selected = find_best state Init 3 15000 in

| Node(_, Put i, _) -> last_move <- Put i ; i

| _ -> failwith "no put found"

- let selected = find_best state Init 4 30000 in

+ let before = Unix.gettimeofday() in

+ let selected = find_best state Init 6 30000 in

+ let after = Unix.gettimeofday() in

+ Printf.printf "time: %f\n%!" (after -. before);

| Node(_, Move (f, g), _) -> last_move <- Move (f, g) ; f, g

| _ -> failwith "no move found"

- let selected = find_best state Init ~~3~~ 30000 in

+ let selected = find_best state Init 6 30000 in

| Node(_, Fly (f, g), _) -> last_move <- Fly (f, g) ; f, g

| _ -> failwith "no fly found"

end_of_turn state; (* unrolled later *)

- let selected = find_best state last_move ~~2~~ 10000 in

+ let selected = find_best state last_move 4 10000 in

| Node(_, Capture i, _) -> last_move <- Capture i ; i

| _ -> failwith "no capture found"