Commits

Anonymous committed a41ded9

Parsing initial network messages.

Comments (0)

Files changed (3)

 .PHONY: all clean
 EXEC=starml.exe
 OBJ=types.cmo main.cmo
-OCAMLFLAGS=-warn-error A -g
+OCAMLFLAGS=-w A -warn-error A -g
 
 all: $(EXEC)
 
 $(EXEC): $(OBJ)
-	ocamlc $(OCAMLFLAGS) -o $@ unix.cma $+
+	ocamlc $(OCAMLFLAGS) -o $@ str.cma unix.cma $+
 	
 %.cmo: %.ml
 	ocamlc $(OCAMLFLAGS) -c $<
+
+open Types
 
 module Bufreader : sig
     type t
             Buffer.add_char b !c
         done;
         Buffer.contents b
+end
 
-end
+let send_string fd s =
+    ignore (Unix.send fd s 0 (String.length s) [])
+
+type options =
+    { user_control         : bool
+    ; complete_information : bool
+    }
+
+let options =
+    { user_control         = true
+    ; complete_information = false
+    }
+
+let option_string o =
+    let opt x = if x then "1" else "0" in
+     (opt o.user_control)
+    ^(opt o.complete_information)
+
+type player =
+    { player_id : int
+    ; player_race : race
+    }
+
+let split_re re =
+    Str.split (Str.regexp re)
+
+let split_colon =
+    split_re ":"
+
+let split_semicolon =
+    split_re ";"
+
+let parse_int = int_of_string
+
+let parse_bool s =
+    match parse_int s with
+    | 0 -> false
+    | 1 -> true
+    | _ -> invalid_arg "read_bool"
+
+let build_parser parse_fun s =
+    let elts = split_colon s in
+    List.map (fun s ->
+        let a = Array.of_list (split_semicolon s) in
+        parse_fun a
+    ) (List.tl elts)
+
+let parse_player str =
+    match split_colon str with
+        | _::a::b::c::d::_ ->
+                (           (int_of_string a)
+                , read_race (int_of_string b)
+                ,           (int_of_string c)
+                , read_race (int_of_string d)
+                )
+        | _ -> invalid_arg "parse_player"
+
+let parse_location =
+    build_parser (fun attr ->
+        (int_of_string attr.(0)
+        ,int_of_string attr.(1)
+        )
+    )
+
+type unit_type =
+    { unit_id               : int    ; unit_race             : race
+    ; unit_name             : string ; unit_min_cost         : int
+    ; unit_gas_cost         : int    ; unit_max_hp           : int
+    ; unit_max_shld         : int    ; unit_energy           : int
+    ; unit_build_time       : int    ; unit_can_attack       : bool
+	; unit_can_move         : bool   ; unit_tile_width       : int
+	; unit_tile_height      : int    ; unit_supply_req       : int
+	; unit_supply_prov      : int    ; unit_sight            : int
+	; unit_ground_max_range : int    ; unit_ground_min_range : int
+	; unit_ground_damage    : int    ; unit_air_range        : int
+	; unit_air_damage       : int    ; unit_is_building      : bool
+	; unit_is_flyer         : bool   ; unit_is_spell_caster  : bool
+	; unit_is_worker        : bool   ; unit_builder          : int
+    }
+
+let parse_units =
+    build_parser (fun attr ->
+        { unit_id               = int_of_string attr.(0)
+        ; unit_race             = read_race (int_of_string attr.(1))
+        ; unit_name             = attr.(2)
+        ; unit_min_cost         = parse_int  attr.(3)
+        ; unit_gas_cost         = parse_int  attr.(4)
+        ; unit_max_hp           = parse_int  attr.(5)
+        ; unit_max_shld         = parse_int  attr.(6)
+        ; unit_energy           = parse_int  attr.(7)
+        ; unit_build_time       = parse_int  attr.(8)
+        ; unit_can_attack       = parse_bool attr.(9)
+        ; unit_can_move         = parse_bool attr.(10)
+        ; unit_tile_width       = parse_int  attr.(11)
+        ; unit_tile_height      = parse_int  attr.(12)
+        ; unit_supply_req       = parse_int  attr.(13)
+        ; unit_supply_prov      = parse_int  attr.(14)
+        ; unit_sight            = parse_int  attr.(15)
+        ; unit_ground_max_range = parse_int  attr.(16)
+        ; unit_ground_min_range = parse_int  attr.(17)
+        ; unit_ground_damage    = parse_int  attr.(18)
+        ; unit_air_range        = parse_int  attr.(19)
+        ; unit_air_damage       = parse_int  attr.(20)
+        ; unit_is_building      = parse_bool attr.(21)
+        ; unit_is_flyer         = parse_bool attr.(22)
+        ; unit_is_spell_caster  = parse_bool attr.(23)
+        ; unit_is_worker        = parse_bool attr.(24)
+        ; unit_builder          = parse_int  attr.(25)
+        }
+    )
+
+type tech = 
+    { tech_id       : int
+    ; tech_name     : string
+    ; tech_research : int
+    ; tech_min_cost : int
+    ; tech_gas_cost : int
+    }
+
+let parse_techs =
+    build_parser (fun attr ->
+        { tech_id       = int_of_string attr.(0)
+        ; tech_name     = attr.(1)
+        ; tech_research = int_of_string attr.(2)
+        ; tech_min_cost = int_of_string attr.(3)
+        ; tech_gas_cost = int_of_string attr.(4)
+        }
+    )
+
+type upgrade =
+    { upgr_id         : int
+    ; upgr_name       : string
+    ; upgr_research   : int
+    ; upgr_repeats    : int
+    ; upgr_min_base   : int
+    ; upgr_min_factor : int
+    ; upgr_gas_base   : int
+    ; upgr_gas_factor : int
+    }
+
+let parse_upgrades =
+    build_parser (fun attr ->
+        { upgr_id         = int_of_string attr.(0)
+        ; upgr_name       = attr.(1)
+        ; upgr_research   = int_of_string attr.(2)
+        ; upgr_repeats    = int_of_string attr.(3)
+        ; upgr_min_base   = int_of_string attr.(4)
+        ; upgr_min_factor = int_of_string attr.(5)
+        ; upgr_gas_base   = int_of_string attr.(6)
+        ; upgr_gas_factor = int_of_string attr.(7)
+        }
+    )
+
+type map_attr =
+    { mattr_height    : int
+    ; mattr_buildable : bool
+    ; mattr_walkable  : bool
+    }
+
+type map =
+    { map_name  : string
+    ; map_w     : int
+    ; map_h     : int
+    ; map_attrs : map_attr array array
+    }
+
+let parse_map s =
+    let map = Array.of_list (split_colon s) in
+    let split_tokens s =
+        List.map (fun x -> match x with
+        | Str.Delim s -> s
+        | Str.Text  _ -> invalid_arg "split_tokens"
+        ) (Str.full_split (Str.regexp "...") s)
+    in
+    let attr_l = List.map (fun s ->
+        { mattr_height    = int_of_char s.[0]
+        ; mattr_buildable = (s.[1] = '1')
+        ; mattr_walkable  = (s.[2] = '1')
+        }
+    ) (split_tokens map.(3))
+    in
+    let mw = int_of_string map.(1) in
+    let mh = int_of_string map.(2) in
+    let i = ref 0 in
+    let attr = Array.make_matrix mh mw
+        { mattr_height    = 0
+        ; mattr_buildable = false
+        ; mattr_walkable  = false 
+        }
+    in
+    List.iter (fun a ->
+        let w = !i mod mw in
+        let h = !i / mw in
+        attr.(h).(w) <- a;
+        incr i
+    ) attr_l;
+    { map_name  = map.(0)
+    ; map_w     = mw
+    ; map_h     = mh
+    ; map_attrs = attr
+    }
 
 let main _ =
     print_endline "Sup dawg, I heard you like starcraft";
     let (fd, _) = Unix.accept sock in
     print_endline "Got it !";
     let reader = Bufreader.new_from fd in
