diff options
author | Alex AUVOLAT <alex.auvolat@ens.fr> | 2014-11-09 19:16:08 +0100 |
---|---|---|
committer | Alex AUVOLAT <alex.auvolat@ens.fr> | 2014-11-09 19:16:08 +0100 |
commit | e17b538a1a541cb83794f044027c6fc2bc7e0aae (patch) | |
tree | a4961bca0459ee6b0e611e8df7bb2bcb5662f53b /judge/core.ml | |
parent | 9bd1d3150d4049cc39eae899914b4ea3e98d9850 (diff) | |
download | CompetIA-e17b538a1a541cb83794f044027c6fc2bc7e0aae.tar.gz CompetIA-e17b538a1a541cb83794f044027c6fc2bc7e0aae.zip |
Working on judge system
Diffstat (limited to 'judge/core.ml')
-rw-r--r-- | judge/core.ml | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/judge/core.ml b/judge/core.ml index 34d5dc9..70e2bd4 100644 --- a/judge/core.ml +++ b/judge/core.ml @@ -25,14 +25,14 @@ type player_proc_status = | Dead module type GAME = sig - type game (* mutable structure *) + type game (* immutable structure *) val name : string (* ex: Morpion récursif *) val id : string (* ex: morpion_rec *) - val new_game : unit -> (game * game_status) + val new_game : game * game_status - val turn : game -> player -> string -> game_status + val turn : game -> player -> string -> (game * game_status) end module type CORE = sig @@ -43,8 +43,10 @@ module type CORE = sig val p2 : game -> player_proc_status val s : game -> game_proc_status val g : game -> G.game + val hist : game -> G.game list (* head: same as g g *) val init : unit -> unit + val finish : unit -> unit val handle_events : unit -> unit (* is anything happening ? *) @@ -62,7 +64,7 @@ end module C (G: GAME) : CORE = struct module G : GAME = G - exception Eliminated_ex + exception Eliminated_ex of string type player = { name: string; @@ -84,7 +86,7 @@ module C (G: GAME) : CORE = struct flush pp.o type game = { - g: G.game; + mutable hist: G.game list; p1: player_proc; p2: player_proc; mutable s: game_proc_status; @@ -92,7 +94,8 @@ module C (G: GAME) : CORE = struct let p1 g = g.p1.s let p2 g = g.p2.s let s g = g.s - let g g = g.g + let g g = List.hd g.hist + let hist g = g.hist let players = Hashtbl.create 12 let planned_games = Queue.create () @@ -101,6 +104,10 @@ module C (G: GAME) : CORE = struct (* program paremeters *) let par_games = ref 2 (* default: launch two simultaneous games *) let game_time = ref 30.0 (* default: 30 sec for each player *) + let pt_win = ref 3 (* default: on win, score += 3 *) + let pt_tie = ref 1 (* default: on tie, score += 1 *) + let pt_lose = ref 0 (* default: on lose, score does not change *) + let pt_elim = ref (-1) (* default: on eliminated, score -= 1 *) let scores () = Hashtbl.fold (fun _ p l -> (p.name, p.score)::l) players [] @@ -110,9 +117,13 @@ module C (G: GAME) : CORE = struct (* 1. PARSE ARGUMENTS *) let game_dir = ref "" in let args = [ - "-p", Arg.Set_int par_games, "How many games to run in parallel."; - "-t", Arg.Set_float game_time, - "Time (seconds) allotted to each player for a game." + "-p", Arg.Set_int par_games, "How many games to run in parallel (2)"; + "-s", Arg.Set_float game_time, + "Time (seconds) allotted to each player for a game (30)"; + "-w", Arg.Set_int pt_win, "Points granted on win (+3)"; + "-t", Arg.Set_int pt_tie, "Points granted on tie (+1)"; + "-l", Arg.Set_int pt_lose, "Points granted on lose (0)"; + "-e", Arg.Set_int pt_elim, "Points granted on eliminated (-1)"; ] in Arg.parse args (fun s -> game_dir := s) @@ -172,7 +183,14 @@ module C (G: GAME) : CORE = struct rd() with End_of_file -> () in rd () - + + let finish () = + (* TODO : + - save scores + - kill all child processes and wait for them + *) + () + let add_rounds () = Hashtbl.iter (fun p _ -> Hashtbl.iter @@ -213,8 +231,8 @@ module C (G: GAME) : CORE = struct in let p1 = open_c (Hashtbl.find players p1) in let p2 = open_c (Hashtbl.find players p2) in - let g, s = G.new_game () in - let g = { p1; p2; g; s = Initializing s } in + let g, s = G.new_game in + let g = { p1; p2; hist = [g]; s = Initializing s } in r_games := g::(!r_games) done; @@ -245,39 +263,38 @@ module C (G: GAME) : CORE = struct begin try match decode (input_line p.i), p.s with | Hello x, Loading when x = G.id -> p.s <- StandBy !game_time; - if op.s <> Loading then begin - match g.s, g.p1.s, g.p2.s with - | Initializing (TurnOf P1), StandBy t, _ -> - send_m g.p1 (YourTurn t); - g.p1.s <- Thinking (t, Unix.time()); + begin match g.s, g.p1.s, g.p2.s, g.p1, g.p2 with + | Initializing (TurnOf P1), StandBy t, StandBy _, p, _ + | Initializing (TurnOf P2), StandBy _, StandBy t, _, p -> + send_m p (YourTurn t); + p.s <- Thinking (t, Unix.time()); g.s <- Running (TurnOf P1) - | Initializing (TurnOf P2), _, StandBy t -> - send_m g.p2 (YourTurn t); - g.p2.s <- Thinking (t, Unix.time()); - g.s <- Running (TurnOf P2) - | _ -> assert false + | _ -> () end | Play act, Thinking (time, beg_r) -> let end_r = Unix.time () in - let new_s = G.turn g.g pi act in - begin match new_s with | Eliminated _ -> raise Eliminated_ex | _ -> () end; + let new_g, new_s = G.turn (List.hd g.hist) pi act in + begin match new_s with + | Eliminated _ -> raise (Eliminated_ex ("invalid move: " ^ act)) | _ -> () + end; send_m p OK; send_m op (Play act); + g.hist <- new_g::g.hist; let finished = match new_s with | Tie -> send_m p Tie; send_m op Tie; Format.printf "%s vs. %s: tie!@." g.p1.p.name g.p2.p.name; - true - | Won x when x = pi -> - send_m p YouWin; - send_m op YouLose; - Format.printf "%s vs. %s: %s wins!@." g.p1.p.name g.p2.p.name p.p.name; + p.p.score <- p.p.score + !pt_tie; + op.p.score <- op.p.score + !pt_tie; true | Won x -> - send_m op YouWin; - send_m p YouLose; - Format.printf "%s vs. %s: %s wins!@." g.p1.p.name g.p2.p.name op.p.name; + let (w, l) = if x = P1 then (g.p1, g.p2) else (g.p2, g.p1) in + send_m w YouWin; + send_m l YouLose; + Format.printf "%s vs. %s: %s wins!@." g.p1.p.name g.p2.p.name w.p.name; + w.p.score <- w.p.score + !pt_win; + l.p.score <- l.p.score + !pt_lose; true | TurnOf _ -> false | Eliminated x -> assert false @@ -298,17 +315,19 @@ module C (G: GAME) : CORE = struct | FairEnough, Saving -> kill p.pid 15; (* 15 : sigterm *) p.s <- Dead - | _ -> raise Eliminated_ex - | exception _ -> raise Eliminated_ex + | bad_m, _ -> raise (Eliminated_ex ("unexpected message: '" ^ encode bad_m ^ "'")) + | exception Invalid_message m -> raise (Eliminated_ex ("invalid message: '" ^ m ^"'")) + | exception _ -> raise (Eliminated_ex "exception when reading message") with - | Eliminated_ex -> + | Eliminated_ex r -> send_m p Eliminated; send_m op YouWin; (* since process is not respecting the protocol, we cannot assume it is doing anything reasonable, so we kill it... *) kill p.pid 15; - Format.printf "%s vs. %s: %s eliminated!@." g.p1.p.name g.p2.p.name p.p.name; + Format.printf "%s vs. %s: %s eliminated (%s)!@." g.p1.p.name g.p2.p.name p.p.name r; p.s <- Dead; + p.p.score <- p.p.score + !pt_elim; op.s <- Saving; g.s <- Finished (Eliminated pi) end; |