[Toss-devel-svn] SF.net SVN: toss:[1687] trunk/Toss
Status: Beta
Brought to you by:
lukaszkaiser
|
From: <luk...@us...> - 2012-03-09 18:42:47
|
Revision: 1687
http://toss.svn.sourceforge.net/toss/?rev=1687&view=rev
Author: lukaszkaiser
Date: 2012-03-09 18:42:39 +0000 (Fri, 09 Mar 2012)
Log Message:
-----------
Merging Move into Arena and debugging JS-Server communication. First full JS-standalone+Server-speedup Toss version.
Modified Paths:
--------------
trunk/Toss/Arena/Arena.ml
trunk/Toss/Arena/Arena.mli
trunk/Toss/Arena/ArenaTest.ml
trunk/Toss/Client/JsHandler.ml
trunk/Toss/Client/Main.js
trunk/Toss/Client/Play.js
trunk/Toss/Client/State.js
trunk/Toss/Client/Style.css
trunk/Toss/Client/index.html
trunk/Toss/GGP/TranslateGameTest.ml
trunk/Toss/Play/GameTree.ml
trunk/Toss/Play/Play.ml
trunk/Toss/Play/PlayTest.ml
trunk/Toss/Server/Server.ml
trunk/Toss/Server/Tests.ml
Removed Paths:
-------------
trunk/Toss/Play/Move.ml
trunk/Toss/Play/Move.mli
trunk/Toss/Play/MoveTest.ml
Modified: trunk/Toss/Arena/Arena.ml
===================================================================
--- trunk/Toss/Arena/Arena.ml 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Arena/Arena.ml 2012-03-09 18:42:39 UTC (rev 1687)
@@ -86,6 +86,149 @@
Structure.equal gs1.struc gs2.struc
+(* ---------------------------- PRINTING FUNCTIONS -------------------------- *)
+
+(* Print a label as a string. *)
+let label_str
+ {lb_rule = rr; time_in = t_interval; parameters_in = param_intervals} =
+ let fpstr (f,(fs, fe)) =
+ f ^ ": " ^ (string_of_float fs) ^ " -- " ^ (string_of_float fe) in
+ let par_str = if param_intervals = [] then " " else
+ ", " ^ (String.concat ", " (List.map fpstr param_intervals)) in
+ (rr) ^ ", " ^ fpstr ("t", t_interval) ^ par_str
+
+(* Print a move as string. *)
+let move_str (lb, i) = Printf.sprintf "[%s -> %i]" (label_str lb) i
+let pmv_str (pl, lb, i) = Printf.sprintf "[%s,%s -> %i]" pl (label_str lb) i
+
+let fprint_loc_body_in struc pnames f player {payoff = in_p; moves = in_m} =
+ Format.fprintf f "@ @[<0>PLAYER@ %s@ {@ %a}@]@," (Aux.rev_assoc pnames player)
+ (fun f (payoff, moves) ->
+ Format.fprintf f "@[<1>PAYOFF@ @[<1>%a@]@]@ "
+ (Formula.fprint_real(* _nobra 0 *)) payoff;
+ if moves <> [] then
+ Format.fprintf f "@[<1>MOVES@ %a@]@ "
+ (Aux.fprint_sep_list ";" (fun f ({
+ lb_rule=r; time_in=(t_l, t_r); parameters_in=params}, target) ->
+ Format.fprintf f "[@,@[<1>%s" r;
+ if t_l <> cDEFAULT_TIMESTEP || t_r <> cDEFAULT_TIMESTEP then
+ Format.fprintf f ",@ @[<1>t:@ %F@ --@ %F@]" t_l t_r;
+ if params <> [] then
+ Format.fprintf f ",@ %a"
+ (Aux.fprint_sep_list "," (fun f (pn, (p_l, p_r)) ->
+ Format.fprintf f "@[<1>%s:@ %F@ --@ %F@]" pn p_l p_r)) params;
+ Format.fprintf f "@ ->@ %d@]@,]" target)) moves
+ ) (in_p, in_m)
+
+let fprint_loc_body struc pnames f loc =
+ Array.iteri (fun p l -> fprint_loc_body_in struc pnames f p l) loc
+
+let equational_def_style = ref true
+
+let fprint_game_move ?(as_ints=false) struc f
+ ({mv_time = t; parameters = pl; rule = rn;
+ next_loc = l; matching = m}, rtime) =
+ let m_s = String.concat ", "
+ (List.map (fun (e, x) ->
+ if as_ints then
+ Printf.sprintf "%s: %i" e x
+ else
+ Printf.sprintf "%s: %s" e (Structure.elem_str struc x))
+ (List.sort Pervasives.compare m)) in
+ let rt = match rtime with None -> "" | Some f -> " " ^ (string_of_float f) in
+ if (pl = []) then
+ Format.fprintf f "@[<1>[%s@ %F@ ->@ %i@ emb@ %s]%s@]" rn t l m_s rt
+ else (
+ let p_s = String.concat ", "
+ (List.map (fun (p, v) -> Printf.sprintf "%s: %F" p v) pl) in
+ Format.fprintf f "@[<1>[%s@ %F,@ %s@ ->@ %i@ emb@ %s]%s@]" rn t p_s l m_s rt
+ )
+
+let sprint_game_move st gm = AuxIO.sprint_of_fprint (fprint_game_move st) gm
+let game_move_str st gm = sprint_game_move st (gm, None)
+let game_move_gs_str st gm = sprint_game_move st.struc (gm, None)
+
+let fprint_only_state ?(ext_struct=false) ppf
+ {struc = struc;
+ time = time;
+ cur_loc = cur_loc;
+ history = hist;
+ } =
+ Format.fprintf ppf "@[<1>MODEL@ %a@]@ "
+ (if ext_struct then (Structure.fprint_ext_structure ~show_empty:true) else
+ (Structure.fprint ~show_empty:true)) struc;
+ if (hist <> []) then
+ Format.fprintf ppf "@[<1>MOVES@ %a@]@ "
+ (Aux.fprint_sep_list ";\n" (fprint_game_move struc)) hist;
+ if cur_loc <> 0 then
+ Format.fprintf ppf "@[<1>STATE LOC@ %d@]@ " cur_loc;
+ if time <> 0. then
+ Format.fprintf ppf "@[<1>TIME@ %F@]@ " time
+
+let sprint_only_state s = AuxIO.sprint_of_fprint fprint_only_state s
+
+let fprint_state_full ?(ext_struct=false) print_compiled_rules ppf
+ ({rules = rules;
+ graph = graph;
+ num_players = num_players;
+ player_names = player_names;
+ data = data;
+ defined_rels = defined_rels;
+ starting_struc = struc;
+ },
+ {time = time;
+ cur_loc = cur_loc;
+ history = hist;
+ }) =
+ Format.fprintf ppf "@[<v>";
+ List.iter (fun (drel, (args, body)) ->
+ if !equational_def_style then
+ Format.fprintf ppf "@[<1>REL@ %s@,(@[<1>%a@])@ =@ @[<1>%a@]"
+ drel (Aux.fprint_sep_list "," Format.pp_print_string) args
+ Formula.fprint body
+ else
+ Format.fprintf ppf "@[<1>REL@ %s@,(@[<1>%a@])@ {@,@[<1>%a@,@]}"
+ drel (Aux.fprint_sep_list "," Format.pp_print_string) args
+ Formula.fprint body;
+ Format.fprintf ppf "@]@ ";
+ ) defined_rels;
+ Format.fprintf ppf "@[<1>PLAYERS@ %a@]@ "
+ (Aux.fprint_sep_list "," Format.pp_print_string)
+ (List.map fst (List.sort (fun (_,x) (_,y) -> x-y) player_names));
+ if data <> [] then
+ Format.fprintf ppf "@[<1>DATA@ %a@]@ "
+ (Aux.fprint_sep_list ","
+ (fun ppf (k,v) -> Format.fprintf ppf "@[<1>%s@,:@ %s@]" k v))
+ data;
+ List.iter (fun (rname, r) ->
+ Format.fprintf ppf "@[<1>RULE %s:@ %a@]@ " rname
+ (ContinuousRule.fprint_full print_compiled_rules) r) rules;
+ Array.iteri (fun loc_id loc ->
+ Format.fprintf ppf "@[<0>LOC@ %d@ {@,@[<2> %a@]@]@,}@ "
+ loc_id (fprint_loc_body struc player_names) loc) graph;
+ Format.fprintf ppf "@[<1>MODEL@ %a@]@ "
+ (if ext_struct then (Structure.fprint_ext_structure ~show_empty:true) else
+ (Structure.fprint ~show_empty:true)) struc;
+ if (hist <> []) then
+ Format.fprintf ppf "@[<1>MOVES@ %a@]@ "
+ (Aux.fprint_sep_list ";\n" (fprint_game_move ~as_ints:true struc)) hist;
+ if cur_loc <> 0 then
+ Format.fprintf ppf "@[<1>STATE LOC@ %d@]@ " cur_loc;
+ if time <> 0. then
+ Format.fprintf ppf "@[<1>TIME@ %F@]@ " time;
+ Format.fprintf ppf "@]"
+
+let fprint_state = fprint_state_full false
+let print_state r = AuxIO.print_of_fprint (fprint_state_full false) r
+let sprint_state r = AuxIO.sprint_of_fprint (fprint_state_full false) r
+let sprint_state_full r = AuxIO.sprint_of_fprint (fprint_state_full true) r
+let sprint_state_ext r =
+ AuxIO.sprint_of_fprint (fprint_state_full ~ext_struct:true false) r
+let str game = sprint_state (game, snd empty_state)
+let state_str state = sprint_state state
+
+
+
(* -------------------- PARSER HELPER ------------------------------ *)
let matching_of_names (game, state) rname match_str =
@@ -191,7 +334,8 @@
time = new_time;
history = (m, t) :: state.history;
cur_loc = m.next_loc }
- | _ -> failwith "rule inapplicable"
+ | _ -> failwith ("move " ^ (sprint_game_move state.struc (m,t)) ^
+ " inapplicable to " ^ (sprint_only_state state))
(* Make a move in a game. *)
let make_move m (game, state) = (game, apply_move game.rules state (m, None))
@@ -289,7 +433,7 @@
let pats=List.rev_map (FormulaSubst.subst_rels_expr def_rels_pure) patterns in
let apply_moves rules mvs s = List.fold_left (apply_move rules) s mvs in
let result_state =
- apply_moves rules hist {
+ apply_moves rules (List.rev hist) {
struc = state;
time = time;
cur_loc = cur_loc;
@@ -307,118 +451,6 @@
}, result_state
-
-(* ---------------------------- PRINTING FUNCTIONS -------------------------- *)
-
-(* Print a label as a string. *)
-let label_str
- {lb_rule = rr; time_in = t_interval; parameters_in = param_intervals} =
- let fpstr (f,(fs, fe)) =
- f ^ ": " ^ (string_of_float fs) ^ " -- " ^ (string_of_float fe) in
- let par_str = if param_intervals = [] then " " else
- ", " ^ (String.concat ", " (List.map fpstr param_intervals)) in
- (rr) ^ ", " ^ fpstr ("t", t_interval) ^ par_str
-
-(* Print a move as string. *)
-let move_str (lb, i) = Printf.sprintf "[%s -> %i]" (label_str lb) i
-let pmv_str (pl, lb, i) = Printf.sprintf "[%s,%s -> %i]" pl (label_str lb) i
-
-let fprint_loc_body_in struc pnames f player {payoff = in_p; moves = in_m} =
- Format.fprintf f "@ @[<0>PLAYER@ %s@ {@ %a}@]@," (Aux.rev_assoc pnames player)
- (fun f (payoff, moves) ->
- Format.fprintf f "@[<1>PAYOFF@ @[<1>%a@]@]@ "
- (Formula.fprint_real(* _nobra 0 *)) payoff;
- if moves <> [] then
- Format.fprintf f "@[<1>MOVES@ %a@]@ "
- (Aux.fprint_sep_list ";" (fun f ({
- lb_rule=r; time_in=(t_l, t_r); parameters_in=params}, target) ->
- Format.fprintf f "[@,@[<1>%s" r;
- if t_l <> cDEFAULT_TIMESTEP || t_r <> cDEFAULT_TIMESTEP then
- Format.fprintf f ",@ @[<1>t:@ %F@ --@ %F@]" t_l t_r;
- if params <> [] then
- Format.fprintf f ",@ %a"
- (Aux.fprint_sep_list "," (fun f (pn, (p_l, p_r)) ->
- Format.fprintf f "@[<1>%s:@ %F@ --@ %F@]" pn p_l p_r)) params;
- Format.fprintf f "@ ->@ %d@]@,]" target)) moves
- ) (in_p, in_m)
-
-let fprint_loc_body struc pnames f loc =
- Array.iteri (fun p l -> fprint_loc_body_in struc pnames f p l) loc
-
-let equational_def_style = ref true
-
-let fprint_game_move f ({mv_time = t; parameters = pl; rule = rn;
- next_loc = l; matching = m}, rtime) =
- let m_s = String.concat ", "
- (List.map (fun (e, x) -> Printf.sprintf "%s: %i" e x) m) in
- let rt = match rtime with None -> "" | Some f -> " " ^ (string_of_float f) in
- if (pl = []) then
- Format.fprintf f "@[<1>[%s@ %F@ ->@ %i@ emb@ %s]%s@]" rn t l m_s rt
- else (
- let p_s = String.concat ", "
- (List.map (fun (p, v) -> Printf.sprintf "%s: %F" p v) pl) in
- Format.fprintf f "@[<1>[%s@ %F,@ %s@ ->@ %i@ emb@ %s]%s@]" rn t p_s l m_s rt
- )
-
-let sprint_game_move gm = AuxIO.sprint_of_fprint fprint_game_move gm
-
-let fprint_state_full print_compiled_rules ppf
- ({rules = rules;
- graph = graph;
- num_players = num_players;
- player_names = player_names;
- data = data;
- defined_rels = defined_rels;
- },
- {struc = struc;
- time = time;
- cur_loc = cur_loc;
- history = hist;
- }) =
- Format.fprintf ppf "@[<v>";
- List.iter (fun (drel, (args, body)) ->
- if !equational_def_style then
- Format.fprintf ppf "@[<1>REL@ %s@,(@[<1>%a@])@ =@ @[<1>%a@]"
- drel (Aux.fprint_sep_list "," Format.pp_print_string) args
- Formula.fprint body
- else
- Format.fprintf ppf "@[<1>REL@ %s@,(@[<1>%a@])@ {@,@[<1>%a@,@]}"
- drel (Aux.fprint_sep_list "," Format.pp_print_string) args
- Formula.fprint body;
- Format.fprintf ppf "@]@ ";
- ) defined_rels;
- Format.fprintf ppf "@[<1>PLAYERS@ %a@]@ "
- (Aux.fprint_sep_list "," Format.pp_print_string)
- (List.map fst (List.sort (fun (_,x) (_,y) -> x-y) player_names));
- if data <> [] then
- Format.fprintf ppf "@[<1>DATA@ %a@]@ "
- (Aux.fprint_sep_list ","
- (fun ppf (k,v) -> Format.fprintf ppf "@[<1>%s@,:@ %s@]" k v))
- data;
- List.iter (fun (rname, r) ->
- Format.fprintf ppf "@[<1>RULE %s:@ %a@]@ " rname
- (ContinuousRule.fprint_full print_compiled_rules) r) rules;
- Array.iteri (fun loc_id loc ->
- Format.fprintf ppf "@[<0>LOC@ %d@ {@,@[<2> %a@]@]@,}@ "
- loc_id (fprint_loc_body struc player_names) loc) graph;
- Format.fprintf ppf "@[<1>MODEL@ %a@]@ "
- (Structure.fprint ~show_empty:true) struc;
- if (hist <> []) then
- Format.fprintf ppf "@[<1>MOVES@ %a@]@ "
- (Aux.fprint_sep_list ";\n" fprint_game_move) hist;
- if cur_loc <> 0 then
- Format.fprintf ppf "@[<1>STATE LOC@ %d@]@ " cur_loc;
- if time <> 0. then
- Format.fprintf ppf "@[<1>TIME@ %F@]@ " time;
- Format.fprintf ppf "@]"
-
-let fprint_state = fprint_state_full false
-let print_state r = AuxIO.print_of_fprint (fprint_state_full false) r
-let sprint_state r = AuxIO.sprint_of_fprint (fprint_state_full false) r
-let sprint_state_full r = AuxIO.sprint_of_fprint (fprint_state_full true) r
-let str game = sprint_state (game, snd empty_state)
-let state_str state = sprint_state state
-
(* -------------------- WHOLE ARENA MANIPULATION -------------------- *)
let add_new_player (state_game, state) pname =
@@ -549,6 +581,105 @@
with Diff_result expl -> false, expl
+
+(* -------- Move definition, generation and helper functions. ------- *)
+
+
+(* TODO: Sampling grid size fixed until doing more with continuous games. *)
+let cGRID_SIZE = 5
+
+
+(* Generate moves available from a state, as an array, in fixed order. *)
+let gen_moves grid_size rules model loc =
+ let matchings =
+ Aux.concat_map
+ (fun (label,next_loc) ->
+ let rule = List.assoc label.lb_rule rules in
+ List.map (fun emb -> label,next_loc,emb)
+ (ContinuousRule.matches model rule))
+ loc.moves in
+ if matchings = [] then [| |] else (
+ (* generating the grid *)
+ Array.concat
+ (List.map (fun (label,next_loc,emb) ->
+ (* not searching through time *)
+ let t_l, t_r = label.time_in in
+ let t = (t_r +. t_l) /. 2. in
+ if label.parameters_in = [] then
+ [| {
+ mv_time = t;
+ parameters = [];
+ rule = label.lb_rule;
+ next_loc = next_loc;
+ matching = emb
+ } |]
+ else
+ let param_names, params_in =
+ List.split label.parameters_in in
+ let axes = List.map (fun (f_l,f_r) ->
+ if grid_size < 2 then
+ [(f_r +. f_l) /. 2.]
+ else
+ let df = (f_r -. f_l) /. float_of_int (grid_size - 1) in
+ Array.to_list
+ (Array.init grid_size
+ (fun i -> f_l +. float_of_int i *. df))
+ ) params_in in
+ let grid = Aux.product axes in
+ Aux.array_map_of_list (fun params -> {
+ mv_time = t;
+ parameters = List.combine param_names params;
+ rule = label.lb_rule;
+ next_loc = next_loc;
+ matching = emb}
+ ) grid
+ ) matchings))
+
+(* Check if the before-part of the precondition of the rule holds on history. *)
+let check_history_pre r hist =
+ match r.DiscreteRule.struc_rule with
+ | None -> true
+ | Some sr ->
+ let prev_list = snd (sr.DiscreteRule.pre) in
+ let constraint_satisfied (rname, b) =
+ List.exists (fun (mv, _) -> mv.rule = rname) hist = b in
+ List.for_all constraint_satisfied prev_list
+
+let gen_models_list rules state time moves =
+ Aux.map_some (fun mv ->
+ let rule = List.assoc mv.rule rules in
+ if check_history_pre rule.ContinuousRule.discrete state.history then
+ Aux.map_option
+ (fun (model, time, _) -> (* ignoring shifts, i.e. animation steps *)
+ (mv,
+ {cur_loc = mv.next_loc;
+ history = (mv, None) :: state.history;
+ struc = model;
+ time = time}))
+ (ContinuousRule.rewrite_single state.struc time mv.matching
+ rule mv.mv_time mv.parameters)
+ else None) (Array.to_list moves)
+
+let gen_models rules state time moves =
+ let res = gen_models_list rules state time moves in
+ let moves, states = List.split res in
+ Array.of_list moves, Array.of_list states
+
+let list_moves game s =
+ let select_moving a =
+ let pls = Aux.array_argfind_all (fun l -> l.moves <> []) a in
+ if pls = [] then [0] else pls in
+ let loc = game.graph.(s.cur_loc) in
+ let moving = select_moving loc in
+ let get_moves pl =
+ let m = gen_moves cGRID_SIZE game.rules s.struc loc.(pl) in
+ (gen_models_list game.rules s s.time m) in
+ Array.of_list (List.concat (
+ List.map (fun p -> List.map (fun (a,b) -> (p,a,b)) (get_moves p)) moving))
+
+
+
+
let apply_rule_int (state_game, state) (r_name, mtch, t, p) =
(let try r = List.assoc r_name state_game.rules in (
match ContinuousRule.rewrite_single state.struc state.time mtch r t p with
@@ -566,3 +697,38 @@
with Not_found ->
((state_game, state), "ERR applying " ^ r_name ^ ", rule not found")
)
+
+
+exception Found of int
+
+(* Players are indexed from 1 in graph (0 is Environment) *)
+let apply_rewrite (game,state as gstate) (player, (r_name, mtch)) =
+ if r_name <> "" then (
+ let {rules=rules; graph=graph} = game in
+ let struc = state.struc in
+ let mv_loc = graph.(state.cur_loc).(player) in
+ let moves = gen_moves cGRID_SIZE rules struc mv_loc in
+ LOG 1 "apply_rewrite: r_name=%s; mtch=%s; player=%d; prules=%s; moves= %s"
+ r_name (ContinuousRule.matching_str struc mtch) player
+ (String.concat ", " (List.map (fun (lb,_) -> lb.lb_rule) mv_loc.moves))
+ (String.concat "; " (List.map (fun m ->
+ m.rule ^ ":" ^ ContinuousRule.matching_str struc m.matching
+ ) (Array.to_list moves)));
+ let pos = (
+ try
+ for i = 0 to Array.length moves - 1 do
+ let mov = moves.(i) in
+ if r_name = mov.rule && List.for_all
+ (fun (e, f) -> f = List.assoc e mov.matching) mtch then
+ raise (Found i)
+ done;
+ LOG 1 "apply_rewrite: failed for pl. num %d, r_name=%s\n%!"
+ player r_name;
+ failwith "GDL Play request: action mismatched with play state"
+ with Found pos -> pos) in
+ let (new_state_noloc, resp) =
+ apply_rule_int gstate (r_name, mtch, 0.1, []) in
+ let new_loc = moves.(pos).next_loc in
+ (fst new_state_noloc,
+ {snd new_state_noloc with cur_loc = new_loc})
+ ) else gstate
Modified: trunk/Toss/Arena/Arena.mli
===================================================================
--- trunk/Toss/Arena/Arena.mli 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Arena/Arena.mli 2012-03-09 18:42:39 UTC (rev 1687)
@@ -84,14 +84,20 @@
syntax. Defaults to [true]. *)
val equational_def_style : bool ref
-val fprint_state_full :
+val fprint_state_full : ?ext_struct : bool ->
bool -> Format.formatter -> game * game_state -> unit
val fprint_state : Format.formatter -> game * game_state -> unit
val print_state : game * game_state -> unit
val sprint_state : game * game_state -> string
+(** Print the structure in extensive form. *)
+val sprint_state_ext : game * game_state -> string
(** For the rules of the game, also print their compiled forms. *)
val sprint_state_full : game * game_state -> string
+val sprint_game_move : Structure.structure -> move * float option -> string
+val game_move_str : Structure.structure -> move -> string
+val game_move_gs_str : game_state -> move -> string
+
(** The order of following entries matters: [DefPlayers] adds more
players, with consecutive numbers starting from first available;
later [StateStruc], [StateTime] and [StateLoc] entries override
@@ -161,6 +167,33 @@
game * game_state -> game * game_state -> bool * string
+
+(** {2 Move definition, generation and helper functions.} *)
+
+(** Default number of sample points per parameter in tree search.
+ TODO: fixed for now. *)
+val cGRID_SIZE : int
+
+(** Generate moves available from a state, as an array, in fixed
+ order. Does not check postconditions. *)
+val gen_moves : int -> (string * ContinuousRule.rule) list ->
+ Structure.structure -> player_loc -> move array
+
+(** Given moves available from a state, keep those for which
+ postconditions pass, and return the respective resulting game states. *)
+val gen_models : (string * ContinuousRule.rule) list -> game_state ->
+ float -> move array -> move array * game_state array
+
+(** Get moves and resulting game states, like {!Move.gen_models}, but for
+ all rules the players can apply in the given game state. Returns
+ the player together with a move. *)
+val list_moves : game -> game_state -> (int * move * game_state) array
+
+
val apply_rule_int : game * game_state ->
string * (string * int) list * float * (string * float) list ->
(game * game_state) * string
+
+
+val apply_rewrite : game * game_state ->
+ int * (string * DiscreteRule.matching) -> game * game_state
Modified: trunk/Toss/Arena/ArenaTest.ml
===================================================================
--- trunk/Toss/Arena/ArenaTest.ml 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Arena/ArenaTest.ml 2012-03-09 18:42:39 UTC (rev 1687)
@@ -77,5 +77,19 @@
assert_equal ~printer:(fun x->x) ~msg:"from file, curly braces style"
contents (Arena.sprint_state gs);
);
+
+ "move to string" >::
+ (fun () ->
+ let mv = {
+ Arena.mv_time = 0.;
+ parameters = [];
+ rule = "rule";
+ next_loc = 1;
+ matching = [("x", 1)];
+ } in
+ let s = Structure.empty_structure () in
+ assert_equal ~printer:(fun x -> x) (Arena.game_move_str s mv)
+ "[rule 0. -> 1 emb x: 1]"
+ );
]
Modified: trunk/Toss/Client/JsHandler.ml
===================================================================
--- trunk/Toss/Client/JsHandler.ml 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Client/JsHandler.ml 2012-03-09 18:42:39 UTC (rev 1687)
@@ -235,7 +235,7 @@
let game, state = game_data.game_state in
cur_game := game_data;
play_states := [state];
- cur_all_moves := Move.list_moves game state;
+ cur_all_moves := Arena.list_moves game state;
cur_move := 0;
LOG 1 "new_play (%s): calling js_of_game_state." game_name;
js_of_game_state game state
@@ -260,7 +260,7 @@
let (p, m, n_state) = !cur_all_moves.(move_id) in
let game, _ = !cur_game.game_state in
play_states := n_state :: !play_states;
- cur_all_moves := Move.list_moves game n_state;
+ cur_all_moves := Arena.list_moves game n_state;
cur_move := 0;
Js.some (js_of_game_state game n_state)
@@ -282,7 +282,7 @@
let hs a = String.concat "#" (Array.to_list (Array.map Formula.real_str a)) in
let h= String.concat "#" (Array.to_list (Array.map hs !cur_game.heuristic)) in
js(Printf.sprintf "%f#%s#%s" (Js.to_float timeout)
- (Arena.state_str (game, state)) h)
+ (Arena.sprint_state_ext (game, state)) h)
let _ = set_handle "gameinfo" game_info
@@ -325,7 +325,7 @@
let game, _ = !cur_game.game_state in
let move_s, state = of_js move_js, List.hd !play_states in
let move_id = Aux.array_argfind
- (fun (_, m, _) -> Move.move_gs_str state m = move_s) !cur_all_moves in
+ (fun (_,m,_) -> Arena.game_move_gs_str state m = move_s) !cur_all_moves in
let result =
js_of_move game state move_id (!cur_all_moves.(move_id)) in
Js.Unsafe.set result (js"comp_iters")
Modified: trunk/Toss/Client/Main.js
===================================================================
--- trunk/Toss/Client/Main.js 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Client/Main.js 2012-03-09 18:42:39 UTC (rev 1687)
@@ -1,441 +1,41 @@
-// JavaScript Toss Module -- Main (requires Connect.js, State.js, Play.js)
+// JavaScript Toss Module -- Main (requires State.js, Play.js)
var UNAME = "";
var GAME_NAME = ""; // name of current game, e.g. "Breakthrough"
-var PLAYS = [];
-var CUR_PLAY_I = -1;
+var PLAY = [];
-var FRIENDS = []
-var UNAME_TO_NAME_MAP = {}
-
-var MAX_OPNT_LEN = 20;
-var FULL_OPNT_LEN = 0;
-var CUR_OPNT_START = 0;
-
var SIMPLE_SET = false;
function disp_name (uname) {
if (uname == "guest") { return ("You"); }
if (uname == "computer") { return ("Computer"); }
- if (typeof CONN == 'undefined') { return ("Player " + uname); }
- if (UNAME_TO_NAME_MAP[uname]) { return (UNAME_TO_NAME_MAP[uname]); }
- name = CONN.get_name (uname);
- UNAME_TO_NAME_MAP[uname] = name;
- return (name);
+ return ("Player " + uname);
}
nameDISP = disp_name;
function handle_elem_click (elem) {
- PLAYS[CUR_PLAY_I].handle_click (elem);
+ PLAY.handle_click (elem);
}
function make_move () {
- PLAYS[CUR_PLAY_I].move ();
+ PLAY.move ();
}
function make_move_continue (info) {
var suggest_f = function (time) { suggest_move_async (time, make_move) };
- PLAYS[CUR_PLAY_I].move_continue (info, suggest_f);
+ PLAY.move_continue (info, suggest_f);
}
function prev_move_click () {
- PLAYS[CUR_PLAY_I].prev_move ();
+ PLAY.prev_move ();
}
function next_move_click () {
- PLAYS[CUR_PLAY_I].next_move ();
+ PLAY.next_move ();
}
-var GAMES = new Array(
- /* "Concurrent-Tic-Tac-Toe" */
- "Breakthrough",
- "Checkers",
- "Chess",
- "Connect4",
- "Entanglement",
- "Gomoku",
- "Pawn-Whopping",
- "Tic-Tac-Toe"
-);
-
-var GAMESPAGE = undefined;
-
-
-function GamesPage(id, games){ // html tag id
- this.games = games;
- this.paragraphs = new Object();
- this.container = document.getElementById (id);
- for (var i = 0; i < this.games.length; i++) {
- var game = this.games[i];
-
- var paragraph = document.createElement("p");
- this.paragraphs[game] = paragraph;
- paragraph.setAttribute("class", "game-par");
- this.container.appendChild (paragraph);
-
- var button = document.createElement("button");
- paragraph.game_button = button;
- button.setAttribute("class", "gamebt");
- button.setAttribute("onclick", "new_play('" + game + "')");
- button.innerHTML = game;
- button.style.display = "block";
- paragraph.appendChild (button);
-
- var open_play_list = document.createElement("ul");
- paragraph.open_play_list = open_play_list;
- open_play_list.setAttribute("class", "plays-list");
- open_play_list.setAttribute("id", "a-plays-list-" + game);
- paragraph.appendChild (open_play_list);
-
- var closed_plays = document.createElement("div");
- paragraph.closed_plays = closed_plays;
- closed_plays.setAttribute("id", "d-plays-div-" + game);
-
- var completed_bt = document.createElement("button");
- paragraph.completed_button = completed_bt;
- completed_bt.setAttribute("class", "completedbt");
- completed_bt.setAttribute("onclick",
- "GAMESPAGE.toggle_completed ('" +game+ "')");
- completed_bt.innerHTML = "Completed games (Show)";
- closed_plays.appendChild (completed_bt);
-
- var learn_button = document.createElement("button");
- paragraph.learn_button = learn_button;
- learn_button.setAttribute("class", "completedbt");
- learn_button.setAttribute("onclick",
- "GAMESPAGE.learn_game ('" + game + "')");
- learn_button.innerHTML = "Learn";
- learn_button.style.display = "none";
- closed_plays.appendChild (learn_button);
-
- var closed_play_list = document.createElement("ul");
- paragraph.closed_play_list = closed_play_list;
- closed_play_list.setAttribute("class", "plays-list");
- closed_play_list.setAttribute("id", "d-plays-list-" + game);
- closed_play_list.style.display = "none";
- closed_plays.appendChild (closed_play_list);
-
- closed_plays.style.display = "none";
- paragraph.appendChild (closed_plays);
-
- var edit_div = document.createElement("div");
- paragraph.edit_div = edit_div;
- edit_div.setAttribute("id", "edit-div-" + game);
- edit_div.setAttribute("class", "edit-div");
-
- var edit_button = document.createElement("button");
- paragraph.edit_button = edit_button;
- edit_button.setAttribute("class", "completedbt");
- edit_button.setAttribute("onclick",
- "GAMESPAGE.toggle_edit ('" + game + "')");
- edit_button.innerHTML = "Edit " + game + " (Show)";
- edit_div.appendChild (edit_button);
-
- var edit_save_button = document.createElement("button");
- paragraph.edit_save_button = edit_save_button;
- edit_save_button.setAttribute("class", "completedbt");
- edit_save_button.setAttribute("onclick",
- "GAMESPAGE.save_edit ('" + game + "')");
- edit_save_button.innerHTML = "Save";
- edit_save_button.style.display = "none";
- edit_div.appendChild (edit_save_button);
-
- var edit_area = document.createElement("textarea");
- edit_area.setAttribute("class", "edit-area");
- paragraph.edit_area = edit_area;
- edit_div.appendChild (edit_area);
- edit_area.style.display = "none";
- if (typeof CONN != 'undefined')
- edit_area.value = CONN.get_game (game);
- else ASYNCH ("get_game", [game],
- function (v) {edit_area.value = v});
- paragraph.appendChild (edit_div);
-
- paragraph.completed_shown = false;
- paragraph.edit_shown = false;
- this.container.appendChild (paragraph);
- }
- return (this);
-}
-
-GamesPage.prototype.show = function () {
- this.container.style.display = "block";
-}
-
-GamesPage.prototype.hide = function () {
- this.container.style.display = "none";
-}
-
-GamesPage.prototype.show_completed = function (game) {
- this.paragraphs[game].closed_plays.style.display = "block";
-}
-
-GamesPage.prototype.hide_completed = function (game) {
- this.paragraphs[game].closed_plays.style.display = "none";
-}
-
-GamesPage.prototype.learn_game = function (game) {
- if (typeof CONN == 'undefined') {
- alert ("Learing not implemented for the ASYNCH interface");
- return;
- }
- var lst = CONN.list_plays (game, UNAME);
- var lst_plays = parse_list ('##', lst);
- var plays = "$";
- for (var i = 0; i < lst_plays.length; i++) {
- lst_plays[i] = play_from_string (game, lst_plays[i]);
- if (lst_plays[i].cur_state.result != null) {
- var pid = lst_plays[i].pid;
- var val = document.getElementById ("select_" + pid).value;
- if (val != -1) plays += pid + ":" + val + "$";
- }
- }
- var res = CONN.learn_game (game, plays)
- alert (res);
-}
-
-GamesPage.prototype.toggle_completed = function (game) {
- var par = this.paragraphs[game];
- if (par.completed_shown) {
- par.closed_play_list.style.display = "none";
- par.learn_button.style.display = "none";
- par.completed_button.innerHTML = "Completed games (Show)";
- par.completed_shown = false;
- } else {
- par.closed_play_list.style.display = "block";
- //par.learn_button.style.display = "inline"; skip for now
- par.completed_button.innerHTML = "Completed games (Hide)";
- par.completed_shown = true;
- }
-}
-
-GamesPage.prototype.toggle_edit = function (game) {
- var par = this.paragraphs[game];
- if (par.edit_shown) {
- par.edit_area.style.display = "none";
- par.edit_save_button.style.display = "none";
- par.edit_button.innerHTML = "Edit " + game + " (Show)";
- par.edit_shown = false;
- } else {
- par.edit_area.style.display = "block";
- par.edit_save_button.style.display = "inline";
- par.edit_button.innerHTML = "Edit " + game + " (Hide)";
- par.edit_shown = true;
- }
-}
-
-GamesPage.prototype.save_edit = function (game) {
- if (typeof CONN != 'undefined')
- alert (CONN.set_game (game, this.paragraphs[game].edit_area.value));
- else ASYNCH ("set_game", [game, this.paragraphs[game].edit_area.value],
- function (s) {alert (s)});
-}
-
-function play_from_string (game, s) {
- var p = s.substring(game.length + 1);
- var lst = parse_list ('#', p);
- return (new Play (game, [0, 1], [lst[0], lst[1]],
- lst[2], lst[3], lst[4], UNAME));
-}
-
-// Play lists on display.
-function new_play_item (game, i) {
- var li = document.createElement('li');
- li.setAttribute ("class", "plays-list-elem");
- li.setAttribute ("id", "plays-list-" + game + "-elem-" + i);
- var pname = disp_name(PLAYS[i].players[0]) +" vs " +
- disp_name(PLAYS[i].players[1]) + " (game " + PLAYS[i].pid + ')';
- var bs = '<button class="obt" title="Open game ' + PLAYS[i].pid +
- '" onclick="'+ "play_click('" + game + "', " + PLAYS[i].pid + ", " +
- i + ')">' + pname + '</button> ';
- if (PLAYS[i].cur_state.result != null) { // completed game
- li.innerHTML = bs;
- li.innerHTML += '<span class="list_result">' +
- PLAYS[i].get_formatted_result_string() + '</span>';
- li.innerHTML += ' <span class="play_learn">' +
- "Learning:</span>";
- li.innerHTML +=
- '<select class="play_select" id="select_' + PLAYS[i].pid + '">' +
- '<option class="play_select_opt" value="-1">skip</option>' +
- '<option class="play_select_opt" value="0">wins0</option>' +
- '<option class="play_select_opt" value="1">wins1</option>' +
- '<option class="play_select_opt" value="2">notwon</option>' +
- '<option class="play_select_opt" value="3">wrong</option></select>';
- } else {
- li.innerHTML = bs;
- }
- return (li);
-}
-
-
-function list_plays_string (game, lst) {
- PLAYS = parse_list ('##', lst);
- var a_plist = document.getElementById ("a-plays-list-" + game);
- var d_plist = document.getElementById ("d-plays-list-" + game);
- while (a_plist.childNodes.length > 0) {
- a_plist.removeChild (a_plist.firstChild);
- }
- while (d_plist.childNodes.length > 0) {
- d_plist.removeChild (d_plist.firstChild);
- }
- for (var i = 0; i < PLAYS.length; i++) {
- PLAYS[i] = play_from_string (game, PLAYS[i]);
- if (PLAYS[i].cur_state.payoff == "") {
- a_plist.appendChild (new_play_item (game, i));
- } else {
- d_plist.appendChild (new_play_item (game, i));
- }
- }
- if (d_plist.childNodes.length > 0) { GAMESPAGE.show_completed (game); }
-}
-
-function list_plays (game) {
- if (typeof CONN == 'undefined') {
- alert ("Multiple plays not implemented in ASYNCH interface.");
- return;
- }
- var lst = CONN.list_plays (game, UNAME);
- list_plays_string (game, lst);
-}
-
-
-function play_click (game, play_id, pi) {
- document.getElementById ("opponents").style.display = "none";
- document.getElementById ("game-desc-controls").style.display = "block";
- GAME_NAME = game;
- list_plays (game);
- document.getElementById ("welcome").style.display = "none";
- document.getElementById ("game-disp").style.display = "none";
- document.getElementById ("plays").style.display = "none";
- var gd = document.getElementById ("game-disp");
- gd.style.display = "block";
- gd.setAttribute ("class", "Game-" + game);
- document.getElementById ("game-title").innerHTML = game;
- document.getElementById ("game-disp").style.display = "block";
- document.getElementById ("play-number").innerHTML = "" + play_id;
- document.getElementById ("suggestions-toggle").style.display = "inline";
- CUR_PLAY_I = pi;
- PLAYS[CUR_PLAY_I].redraw ();
-}
-
-
-function del_play (play) {
- alert ("Deleting " + play);
-}
-
-function opponent_item (uid, index) {
- var li = document.createElement('li');
- li.setAttribute ("class", "opponents-list-elem");
- li.setAttribute ("id", "opponent-" + uid); // + "-" + index
- li.innerHTML =
- '<button class="dbt" onclick="new_play_do(' + "'" + uid + "'" + ')">'+
- disp_name(uid) + ' (' + uid + ') </button>';
- return (li);
-}
-
-function data_cmp (d1, d2) {
- if (d1.name < d2.name) { return -1; }
- if (d1.name > d2.name) { return 1; }
- return (0);
-}
-
-function make_opnt_list () {
- var o = document.getElementById ("opponents-list");
- FULL_OPNT_LEN = FRIENDS.length + 1;
- CUR_OPNT_START = 0;
- document.getElementById ("opponents-prev").style.display = "none";
- if (MAX_OPNT_LEN > FULL_OPNT_LEN) {
- document.getElementById ("opponents-next").style.display = "none"
- }
- var zeroli = document.createElement('li');
- zeroli.setAttribute ("class", "opponents-list-elem");
- zeroli.setAttribute ("id", "opponent-" + "-0");
- zeroli.innerHTML = '<button class="dbt" onclick="new_play_do(-1)">' +
- 'Play against Yourself</button>';
- o.appendChild (zeroli);
- for (var i = 0; i < FRIENDS.length; i++) {
- var oi = opponent_item (FRIENDS[i], i+1);
- if (i > MAX_OPNT_LEN - 2) { oi.style.display = "none"; }
- o.appendChild (oi);
- }
- document.getElementById ("opponents").style.display = "block";
-}
-
-function new_play (game) {
- if (UNAME == "") { alert ("Please log in to create plays"); return; }
- GAME_NAME = game;
- var olist = document.getElementById ("opponents-list");
- while (olist.childNodes.length > 0) { olist.removeChild (olist.firstChild); }
- make_opnt_list ();
-}
-
-function opponents_next () {
- for (var i = CUR_OPNT_START; i < CUR_OPNT_START + MAX_OPNT_LEN; i++) {
- document.getElementById ("opponent-" + "-" + i).style.display = "none";
- }
- CUR_OPNT_START += MAX_OPNT_LEN;
- for (var i = CUR_OPNT_START; i < CUR_OPNT_START + MAX_OPNT_LEN; i++) {
- if (i < FULL_OPNT_LEN) {
- document.getElementById ("opponent-" + "-" + i).style.display = "list-item";
- }
- }
- document.getElementById ("opponents-prev").style.display = "block"
- if (CUR_OPNT_START + MAX_OPNT_LEN > FULL_OPNT_LEN) {
- document.getElementById ("opponents-next").style.display = "none"
- }
-}
-
-function opponents_prev () {
- for (var i = CUR_OPNT_START; i < CUR_OPNT_START + MAX_OPNT_LEN; i++) {
- if (i < FULL_OPNT_LEN) {
- document.getElementById ("opponent-" + "-" + i).style.display = "none";
- }
- }
- CUR_OPNT_START -= MAX_OPNT_LEN;
- for (var i = CUR_OPNT_START; i < CUR_OPNT_START + MAX_OPNT_LEN; i++) {
- document.getElementById ("opponent-" + "-" + i).style.display = "list-item";
- }
- document.getElementById ("opponents-next").style.display = "block"
- if (CUR_OPNT_START == 0) {
- document.getElementById ("opponents-prev").style.display = "none"
- }
-}
-
-function show_chess_warning () {
- document.getElementById ("chess-level-warning").style.display = "block";
-}
-
-function hide_chess_warning () {
- document.getElementById ("chess-level-warning").style.display = "none";
-}
-
-function new_play_guest (game) {
- GAME_NAME = game;
- UNAME = "guest";
- document.getElementById ("topuser").innerHTML = game;
- document.getElementById ("game-title").style.display = "none";
- document.getElementById ("game-title-move").style.display = "none";
- document.getElementById ("game-info-par").style.paddingBottom = "1em";
- document.getElementById ("loginform").style.display = "none";
- document.getElementById ("topright-register").style.display = "none";
- document.getElementById ("topright").style.display = "inline";
- document.getElementById ("logouttab").style.display = "none";
- document.getElementById ("profiletab").style.display = "none";
- document.getElementById ("welcome").style.display = "none";
- if (game == "Chess") {
- if (typeof CONN == 'undefined') {
- alert ('Chess is not available using local Toss');
- return;
- } else {
- show_chess_warning ();
- setTimeout("hide_chess_warning ()", 3000);
- }
- }
- new_play_do ("computer");
-}
-
function startup_local () {
// should do some work here perhaps
}
@@ -448,36 +48,20 @@
document.getElementById ("game-title-move").style.display = "none";
document.getElementById ("game-info-par").style.paddingBottom = "1em";
document.getElementById ("welcome").style.display = "none";
- if (game == "Chess") {
- show_chess_warning ();
- setTimeout("hide_chess_warning ()", 3000);
- }
- new_play_do ("computer");
+ new_play_do ("computer", function () { });
}
-function new_play_do (opp_uid) {
+function new_play_do (opp_uid, continuation) {
document.getElementById ("working").innerHTML = "Loading "+GAME_NAME+"...";
document.getElementById ("working").style.display = "block";
- if (typeof CONN != 'undefined') {
- list_plays (GAME_NAME);
- document.getElementById ("opponents").style.display = "none";
- document.getElementById ("plays").style.display = "none";
- }
document.getElementById ("welcome").style.display = "none";
document.getElementById ("game-disp").style.display = "none";
var gd = document.getElementById ("game-disp");
gd.style.display = "block";
gd.setAttribute ("class", "Game-" + GAME_NAME);
document.getElementById ("game-title").innerHTML = GAME_NAME;
- if (typeof CONN != 'undefined') {
- var olist = document.getElementById ("opponents-list");
- while (olist.childNodes.length > 0)
- { olist.removeChild (olist.firstChild); }
- }
- if (opp_uid == -1) { opp_uid = UNAME; }
- if (opp_uid == 0 || UNAME == "") { return; }
- //document.getElementById("plays-list-"+GAME_NAME).style.display = "block";
document.getElementById ("suggestions-toggle").style.display = "none";
+ FREE_PLAY_NO = 1;
var state_str;
// state_str is either a state string, or a record of state data
var build_play = function (state_str) {
@@ -485,30 +69,18 @@
document.getElementById ("game-desc-controls").style.display = "block";
document.getElementById ("suggestions-toggle").style.display = "inline";
document.getElementById ("play-number").innerHTML = "" + FREE_PLAY_NO;
- CUR_PLAY_I = PLAYS.length;
document.getElementById ("game-disp").style.display = "block";
document.getElementById ("plays").style.left = "30em";
var p = new Play (GAME_NAME, [0,1], [UNAME, opp_uid], FREE_PLAY_NO, 0,
state_str, UNAME);
console.log ("new_play_do callback: play created");
- PLAYS.push(p);
+ PLAY = p;
p.redraw ();
ASYNCH ("precache", [0.5], function () {});
- //li = new_play_item (GAME_NAME, CUR_PLAY_I);
- //document.getElementById ("plays-list-" + GAME_NAME).appendChild (li);
+ continuation ();
}
- // compute FREE_PLAY_NO and state_str
- if (typeof CONN == 'undefined') {
- FREE_PLAY_NO = 0;
- // LOCAL.new_play returns info_obj (not a string)
- ASYNCH ("new_play", [GAME_NAME, UNAME, opp_uid], build_play);
- } else {
- info_nbr = CONN.new_play (GAME_NAME, UNAME, opp_uid);
- info_idx = info_nbr.indexOf('$');
- FREE_PLAY_NO = parseInt(info_nbr.substring(0, info_idx));
- state_str = info_nbr.substring(info_idx+1);
- build_play (state_str);
- }
+ // LOCAL.new_play returns info_obj (not a string)
+ ASYNCH ("new_play", [GAME_NAME, UNAME, opp_uid], build_play);
}
function play_anew (me_starts) {
@@ -520,28 +92,27 @@
};
toggle_suggestions ();
toggle_suggestions ();
- PLAYS[CUR_PLAY_I].clear ();
+ PLAY.clear ();
document.getElementById ('cur-move').innerHTML = "none";
if (me_starts) {
- var opp = PLAYS[CUR_PLAY_I].players[1];
- if (PLAYS[CUR_PLAY_I].players[0] != UNAME) {
- opp = PLAYS[CUR_PLAY_I].players[0];
+ var opp = PLAY.players[1];
+ if (PLAY.players[0] != UNAME) {
+ opp = PLAY.players[0];
}
- new_play_do (opp);
+ new_play_do (opp, function () { });
} else {
- var opp = PLAYS[CUR_PLAY_I].players[1];
- if (PLAYS[CUR_PLAY_I].players[0] != UNAME) {
- opp = PLAYS[CUR_PLAY_I].players[0];
+ var opp = PLAY.players[1];
+ if (PLAY.players[0] != UNAME) {
+ opp = PLAY.players[0];
}
var me = UNAME;
UNAME = opp;
- new_play_do (me);
- UNAME = me;
- PLAYS[CUR_PLAY_I].cur_player_uid = UNAME;
- if (opp == "computer") {
+ new_play_do (me, function () {
+ UNAME = me;
+ PLAY.cur_player_uid = UNAME;
var mv_time = document.getElementById ("speed").value;
suggest_move_async (mv_time, make_move);
- }
+ });
}
}
@@ -554,7 +125,7 @@
function show_moving_msg (n) {
if (n > 1) {
- document.getElementById ("working").innerHTML = "Moving in "+ n+ "s ...";
+ document.getElementById ("working").innerHTML= "Moving in "+ n+ "s ...";
document.getElementById ("working").style.display = "block";
setTimeout("decrease_moving(" + (n-1) + ")", 1000);
}
@@ -588,37 +159,44 @@
xml_request.send (msg);
}
+var DONE_MOVES_MARKER = {}
+var MOVE_INDEX = 0
function suggest_move_async (time, f) {
show_moving_msg (time);
var fm = function (m) {
document.getElementById("working").style.display = "none";
document.getElementById("working").innerHTML = "Working...";
- if (typeof m.comp_tree_size != 'undefined' && SIMPLE_MOVES == false) {
- alert ("Algorithm performed " +m.comp_iters +" iterations.");
+ console.log ("Algorithm performed " +m.comp_iters +" iterations.");
+ if (m != "") { PLAY.show_move (new Move (m)); f() }
+ }
+ var fm_check = function (m) {
+ if (DONE_MOVES_MARKER[MOVE_INDEX] === false) {
+ DONE_MOVES_MARKER[MOVE_INDEX] = true;
+ fm (m);
+ } else {
+ console.log ("Discarded " + m.comp_iters +" iterations.");
}
- if (m != "") { PLAYS[CUR_PLAY_I].show_move (new Move (m)); f() }
};
- if (typeof CONN != 'undefined') {
- CONN.suggest (PLAYS[CUR_PLAY_I].cur_state.players[0]+1, time,
- PLAYS[CUR_PLAY_I].pid, fm);
- } else {
- // ASYNCH does not implement multiple plays
- // I'm not sure about players being numbered from 1
- // anyway, player name is ignored in ASYNCH suggest
- if (typeof time == 'string') time = parseFloat (time);
- var server_move = function (msg) {
- async_server_msg (msg, false, function (resp) {
- ASYNCH ("suggested_move", [resp], fm) })
- }
- ASYNCH ("gameinfo", [time], server_move);
- //ASYNCH ("suggest",
- // [PLAYS[CUR_PLAY_I].cur_state.players[0]+1, time],
- // fm);
+ // ASYNCH does not implement multiple plays
+ // I'm not sure about players being numbered from 1
+ // anyway, player name is ignored in ASYNCH suggest
+ if (typeof time == 'string') time = parseFloat (time);
+ MOVE_INDEX = MOVE_INDEX + 1;
+ DONE_MOVES_MARKER[MOVE_INDEX] = false;
+ var server_move = function (msg) {
+ async_server_msg (msg, false, function (resp) {
+ if (resp !== "" && DONE_MOVES_MARKER[MOVE_INDEX] === false) {
+ DONE_MOVES_MARKER[MOVE_INDEX] = true;
+ ASYNCH ("suggested_move", [resp], fm)
+ } })
}
+ ASYNCH ("gameinfo", [time], server_move);
+ ASYNCH ("suggest", [PLAY.cur_state.players[0]+1,
+ time + .5], fm_check); // wait 0.5s for server
}
function suggest_move_click () {
- if (PLAYS[CUR_PLAY_I].move_nbr < PLAYS[CUR_PLAY_I].last_move_nbr) {return;}
+ if (PLAY.move_nbr < PLAY.last_move_nbr) {return;}
var mv_time = document.getElementById ("speed").value;
suggest_move_async (mv_time, function () {});
}
Modified: trunk/Toss/Client/Play.js
===================================================================
--- trunk/Toss/Client/Play.js 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Client/Play.js 2012-03-09 18:42:39 UTC (rev 1687)
@@ -148,12 +148,7 @@
return;
}
if (! SIMPLE_MOVES) { PlayDISP.busy (); }
- if (typeof CONN == 'undefined') {
- // there is only one play
- ASYNCH ("make_move", [this.CUR_MOVE.id], make_move_continue);
- } else {
- CONN.make_move (this.CUR_MOVE.def_str, this.pid, make_move_continue);
- }
+ ASYNCH ("make_move", [this.CUR_MOVE.id], make_move_continue);
}
Play.prototype.move = play_move;
@@ -161,9 +156,6 @@
PlayDISP.free ();
this.new_state (info);
this.redraw ();
- if (typeof info.comp_tree_size != 'undefined' && SIMPLE_MOVES == false) {
- alert ("Algorithm performed " +info.comp_iters + " iterations ");
- }
if (this.cur_state.players.length == 1 &&
this.players[this.cur_state.players[0]] == "computer") {
var mv_time = document.getElementById("speed").value;
Modified: trunk/Toss/Client/State.js
===================================================================
--- trunk/Toss/Client/State.js 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Client/State.js 2012-03-09 18:42:39 UTC (rev 1687)
@@ -222,6 +222,7 @@
// there are no moves.
if (!is_conn) {
if (typeof info_obj.result != 'undefined') {
+ this.players = [];
this.result = info_obj.result;
var payoffs = [];
for (var player in info_obj.result) {
@@ -236,6 +237,7 @@
mvs.push (new_mv);
if (! in_lst(pls, new_mv.player)) { pls.push (new_mv.player); }
}
+ console.log (pls);
this.moves = mvs;
this.players = pls;
this.payoff = "";
Modified: trunk/Toss/Client/Style.css
===================================================================
--- trunk/Toss/Client/Style.css 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Client/Style.css 2012-03-09 18:42:39 UTC (rev 1687)
@@ -665,6 +665,10 @@
padding-left: 1.5em;
}
+#welcome-list-main {
+ display: none;
+}
+
.welcome-list li {
margin-top: 0.5em;
}
Modified: trunk/Toss/Client/index.html
===================================================================
--- trunk/Toss/Client/index.html 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Client/index.html 2012-03-09 18:42:39 UTC (rev 1687)
@@ -30,12 +30,6 @@
</span>
</div>
-<div id="chess-level-warning">
-Chess is set to very weak play.</br>
-<br/>
-No training here, just have fun!
-</div>
-
<div id="welcome">
<p id="p-under-welcome" style="display: none;">
Strategic games are fun!
@@ -94,7 +88,7 @@
</button>
</p>
-<p style="width:100%; text-align: justify">
+<p id="moregames" style="width:100%; text-align: justify; display: none;">
<button onclick="new_play_local('Chess')" class="game-picbt"
class="boldobt" title="Play Chess">
<img style="max-width:95%" src="img/Chess.png"
@@ -137,6 +131,11 @@
<div id="news">
<h3>News</h3>
<ul id="welcome-list-news" class="welcome-list">
+<li><b>09/03/12</b> First completely working mostly-JS Toss version</li>
+<li><b>05/03/12</b> Fully integrated OCaml and JS debugging and logs</li>
+<li><b>27/02/12</b> Compiled resources to access files from JS</li>
+<li><b>18/02/12</b> Integrating OCaml and JS unit tests</li>
+<li><b>11/02/12</b> Starting systematic unit tests of JS interface</li>
<li><b>06/02/12</b> Toss release 0.7 with many improvements</li>
<li><b>04/02/12</b> Definitions use play history: new Chess toss file</li>
<li><b>02/02/12</b> Improved stand-alone JS interface with menhirLib</li>
Modified: trunk/Toss/GGP/TranslateGameTest.ml
===================================================================
--- trunk/Toss/GGP/TranslateGameTest.ml 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/GGP/TranslateGameTest.ml 2012-03-09 18:42:39 UTC (rev 1687)
@@ -102,7 +102,7 @@
let {Arena.rules=rules; graph=graph} = game in
let struc = state.Arena.struc in
let mv_loc = graph.(state.Arena.cur_loc).(player) in
- let moves = Move.gen_moves Move.cGRID_SIZE rules struc mv_loc in
+ let moves = Arena.gen_moves Arena.cGRID_SIZE rules struc mv_loc in
LOG 1 "apply_rewrite: r_name=%s; mtch=%s; player=%d; prules=%s; moves= %s"
r_name (ContinuousRule.matching_str struc mtch) player
(String.concat ", " (List.map (fun (lb,_)->lb.Arena.lb_rule)
Modified: trunk/Toss/Play/GameTree.ml
===================================================================
--- trunk/Toss/Play/GameTree.ml 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Play/GameTree.ml 2012-03-09 18:42:39 UTC (rev 1687)
@@ -84,7 +84,7 @@
| Leaf (state, player, info) ->
if timeout() then raise (Aux.Timeout "GameTree.unfold_abstract.leaf1");
Solver.M.set_timeout timeout;
- let moves = Move.list_moves game state in
+ let moves = Arena.list_moves game state in
if moves = [||] then (
Solver.M.clear_timeout();
if timeout() then raise (Aux.Timeout "GameTree.unfold_abstract.term");
@@ -239,7 +239,7 @@
let choose_moves game = function
| Terminal _ -> raise Not_found
| Leaf (state, _, _) ->
- List.map (fun (_,a,b) -> (a,b)) (Array.to_list (Move.list_moves game state))
+ List.map (fun (_,a,b)-> (a,b)) (Array.to_list (Arena.list_moves game state))
| Node (_, p, info, succ) ->
let cmp (_, c1) (_, c2) =
let nval child = (node_values child).(p) in
@@ -251,7 +251,7 @@
let maxs = if maxs_exact <> [] then maxs_exact else
Aux.array_find_all (fun (_,c) -> (node_values c).(p) = mval) succ in
let nonleaf = function Leaf _ -> false | _ -> true in
- let move_s (m, n) = Move.move_gs_str_short (state n) m in
+ let move_s (m, n) = Arena.game_move_gs_str (state n) m in
LOG 3"\nBest Moves: %s" (String.concat ", " (List.map move_s maxs));
if List.exists (fun x -> nonleaf (snd x)) maxs then (
List.map (fun (m, t) -> (m, state t)) maxs
Deleted: trunk/Toss/Play/Move.ml
===================================================================
--- trunk/Toss/Play/Move.ml 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Play/Move.ml 2012-03-09 18:42:39 UTC (rev 1687)
@@ -1,122 +0,0 @@
-(* Move definition, generation and helper functions. *)
-
-
-(* TODO: Sampling grid size fixed until doing more with continuous games. *)
-let cGRID_SIZE = 5
-
-
-(* Print a move as string.
- TODO: perhaps find a nicer syntax? See {!TestGame.move_str}. *)
-let move_str struc move =
- let fpstr (f, fv) =
- f ^ ": " ^ (string_of_float fv) in
- let par_str = if move.Arena.parameters = [] then " " else
- ", " ^ (String.concat ", " (List.map fpstr move.Arena.parameters)) in
- let p_name (r, e) =
- r ^": "^ Structure.elem_str struc e in
- let emb = String.concat ", " (List.map p_name move.Arena.matching) in
- (move.Arena.rule) ^ "; " ^ emb ^ "; " ^ fpstr ("t", move.Arena.mv_time) ^
- par_str ^ "; " ^ (string_of_int move.Arena.next_loc)
-
-let move_gs_str state move =
- move_str state.Arena.struc move
-
-
-(* Like move_str but simplified (less data, shorter form). *)
-let move_str_short struc move =
- let p_name (r, e) =
- r ^ ":" ^ Structure.elem_str struc e in
- let emb = String.concat ", "
- (List.map p_name (List.sort Pervasives.compare move.Arena.matching)) in
- move.Arena.rule ^ "{" ^ emb ^ "}"
-
-let move_gs_str_short state move = move_str_short state.Arena.struc move
-
-
-(* Generate moves available from a state, as an array, in fixed order. *)
-let gen_moves grid_size rules model loc =
- let matchings =
- Aux.concat_map
- (fun (label,next_loc) ->
- let rule = List.assoc label.Arena.lb_rule rules in
- List.map (fun emb -> label,next_loc,emb)
- (ContinuousRule.matches model rule))
- loc.Arena.moves in
- if matchings = [] then [| |] else (
- (* generating the grid *)
- Array.concat
- (List.map (fun (label,next_loc,emb) ->
- (* not searching through time *)
- let t_l, t_r = label.Arena.time_in in
- let t = (t_r +. t_l) /. 2. in
- if label.Arena.parameters_in = [] then
- [| {
- Arena.mv_time = t;
- parameters = [];
- rule = label.Arena.lb_rule;
- next_loc = next_loc;
- matching = emb
- } |]
- else
- let param_names, params_in =
- List.split label.Arena.parameters_in in
- let axes = List.map (fun (f_l,f_r) ->
- if grid_size < 2 then
- [(f_r +. f_l) /. 2.]
- else
- let df = (f_r -. f_l) /. float_of_int (grid_size - 1) in
- Array.to_list
- (Array.init grid_size
- (fun i -> f_l +. float_of_int i *. df))
- ) params_in in
- let grid = Aux.product axes in
- Aux.array_map_of_list (fun params -> {
- Arena.mv_time = t;
- parameters = List.combine param_names params;
- rule = label.Arena.lb_rule;
- next_loc = next_loc;
- matching = emb}
- ) grid
- ) matchings))
-
-(* Check if the before-part of the precondition of the rule holds on history. *)
-let check_history_pre r hist =
- match r.DiscreteRule.struc_rule with
- | None -> true
- | Some sr ->
- let prev_list = snd (sr.DiscreteRule.pre) in
- let constraint_satisfied (rname, b) =
- List.exists (fun (mv, _) -> mv.Arena.rule = rname) hist = b in
- List.for_all constraint_satisfied prev_list
-
-let gen_models_list rules state time moves =
- Aux.map_some (fun mv ->
- let rule = List.assoc mv.Arena.rule rules in
- if check_history_pre rule.ContinuousRule.discrete state.Arena.history then
- Aux.map_option
- (fun (model, time, _) -> (* ignoring shifts, i.e. animation steps *)
- (mv,
- {Arena.cur_loc = mv.Arena.next_loc;
- history = (mv, None) :: state.Arena.history;
- struc = model;
- time = time}))
- (ContinuousRule.rewrite_single state.Arena.struc time mv.Arena.matching
- rule mv.Arena.mv_time mv.Arena.parameters)
- else None) (Array.to_list moves)
-
-let gen_models rules state time moves =
- let res = gen_models_list rules state time moves in
- let moves, states = List.split res in
- Array.of_list moves, Array.of_list states
-
-let list_moves game s =
- let select_moving a =
- let pls = Aux.array_argfind_all (fun l -> l.Arena.moves <> []) a in
- if pls = [] then [0] else pls in
- let loc = game.Arena.graph.(s.Arena.cur_loc) in
- let moving = select_moving loc in
- let get_moves pl =
- let m = gen_moves cGRID_SIZE game.Arena.rules s.Arena.struc loc.(pl) in
- (gen_models_list game.Arena.rules s s.Arena.time m) in
- Array.of_list (List.concat (
- List.map (fun p -> List.map (fun (a,b) -> (p,a,b)) (get_moves p)) moving))
Deleted: trunk/Toss/Play/Move.mli
===================================================================
--- trunk/Toss/Play/Move.mli 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Play/Move.mli 2012-03-09 18:42:39 UTC (rev 1687)
@@ -1,29 +0,0 @@
-(** Move definition, generation and helper functions. *)
-
-val move_str :
- Structure.structure -> Arena.move -> string
-val move_gs_str : Arena.game_state -> Arena.move -> string
-
-val move_str_short : Structure.structure -> Arena.move -> string
-val move_gs_str_short : Arena.game_state -> Arena.move -> string
-
-
-(** Default number of sample points per parameter in tree search.
- TODO: fixed for now. *)
-val cGRID_SIZE : int
-
-(** Generate moves available from a state, as an array, in fixed
- order. Does not check postconditions. *)
-val gen_moves : int -> (string * ContinuousRule.rule) list ->
- Structure.structure -> Arena.player_loc -> Arena.move array
-
-(** Given moves available from a state, keep those for which
- postconditions pass, and return the respective resulting game states. *)
-val gen_models : (string * ContinuousRule.rule) list -> Arena.game_state ->
- float -> Arena.move array -> Arena.move array * Arena.game_state array
-
-(** Get moves and resulting game states, like {!Move.gen_models}, but for
- all rules the players can apply in the given game state. Returns
- the player together with a move. *)
-val list_moves : Arena.game -> Arena.game_state ->
- (int * Arena.move * Arena.game_state) array
Deleted: trunk/Toss/Play/MoveTest.ml
===================================================================
--- trunk/Toss/Play/MoveTest.ml 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Play/MoveTest.ml 2012-03-09 18:42:39 UTC (rev 1687)
@@ -1,18 +0,0 @@
-open OUnit
-
-let tests = "Move" >::: [
- "move to string" >::
- (fun () ->
- let mv = {
- Arena.mv_time = 0.;
- parameters = [];
- rule = "rule";
- next_loc = 1;
- matching = [("x", 1)];
- } in
- let s = Structure.empty_structure () in
- assert_equal ~printer:(fun x -> x) (Move.move_str_short s mv)
- "rule{x:1}"
- );
-]
-
Modified: trunk/Toss/Play/Play.ml
===================================================================
--- trunk/Toss/Play/Play.ml 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Play/Play.ml 2012-03-09 18:42:39 UTC (rev 1687)
@@ -50,7 +50,7 @@
try
let u = unfold_maximax ~ab:ab game heur t in
if (AuxIO.debug_level_for "Play" > 0) then AuxIO.printf "%d,%!" (size u);
- LOG 2 "(%s)," (let move_s (m, n) = Move.move_gs_str_short n m in
+ LOG 2 "(%s)," (let move_s (m, n) = Arena.game_move_gs_str n m in
String.concat ", " (List.map move_s (List.hd mvs)));
unfold_maximax_upto ~ab:ab (count-1) game heur (u, mvs)
with
Modified: trunk/Toss/Play/PlayTest.ml
===================================================================
--- trunk/Toss/Play/PlayTest.ml 2012-03-09 12:05:53 UTC (rev 1686)
+++ trunk/Toss/Play/PlayTest.ml 2012-03-09 18:42:39 UTC (rev 1687)
@@ -29,7 +29,7 @@
let res_mvs = Play.maximax_unfold_choose iters g s h in
if res_mvs <> [] then
List.iter (fun (m, ns) ->
- let move_str = Move.move_gs_str_short s m in
+ let move_str = Arena.game_move_gs_str s m in
assert_bool
(Printf.sprintf "%s: Failed move: %s." msg move_str) (cond move_str)
) res_mvs
@@ -90,8 +90,8 @@
. P .
...
[truncated message content] |