-    while true do
-        let line = Bufreader.read_line reader in
-        Printf.printf "Recv <%s>\n" line;
-        flush stdout;
-        begin
-            ignore (Unix.send fd "00" 0 2 []);
-        end
-    done
+    let player_data = Bufreader.read_line reader in
+    flush stdout;
+    send_string fd (option_string options);
+    let unit_type_data    = Bufreader.read_line reader in
+    let location_data     = Bufreader.read_line reader in
+    let map_data          = Bufreader.read_line reader in
+    let tech_type_data    = Bufreader.read_line reader in
+    let upgrade_type_data = Bufreader.read_line reader in
+
+    let (p_id, p_race, e_id, e_race) = parse_player player_data in
+    let units = parse_units    unit_type_data    in
+    let locs  = parse_location location_data     in
+    let map   = parse_map      map_data          in
+    let techs = parse_techs    tech_type_data    in
+    let upgr  = parse_upgrades upgrade_type_data in
+    ()
 
 let _ = main ()
     | Random | Other  | No_race
     | Unknown_race
 
-let race_write = function
+let write_race = function
     | Zerg         -> 0 | Terran       -> 1
     | Protoss      -> 2 | Random       -> 3
     | Other        -> 4 | No_race      -> 5
     | Unknown_race -> 6
 	
-let race_read = function
+let read_race = function
     | 0 -> Zerg          | 1 -> Terran        
     | 2 -> Protoss       | 3 -> Random        
     | 4 -> Other         | 5 -> No_race