M src/panacea_lib/gameplay.ml +21 -1
@@ 12,6 12,11 @@ open Gamestate
* Visibility into the decks is disallowed.
*)
+
+(**
+ * Actions form the baselines of moves. I'm not sure yet if I'm including the
+ * use of Player Cards (usually totally free).
+ *)
type action =
| Drive of infection_city (* Move to a city connected to the one you are in. *)
| DirectFlight of infection_city (* Discard a city card to move to the city named on the card.*)
@@ 19,13 24,20 @@ type action =
| ShuttleFlight of infection_city (* Move from a city with a research station to another with a research station. *)
| BuildResearch of infection_city (* Discard card matching city you're in, build a research station. *)
| TreatDisease of infection_city * infection_color (* Remove cubes *)
- | ShareKnowledge of infection_city (* Give card to another player *)
+ | TakeShareKnowledge (* Take card from another player who has the city card you're in. *)
+ | GiveShareKnowledge of string (* Give city card you're in to specified player. *)
| DiscoverCure of infection_color * infection_card list
type move = (action * action * action * action)
+(*
+ * Note that we're not evaluating whether these moves are legal or not; we
+ * presume that they are. The actual "brains" of the bot will be responsible for
+ * only generating legal moves; this just advances the Gamestate according to
+ * them.
+ *)
let apply_action gs action =
let active_player = Gamestate.active_player gs in
match action with
@@ 51,6 63,14 @@ let apply_action gs action =
gs
|> Gamestate.place_research_station ~city:city
|> Gamestate.decrement_actions_remaining
+ | TreatDisease (city, color) ->
+ gs
+ |> Gamestate.decrement_disease_cube_at ~city:city ~color:color
+ |> Gamestate.decrement_actions_remaining
+ | TakeShareKnowledge ->
+ gs
+ |> Gamestate.take_current_city_card_from_another_player
+ |> Gamestate.decrement_actions_remaining
| _ -> gs
M src/panacea_lib/gamestate.ml +44 -10
@@ 35,7 35,7 @@ type role =
*)
| ContingencyPlanner
- (* - Move another player's paw as if it were yours.
+ (* - Move another player's pawn as if it were yours.
* - As an action, move any pawn to a city with another pawn.
*)
| Dispatcher
@@ 48,7 48,7 @@ type role =
(* - As an action, build a research center in the city you are in (no City card needed).
* - Once per turn as an action, move from a research station to any city by discarding
- * by discarding any City card.
+ * any City card.
*)
| OperationsExpert
@@ 58,7 58,7 @@ type role =
| QuarantineSpecialist
(* - As an action, you may give (or a player can take) any City card from your hand.
- * You must both be in the same city. The card dooes not have to match the city
+ * You must both be in the same city. The card does not have to match the city
* you are in.
*)
| Researcher
@@ 434,13 434,17 @@ let starting_game ~player_names ~difficu
let update_location city player = {player with location=city}
-let discard_card card player =
+let lose_card card player =
let new_hand = List.filter player.hand ~f:(fun x -> not (phys_equal x card)) in
{player with hand=new_hand}
-let discard_location_card player =
+
+let gain_card card player = {player with hand=(card::player.hand)}
+
+
+let lose_location_card player =
let location_card = City player.location in
- discard_card location_card player
+ lose_card location_card player
let update_player_named (name : string) (func : player -> player) : (player -> player) =
@@ 456,13 460,43 @@ let move_player_to ~player ~city gs =
let discard_player_card ~player ~card gs =
- let updated_players = List.map ~f:(update_player_named player (discard_card card)) gs.players in
- {gs with players=updated_players}
+ let updated_players = List.map ~f:(update_player_named player (lose_card card)) gs.players in
+ let augmented_discard = card::gs.player_discard in
+ {gs with players=updated_players; player_discard=augmented_discard}
let discard_player_card_at_location ~player gs =
- let updated_players = List.map ~f:(update_player_named player discard_location_card) gs.players in
- {gs with players=updated_players}
+ let player_struct = List.hd_exn @@ List.filter ~f:(fun p -> phys_equal p.name player) gs.players in
+ let updated_players = List.map ~f:(update_player_named player lose_location_card) gs.players in
+ let augmented_discard = (City player_struct.location)::gs.player_discard in
+ {gs with players=updated_players; player_discard=augmented_discard}
+
+
+let decrement_disease_cube_at ~city ~color gs =
+ let {board;_} = gs in
+ let b_city = Map.find_exn board city in
+ match color with
+ | Black ->
+ let updated_city = {b_city with num_black=b_city.num_black - 1} in
+ {gs with available_black_cubes=gs.available_black_cubes+1; board=(Map.set board ~key:city ~data:updated_city)}
+ | Blue ->
+ let updated_city = {b_city with num_blue=b_city.num_blue - 1} in
+ {gs with available_blue_cubes=gs.available_blue_cubes+1; board=(Map.set board ~key:city ~data:updated_city)}
+ | Red ->
+ let updated_city = {b_city with num_red=b_city.num_red - 1} in
+ {gs with available_red_cubes=gs.available_red_cubes+1; board=(Map.set board ~key:city ~data:updated_city)}
+ | Yellow ->
+ let updated_city = {b_city with num_yellow=b_city.num_yellow - 1} in
+ {gs with available_yellow_cubes=gs.available_yellow_cubes+1; board=(Map.set board ~key:city ~data:updated_city)}
+
+
+let take_current_city_card_from_another_player gs =
+ let my_turn = List.nth_exn gs.players gs.curr_turn in
+ let the_card = City my_turn.location in
+ let has_card = List.hd_exn @@ List.filter ~f:(fun p -> List.mem p.hand the_card ~equal:phys_equal) gs.players in
+ let updated_players = List.map ~f:(update_player_named my_turn.name (gain_card the_card)) gs.players in
+ let final_players = List.map ~f:(update_player_named has_card.name (lose_card the_card)) updated_players in
+ {gs with players=final_players}
M src/panacea_lib/gamestate.mli +6 -0
@@ 55,8 55,14 @@ val discard_player_card_at_location : pl
(** Use an action of this player's turn. *)
val decrement_actions_remaining : t -> t
+(** Removes a cube of a certain color at the chosen location. *)
+val decrement_disease_cube_at : city:infection_city -> color:infection_color -> t -> t
+
(** Place a Research Station at this city. *)
val place_research_station : city:infection_city -> t -> t
+(** Take a card for the current player's city from another player in that city who has it. *)
+val take_current_city_card_from_another_player : t -> t
+
(** Get the name of the player who's turn it is. *)
val active_player : t -> string