diff options
author | Alex AUVOLAT <alex.auvolat@ens.fr> | 2014-11-09 01:07:08 +0100 |
---|---|---|
committer | Alex AUVOLAT <alex.auvolat@ens.fr> | 2014-11-09 01:07:08 +0100 |
commit | 671244fc96a54dff2d3bec618ec9e398f744e430 (patch) | |
tree | 1139550f1355cf9050bfcabf83c30846ceb93264 | |
parent | 65af3ed6ef638ea46229bd64c1a10cec3e5a34d8 (diff) | |
download | CompetIA-671244fc96a54dff2d3bec618ec9e398f744e430.tar.gz CompetIA-671244fc96a54dff2d3bec618ec9e398f744e430.zip |
Improve judge, add NiAh player from AP.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | judge/core.ml | 106 | ||||
-rw-r--r-- | morpion_rec/NiAh/main.c | 243 | ||||
-rw-r--r-- | morpion_rec/NiAh/main.h | 13 |
4 files changed, 362 insertions, 1 deletions
@@ -5,3 +5,4 @@ judge/_build/* *.native *.byte +morpion_rec/*/player diff --git a/judge/core.ml b/judge/core.ml index 7012118..65a43a8 100644 --- a/judge/core.ml +++ b/judge/core.ml @@ -62,9 +62,12 @@ end module C (G: GAME) : CORE = struct module G : GAME = G + exception Eliminated_ex + type player = { name: string; binary: string; + log_out: file_descr; mutable score: int; } @@ -151,9 +154,15 @@ module C (G: GAME) : CORE = struct if (st.st_kind = S_REG || st.st_kind = S_LNK) && (st.st_perm land 0o100 <> 0) then begin Format.printf "- %s@." s; + (* open log output for player *) + let p_log_file = Filename.concat (Filename.concat !game_dir s) "stderr.log" in + let p_log_out = Unix.openfile p_log_file [O_APPEND; O_CREAT; O_WRONLY] 0o644 in + let f = Format.formatter_of_out_channel (out_channel_of_descr p_log_out) in + Format.fprintf f "---- Begin session %s@." date; Hashtbl.add players s { name = s; binary = b; + log_out = p_log_out; score = 0; } end with _ -> (); @@ -179,12 +188,15 @@ module C (G: GAME) : CORE = struct Format.printf "Launching match: %s vs. %s@." p1 p2; let open_c p = + let f =Format.formatter_of_out_channel (out_channel_of_descr p.log_out) in + Format.fprintf f "--- Begin game (%s vs. %s)@." p1 p2; let (j2p_i, j2p_o) = pipe () in let (p2j_i, p2j_o) = pipe () in let pid = fork() in if pid = 0 then begin dup2 j2p_i stdin; dup2 p2j_o stdout; + dup2 p.log_out stderr; execv p.binary [| p.binary |]; end; Format.printf "- %s: pid %d@." p.name pid; @@ -204,6 +216,98 @@ module C (G: GAME) : CORE = struct (* 2. LOOK IF ANYBODY IS TELLING US SOMETHING - IF SO, REACT (wait max. 0.01 sec) *) - () + let in_fd = List.fold_left + (fun l g -> match g.s with + | Finished _ -> l + | _ -> + let l = match g.p1.s with + | Dead -> l + | _ -> (Unix.descr_of_in_channel g.p1.i)::l + in match g.p2.s with + | Dead -> l + | _ -> (Unix.descr_of_in_channel g.p2.i)::l) + [] !r_games + in + let in_fd, _, _ = select in_fd [] [] 0.01 in + let do_fd fd = + let g = List.find + (fun g -> fd = Unix.descr_of_in_channel g.p1.i + || fd = Unix.descr_of_in_channel g.p2.i) + !r_games + in + let pi = if Unix.descr_of_in_channel g.p1.i = fd then P1 else P2 in + let p = match pi with P1 -> g.p1 | P2 -> g.p2 in + let op = match pi with P1 -> g.p2 | P2 -> g.p1 in + 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()); + 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; + send_m p OK; + send_m op (Play act); + 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; + 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; + true + | TurnOf _ -> false + | Eliminated x -> assert false + in + if finished then begin + p.s <- Saving; + op.s <- Saving; + g.s <- Finished new_s + end else begin + p.s <- StandBy (time -. (end_r -. beg_r)); + g.s <- Running new_s; + match op.s with + | StandBy t -> + send_m op (YourTurn t); + op.s <- Thinking (t, Unix.time()) + | _ -> assert false + end + | FairEnough, Saving -> + kill p.pid 15; (* 15 : sigterm *) + p.s <- Dead + | _ -> raise Eliminated_ex + | exception _ -> raise Eliminated_ex + with + | Eliminated_ex -> + 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; + p.s <- Dead; + op.s <- Saving; + g.s <- Finished (Eliminated pi) + end; + in List.iter do_fd in_fd end diff --git a/morpion_rec/NiAh/main.c b/morpion_rec/NiAh/main.c new file mode 100644 index 0000000..74248c3 --- /dev/null +++ b/morpion_rec/NiAh/main.c @@ -0,0 +1,243 @@ +/* IA pour morpion récursif - Alexis + * main.c + * Contient les fonctions principales */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "main.h" + +#define INPUT_LENGTH 50 + +int main() +{ + int i,j,k,l; + + char input[INPUT_LENGTH]; + float timeout; + + Dots grid[9][9]; + Boxes subgrid, move, firstsubgrid; + int firstMove=1; + + for(i=0;i<9;i++) + for(j=0;j<9;j++) + grid[i][j] = FREE; + + subgrid = Z; + firstsubgrid=V; + + // Dis bonjour à Alex ... + fgets(input, sizeof(input), stdin); + for(i=0;i<INPUT_LENGTH;i++){if(input[i]=='\n'){input[i]='\0';}} + if(strcmp(input, "Hello morpion_rec") == 0) + { + printf("Hello morpion_rec\n"); + } + else + { + printf("Who are you, crazy bastard?\n"); + return EXIT_FAILURE; + } + + printGrid(grid); + + // Est-ce à moi de jouer ? + while(1) + { + while(1) + { + fgets(input, sizeof(input), stdin); + + // Attendre pour jouer + if(strstr(input,"Your turn")==input) + { + sscanf(input+10,"%f",&timeout); + break; + } + + //Attendre le coup de l'adversaire + if(strstr(input,"Play")==input) + { + sscanf(input+5,"%d %d %d %d",&i,&j,&k,&l); + subgrid=(i-1)+(j-1)*3; + move = (k-1)+(l-1)*3; + fprintf(stderr,"%d %d\n", subgrid, move); + // L'adversaire joue les ronds + if(firstMove) + { + firstsubgrid=subgrid; + firstMove=0; + } + play(grid, subgrid, CIRCLE, move); + printGrid(grid); + subgrid=move; + } + + // Attendre le résultat de la partie + if(strstr(input,"You win")==input) + { + printf("Yeah!"); + return EXIT_SUCCESS; + } + if(strstr(input,"You lose")==input) + { + printf("I am so sad..."); + return EXIT_SUCCESS; + } + if(strstr(input,"Tie")==input) + { + printf("It is a good result anyways."); + return EXIT_SUCCESS; + } + if(strstr(input,"Cheater")==input) + { + printf("You are so nasty :("); + return EXIT_FAILURE; + } + + } + + // On joue toujours les croix + if(firstMove) + { + firstsubgrid=V; + subgrid=firstsubgrid; + firstMove=0; + } + if(chooseMoveAndPlay(grid, subgrid, CROSS, &move, firstsubgrid) != 0){return EXIT_FAILURE;} + printf("Play %d %d %d %d\n", subgrid%3+1, subgrid/3+1, move%3+1, move/3+1); + + subgrid=move; + printGrid(grid); + } + + + return EXIT_SUCCESS; +} + +int play(Dots grid[9][9], Boxes subgrid, Dots player, Boxes move) +{ + if(subgrid == Z || move == Z || player == FREE || grid[subgrid][move] != FREE) + return 1; + grid[subgrid][move] = player; +} + +int chooseMoveAndPlay(Dots grid[9][9], Boxes subgrid, Dots player, Boxes *move, Boxes firstSubgrid) +{ + int i,j; + Boxes sg = (subgrid!=Z) ? subgrid : V; // Inutile maintenant + for(i=0;i<9;i++) + { + if(grid[sg][i] == FREE) + { + *move = i; + grid[sg][i] = player; + return 0; + } + } + if(firstSubgrid=subgrid) + { + for(i=0;i<9;i++) + { + for(j=0;j<9;j++) + { + if(grid[j][i] == FREE) + { + *move = i; + grid[j][i] = player; + return 0; + } + } + } + } + return 1; +} + +void checkSolutions(Boxes a, Solutions sols) +{ + switch(a) + { + case I: + sols[0][0] = II; sols[0][1] = III; + sols[1][0] = IV; sols[1][1] = VII; + sols[2][0] = Z; sols[2][1] = Z; + sols[3][0] = Z; sols[3][1] = Z; + break; + case II: + sols[0][0] = I; sols[0][1] = III; + sols[1][0] = V; sols[1][1] = VIII; + sols[2][0] = Z; sols[2][1] = Z; + sols[3][0] = Z; sols[3][1] = Z; + break; + case III: + sols[0][0] = I; sols[0][1] = II; + sols[1][0] = VI; sols[1][1] = IX; + sols[2][0] = Z; sols[2][1] = Z; + sols[3][0] = Z; sols[3][1] = Z; + break; + case IV: + sols[0][0] = I; sols[0][1] = VII; + sols[1][0] = V; sols[1][1] = VI; + sols[2][0] = Z; sols[2][1] = Z; + sols[3][0] = Z; sols[3][1] = Z; + break; + case V: + sols[0][0] = II; sols[0][1] = VIII; + sols[1][0] = I; sols[1][1] = IX; + sols[2][0] = IV; sols[2][1] = VI; + sols[3][0] = VII; sols[3][1] = III; + break; + case VI: + sols[0][0] = IV; sols[0][1] = V; + sols[1][0] = III; sols[1][1] = IX; + sols[2][0] = Z; sols[2][1] = Z; + sols[3][0] = Z; sols[3][1] = Z; + break; + case VII: + sols[0][0] = I; sols[0][1] = IV; + sols[1][0] = VII; sols[1][1] = IX; + sols[2][0] = Z; sols[2][1] = Z; + sols[3][0] = Z; sols[3][1] = Z; + break; + case VIII: + sols[0][0] = II; sols[0][1] = V; + sols[1][0] = VI; sols[1][1] = IX; + sols[2][0] = Z; sols[2][1] = Z; + sols[3][0] = Z; sols[3][1] = Z; + break; + case IX: + sols[0][0] = III; sols[0][1] = VI; + sols[1][0] = VII; sols[2][1] = IX; + sols[2][0] = Z; sols[2][1] = Z; + sols[3][0] = Z; sols[3][1] = Z; + break; + default: + sols[0][0] = Z; sols[0][1] = Z; + sols[1][0] = Z; sols[1][1] = Z; + sols[2][0] = Z; sols[2][1] = Z; + sols[3][0] = Z; sols[3][1] = Z; + break; + } +} + +// Les affichages se font dans stderr +void printGrid(Dots grid[9][9]) +{ + int x,y, i,j; + + fprintf(stderr,"\n*********\n"); + for(x=0;x<9;x++) + { + for(y=0;y<9;y++) + { + i=(y/3)*3+(x/3); + j=(y-(y/3)*3)*3+(x-(x/3)*3); + fprintf(stderr,"%d", grid[i][j]); + } + fprintf(stderr,"\n"); + } + fprintf(stderr,"\n*********\n"); +} + + diff --git a/morpion_rec/NiAh/main.h b/morpion_rec/NiAh/main.h new file mode 100644 index 0000000..5cf06d2 --- /dev/null +++ b/morpion_rec/NiAh/main.h @@ -0,0 +1,13 @@ +/* IA pour morpion récursif - Alexis + * main.h + * Définition des énumérations, typedef et autres */ + +typedef enum {FREE, CROSS, CIRCLE} Dots; +typedef enum {I=0, II=1, III=2, IV = 3, V=4, VI=5, VII=6, VIII=7, IX=8, Z=-1} Boxes; +typedef Boxes Solutions[4][2]; + +int play(Dots grid[9][9], Boxes subgrid, Dots player, Boxes move); +int chooseMoveAndPlay(Dots grid[9][9], Boxes subgrid, Dots player, Boxes *move, Boxes firstSubgrid); +void checkSolutions(Boxes a, Solutions sols); +void printGrid(Dots grid[9][9]); + |