Printing functions, toplevel init
2 files changed, 80 insertions(+), 11 deletions(-)

M src/panacea_lib/gamestate.ml
M src/panacea_lib/panacea_lib.ml
M src/panacea_lib/gamestate.ml +78 -9
@@ 10,6 10,7 @@ type difficulty =
   | Heroic        (* 6 Epidemic cards *)
   [@@deriving show]
 
+
 type role = 
   (* - As an action, take any discarded Event card and store it on this card.
    * - When you play the stored Event card, remove it from the game.

          
@@ 77,6 78,7 @@ type player_card =
   | City of infection_city
   [@@deriving show]
 
+
 type player = {
   role : role;
   name : string;

          
@@ 84,6 86,7 @@ type player = {
   location : infection_city;
 } [@@deriving show]
 
+
 type board_city = {
   name : string;
   natural_color : infection_color;

          
@@ 107,13 110,27 @@ module CityCompare = struct
   include T
   include Comparable.Make(T)
 end
+
+
 type board =
   (infection_city, board_city, CityCompare.comparator_witness) Map.t
 
-let pp_board _ = "Board"
+
+let show_board board =
+  let board_city_to_string (_, {name; natural_color; num_red; num_blue; num_black; num_yellow; has_research_station; _}) = 
+    let research_str = if has_research_station then "(R) " else "" in
+    let header = Printf.sprintf "============ %s%s (%s)" research_str name (show_infection_color natural_color) in
+    let body = Printf.sprintf "| %d Red | %d Blue | %d Black | %d Yellow" num_red num_blue num_black num_yellow in
+    header ^ "\n" ^ body
+  in
+  Map.to_alist board
+  |> List.map ~f:board_city_to_string
+  |> String.concat ~sep:"\n"
+
 
 type infection_card = infection_city [@@deriving show]
 
+
 type gamestate = {
   players : player list;
   board : board;

          
@@ 135,7 152,20 @@ type gamestate = {
   is_yellow_cured : bool;
 }
 
-let pp_gamestate _ = "Gamestate"
+
+let show_gamestate gs = 
+  let player_string = List.map ~f:show_player gs.players |> String.concat ~sep:"\n" in
+  let board_string = show_board gs.board in
+  let turn_string = Printf.sprintf "Current Turn: %d. Number of outbreaks: %d. Actions remaining: %d. Research stations available: %d"
+    gs.curr_turn gs.num_outbreaks gs.actions_remaining gs.research_stations_remaining
+  in
+  let cube_string = Printf.sprintf "Red cubes: %d. Blue cubes: %d. Black cubes: %d. Yellow cubes: %d."
+    gs.available_red_cubes gs.available_blue_cubes gs.available_black_cubes gs.available_yellow_cubes
+  in
+  let cure_string = Printf.sprintf "CURES: Red %B. Blue %B. Black %B. Yellow %B."
+    gs.is_red_cured gs.is_blue_cured gs.is_black_cured gs.is_yellow_cured
+  in
+  String.concat ~sep:"\n" ["===== GAMESTATE ====="; player_string; board_string; turn_string; cube_string; cure_string]
 
 
 let empty_board = 

          
@@ 155,7 185,7 @@ let empty_board =
   let cities = [
     make_city_from(SanFrancisco, "San Francisco", Blue, [LosAngeles; Chicago; Tokyo; Manila]);
     make_city_from(Chicago, "Chicago", Blue, [SanFrancisco; LosAngeles; MexicoCity; Atlanta; Montreal]);
-    make_city_from(Atlanta, "Atlanta", Red, [Miami; Chicago; Washington]);
+    make_city_from(Atlanta, "Atlanta", Blue, [Miami; Chicago; Washington]);
     make_city_from(Montreal, "Montreal", Blue, [Chicago; Washington; NewYork]);
     make_city_from(Washington, "Washington", Blue, [Atlanta; Montreal; NewYork; Miami]);
     make_city_from(NewYork, "NewYork", Blue, [Montreal; Washington; London; Madrid]);

          
@@ 261,7 291,7 @@ let empty_gamestate =
 
 let rec shuffle = function
   | [] -> []
-  | [single] -> [single]
+  | [x] -> [x]
   | lst -> 
     let (before, after) = List.partition_tf ~f:(fun _elt -> Random.bool ()) lst in 
     List.rev_append (shuffle before) (shuffle after)

          
@@ 296,15 326,55 @@ let shuffle_player_deck gs =
 
 
 (** Gives each player _n_ cards from the Player deck, per the starting rules. *)
-let hand_out_cards gs = gs
+let hand_out_cards gs = 
+  let {players=players; player_deck=cards; _} = gs in
+  let num_per_player = 6 - List.length players in
+  let draw_for_player (player_accum, deck_accum) player =
+    let (drawn, remaining) = List.split_n deck_accum num_per_player in
+    let updated_player = {player with hand=drawn} in
+    (updated_player::player_accum, remaining)
+  in
+  let (updated_players, updated_player_deck) = List.fold_left players ~init:([], cards) ~f:draw_for_player in
+  {gs with players=(List.rev updated_players); player_deck=updated_player_deck}
 
 
 (** Infects 9 cities with varying severity, per the starting rules. *)
-let infect_cities gs = gs
+let infect_cities gs =
+  let {infection_deck; _} = gs in
+  let (cities, the_rest) = List.split_n infection_deck 9 in
+  let with_quantities = List.zip_exn cities [3;3;3;2;2;2;1;1;1] in
+  let infect_city this_gs (city_name, num_cubes) =
+    let {board; available_red_cubes; available_blue_cubes; available_black_cubes; available_yellow_cubes;_} = this_gs in
+    let b_city = Map.find_exn board city_name in
+    let {natural_color; num_red; num_blue; num_black; num_yellow;_} = b_city in
+    let new_board = match natural_color with 
+      | Red -> Map.set board ~key:city_name ~data:{b_city with num_red=num_red + num_cubes}
+      | Blue -> Map.set board ~key:city_name ~data:{b_city with num_blue=num_blue + num_cubes}
+      | Black -> Map.set board ~key:city_name ~data:{b_city with num_black=num_black + num_cubes}
+      | Yellow -> Map.set board ~key:city_name ~data:{b_city with num_yellow=num_yellow + num_cubes}
+    in
+    match natural_color with 
+      | Red -> {this_gs with available_red_cubes=available_red_cubes - num_cubes; board=new_board}
+      | Blue -> {this_gs with available_blue_cubes=available_blue_cubes - num_cubes; board=new_board}
+      | Black ->{this_gs with available_black_cubes=available_black_cubes - num_cubes; board=new_board}
+      | Yellow -> {this_gs with available_yellow_cubes=available_yellow_cubes - num_cubes; board=new_board}
+  in
+  let with_infected = List.fold_left with_quantities ~init:gs ~f:infect_city in
+  {with_infected with infection_deck=the_rest; infection_discard=(List.rev cities)}
 
 
 (** Places the outbreak cards in the remaining Player deck, per the difficulty level. *)
-let place_outbreaks _difficulty gs = gs
+let place_outbreaks difficulty gs =
+  let {player_deck;_} = gs in
+  let num_outbreaks = match difficulty with
+    | Introductory -> 4
+    | Standard -> 5
+    | Heroic -> 6
+  in
+  let to_split_size = (List.length player_deck) / num_outbreaks in
+  let chunked = List.chunks_of player_deck ~length:to_split_size in
+  let new_player_deck = List.concat_map chunked ~f:(fun sublist -> shuffle (Epidemic::sublist)) in
+  {gs with player_deck=new_player_deck}
 
 
 (** Places the first research center in Atlanta. *)

          
@@ 319,7 389,7 @@ let place_research_station place gs =
 
 
 (** Gives us a Gamestate that's ready to play! *)
-let starting_game player_names difficulty = 
+let starting_game ~player_names ~difficulty = 
   let transformations = 
     [
       draw_players player_names;

          
@@ 335,4 405,3 @@ let starting_game player_names difficult
     ~init:empty_gamestate
     ~f:(fun accum x -> x accum)
     transformations
-  

          
M src/panacea_lib/panacea_lib.ml +2 -2
@@ 1,6 1,6 @@ 
 open Core
 
 let execute () =
-  let inputs = "Hello World!" in
-  inputs
+  Gamestate.starting_game ~player_names:["Pablo"; "Karen"; "Sapo"] ~difficulty:Gamestate.Standard
+  |> Gamestate.show_gamestate
   |> print_endline