aboutsummaryrefslogtreecommitdiff
path: root/judge/core.ml
diff options
context:
space:
mode:
authorAlex AUVOLAT <alex.auvolat@ens.fr>2014-11-09 19:16:08 +0100
committerAlex AUVOLAT <alex.auvolat@ens.fr>2014-11-09 19:16:08 +0100
commite17b538a1a541cb83794f044027c6fc2bc7e0aae (patch)
treea4961bca0459ee6b0e611e8df7bb2bcb5662f53b /judge/core.ml
parent9bd1d3150d4049cc39eae899914b4ea3e98d9850 (diff)
downloadCompetIA-e17b538a1a541cb83794f044027c6fc2bc7e0aae.tar.gz
CompetIA-e17b538a1a541cb83794f044027c6fc2bc7e0aae.zip
Working on judge system
Diffstat (limited to 'judge/core.ml')
-rw-r--r--judge/core.ml91
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;