/// <summary> /// private constructor, for deep copy purposes, only! /// </summary> /// <param name="gameToCopy"></param> private PD_Game( PD_Game gameToCopy ) { unique_id = gameToCopy.unique_id; start_time = gameToCopy.start_time; end_time = gameToCopy.end_time; game_settings = gameToCopy.game_settings.GetCustomDeepCopy(); game_FSM = gameToCopy.game_FSM.GetCustomDeepCopy(); game_state_counter = gameToCopy.game_state_counter.GetCustomDeepCopy(); players = gameToCopy.players.CustomDeepCopy(); map = gameToCopy.map.GetCustomDeepCopy(); map_elements = gameToCopy.map_elements.GetCustomDeepCopy(); cards = gameToCopy.cards.GetCustomDeepCopy(); role__per__player = gameToCopy.role__per__player.CustomDeepCopy(); PlayerActionsHistory = gameToCopy.PlayerActionsHistory.CustomDeepCopy(); InfectionReports = gameToCopy.InfectionReports.CustomDeepCopy(); CurrentAvailablePlayerActions = gameToCopy.CurrentAvailablePlayerActions.CustomDeepCopy(); CurrentAvailableMacros = gameToCopy.CurrentAvailableMacros.CustomDeepCopy(); }
public PD_Game( long unique_id, DateTime start_time, DateTime end_time, PD_GameSettings game_settings, PD_GameFSM game_FSM, PD_GameStateCounter game_state_counter, List <int> players, PD_Map map, PD_MapElements map_elements, PD_GameCards cards, Dictionary <int, int> role__per__player, List <PD_Action> playerActionsHistory, List <PD_InfectionReport> infectionReports, List <PD_Action> currentAvailablePlayerActions, List <PD_MacroAction> currentAvailableMacros ) { this.unique_id = unique_id; this.start_time = start_time; this.end_time = end_time; this.game_settings = game_settings.GetCustomDeepCopy(); this.game_FSM = game_FSM.GetCustomDeepCopy(); this.game_state_counter = game_state_counter.GetCustomDeepCopy(); this.players = players.CustomDeepCopy(); this.map = map.GetCustomDeepCopy(); this.map_elements = map_elements.GetCustomDeepCopy(); this.cards = cards.GetCustomDeepCopy(); this.role__per__player = role__per__player.CustomDeepCopy(); this.PlayerActionsHistory = playerActionsHistory.CustomDeepCopy(); this.InfectionReports = infectionReports.CustomDeepCopy(); this.CurrentAvailablePlayerActions = currentAvailablePlayerActions.CustomDeepCopy(); this.CurrentAvailableMacros = currentAvailableMacros.CustomDeepCopy(); }
/// <summary> /// Shortest paths are computed at the beginning of the game, /// as well as when a new research station is added. /// </summary> private void ComputeShortestPaths(PD_Map map) { shortest_path__per__destination__per__origin = new Dictionary <int, Dictionary <int, List <int> > >(); foreach (int root in map.cities) { shortest_path__per__destination__per__origin .Add(root, new Dictionary <int, List <int> >()); foreach (var destination in map.cities) { var path = ComputeShortestPath( root, destination, map ); shortest_path__per__destination__per__origin[root].Add( destination, path ); } } }
/// <summary> /// Computes the shortest path between two cities of a given map, on demand. /// </summary> /// <param name="root"></param> /// <param name="destination"></param> /// <returns></returns> private List <int> ComputeShortestPath( int root, int destination, PD_Map map ) { if (root == destination) { return(new List <int>() { root }); } Dictionary <int, int> predecessors = new Dictionary <int, int>(); int dummyCity = -1; foreach (int city in map.cities) { predecessors.Add(city, dummyCity); } List <int> visitedCities = new List <int>(); Queue <int> searchQueue = new Queue <int>(); searchQueue.Enqueue(root); visitedCities.Add(root); bool foundDestination = false; while (searchQueue.Count > 0 && foundDestination == false) { var current = searchQueue.Dequeue(); var neighbors = map.neighbors__per__city[current]; var unvisitedNeighbors = neighbors.FindAll( x => visitedCities.Contains(x) == false ); foreach (var neighbor in unvisitedNeighbors) { predecessors[neighbor] = current; searchQueue.Enqueue(neighbor); visitedCities.Add(neighbor); if (neighbor == destination) { foundDestination = true; break; } } } List <int> shortestPath = new List <int>(); bool pathFinished = false; var currentPathPosition = destination; shortestPath.Add(currentPathPosition); while (pathFinished == false) { var predecessor = predecessors[currentPathPosition]; if (predecessor != dummyCity) { shortestPath.Add(predecessor); currentPathPosition = predecessor; } else { pathFinished = true; } } shortestPath.Reverse(); return(shortestPath); }
// normal constructor private PD_Game( Random randomness_provider, int number_of_players, int level_of_difficulty, List <int> assigned__players, Dictionary <int, int> assigned__role__per__player, // map - related List <int> cities, Dictionary <int, int> infection_type__per__city, Dictionary <int, List <int> > neighbors_per_city, List <int> initial_container__city_cards, List <int> initial_container__infection_cards, List <int> initial_container__epidemic_cards ) { if (assigned__players.Count != number_of_players) { throw new Exception("number of players is wrong"); } else if (assigned__role__per__player.Keys.Count != number_of_players) { throw new Exception("number of roles not correct"); } this.players = assigned__players.CustomDeepCopy(); this.role__per__player = assigned__role__per__player.CustomDeepCopy(); // initialize parts... this.start_time = DateTime.UtcNow; this.unique_id = DateTime.UtcNow.Ticks; this.unique_id = this.start_time.Ticks; CurrentAvailablePlayerActions = new List <PD_Action>(); CurrentAvailableMacros = new List <PD_MacroAction>(); PlayerActionsHistory = new List <PD_Action>(); InfectionReports = new List <PD_InfectionReport>(); this.game_settings = new PD_GameSettings(level_of_difficulty); this.game_state_counter = new PD_GameStateCounter(number_of_players); this.game_FSM = new PD_GameFSM(this); this.map = new PD_Map( cities.Count, cities, infection_type__per__city, neighbors_per_city); this.map_elements = new PD_MapElements(this.players, cities); this.cards = new PD_GameCards(this.players); ////////////////////////////////////////////////////////////////////// /// PERFORM THE GAME SETUP, HERE! ////////////////////////////////////////////////////////////////////// // 1. Set out board and pieces // 1.1. put research stations in research stations container map_elements.available_research_stations = 6; // 1.2. separate the infection cubes by color (type) in their containers for (int i = 0; i < 4; i++) { map_elements.available_infection_cubes__per__type[i] = 24; } // 1.3. place research station on atlanta int atlanta = 0; PD_Game_Operators.GO_Place_ResearchStation_OnCity( this, atlanta); // 2. Place outbreaks and cure markers // put outbreaks counter to position zero game_state_counter.ResetOutbreaksCounter(); // place cure markers vial side up game_state_counter.InitializeCureMarkerStates(); // 3. place infection marker and infect 9 cities // 3.1. place the infection marker (epidemics counter) on the lowest position game_state_counter.ResetEpidemicsCounter(); // 3.2. Infect the first cities - process // 3.2.1. put all infection cards in the divided deck of infection cards... cards.divided_deck_of_infection_cards.Add(initial_container__infection_cards.DrawAll()); // 3.2.2 shuffle the infection cards deck... cards.divided_deck_of_infection_cards.ShuffleAllSubListsElements(randomness_provider); // 3.2.3 actually infect the cities.. var firstPlayer = assigned__players[0]; for (int num_InfectionCubes_ToPlace = 3; num_InfectionCubes_ToPlace > 0; num_InfectionCubes_ToPlace--) { for (int city_Counter = 0; city_Counter < 3; city_Counter++) { var infectionCard = cards.divided_deck_of_infection_cards.DrawLastElementOfLastSubList(); int city = infectionCard; int city_type = map.infection_type__per__city[city]; PD_InfectionReport report = new PD_InfectionReport( true, firstPlayer, city, city_type, num_InfectionCubes_ToPlace ); PD_InfectionReport finalReport = PD_Game_Operators.GO_InfectCity( this, city, num_InfectionCubes_ToPlace, report, true ); InfectionReports.Add(finalReport); cards.deck_of_discarded_infection_cards.Add(infectionCard); } } // 4. Give each player cards and a pawn // 4.1. Assign roles (and pawns) // -> already done ^^ // 4.2. Deal cards to players: initial hands cards.divided_deck_of_player_cards.Add(initial_container__city_cards.DrawAll()); cards.divided_deck_of_player_cards.ShuffleAllSubListsElements(randomness_provider); int numPlayers = assigned__players.Count; int numCardsToDealPerPlayer = game_settings.GetNumberOfInitialCardsToDealPlayers(numPlayers); foreach (var player in assigned__players) { for (int i = 0; i < numCardsToDealPerPlayer; i++) { cards.player_hand__per__player[player].Add(cards.divided_deck_of_player_cards.DrawLastElementOfLastSubList()); } } // 5. Prepare the player deck // 5.1. get the necessary number of epidemic cards int numEpidemicCards = game_settings.GetNumberOfEpidemicCardsToUseInGame(); // divide the player cards deck in as many sub decks as necessary var allPlayerCardsList = cards.divided_deck_of_player_cards.DrawAllElementsOfAllSubListsAsOneList(); //int numberOfPlayerCardsPerSubDeck = allPlayerCardsList.Count / numEpidemicCards; int numCards = allPlayerCardsList.Count; int numSubDecks = numEpidemicCards; int numCardsPerSubDeck = numCards / numSubDecks; int remainingCardsNumber = numCards % numSubDecks; // create the sub decks List <List <int> > temporaryDividedList = new List <List <int> >(); for (int i = 0; i < numEpidemicCards; i++) { var subDeck = new List <int>(); for (int j = 0; j < numCardsPerSubDeck; j++) { subDeck.Add(allPlayerCardsList.DrawOneRandom(randomness_provider)); } temporaryDividedList.Add(subDeck); } // add the remaining cards for (int i = 0; i < remainingCardsNumber; i++) { int deckIndex = (temporaryDividedList.Count - 1) - i; temporaryDividedList[deckIndex].Add(allPlayerCardsList.DrawOneRandom(randomness_provider)); } // insert the epidemic cards foreach (List <int> subList in temporaryDividedList) { int epidemic_card = initial_container__epidemic_cards.DrawFirst(); subList.Add(epidemic_card); } // shuffle all the sublists! temporaryDividedList.ShuffleAllSubListsElements(randomness_provider); // set the player cards deck as necessary cards.divided_deck_of_player_cards.Clear(); foreach (var sublist in temporaryDividedList) { cards.divided_deck_of_player_cards.Add(sublist); } //// place all pawns on atlanta PD_Game_Operators.GO_PlaceAllPawnsOnAtlanta(this); UpdateAvailablePlayerActions(); }
public static PD_Game Convert_To_Game( this PD_MiniGame mini_game ) { // game settings... int game_difficulty_level = mini_game.settings___game_difficulty; PD_GameSettings GAME_SETTINGS = new PD_GameSettings(game_difficulty_level); // game FSM PD_GameFSM GAME_FSM; switch (mini_game.state_counter___current_state) { case PD_MiniGame__GameState.MAIN_PLAYER_ACTIONS: GAME_FSM = new PD_GameFSM(new PD_GS_ApplyingMainPlayerActions()); break; case PD_MiniGame__GameState.DISCARDING_DURING_PLAY: GAME_FSM = new PD_GameFSM(new PD_GS_Discarding_DuringMainPlayerActions()); break; case PD_MiniGame__GameState.DRAWING_NEW_PLAYER_CARDS: GAME_FSM = new PD_GameFSM(new PD_GS_DrawingNewPlayerCards()); break; case PD_MiniGame__GameState.DISCARDING_AFTER_DRAWING: GAME_FSM = new PD_GameFSM(new PD_GS_Discarding_AfterDrawing()); break; case PD_MiniGame__GameState.APPLYING_EPIDEMIC_CARDS: GAME_FSM = new PD_GameFSM(new PD_GS_ApplyingEpidemicCard()); break; case PD_MiniGame__GameState.DRAWING_NEW_INFECTION_CARDS: GAME_FSM = new PD_GameFSM(new PD_GS_DrawingNewInfectionCards()); break; case PD_MiniGame__GameState.APPLYING_INFECTION_CARDS: GAME_FSM = new PD_GameFSM(new PD_GS_ApplyingInfectionCards()); break; case PD_MiniGame__GameState.GAME_LOST: GAME_FSM = new PD_GameFSM(new PD_GS_GameLost()); break; case PD_MiniGame__GameState.GAME_WON: GAME_FSM = new PD_GameFSM(new PD_GS_GameWon()); break; default: throw new System.Exception("incorrect state!"); } // game state counter... PD_GameStateCounter GAME_STATE_COUNTER = new PD_GameStateCounter( mini_game.settings___number_of_players, mini_game.state_counter___current_player_action_index, mini_game.state_counter___current_player, mini_game.state_counter___current_turn, mini_game.state_counter___disease_states.CustomDeepCopy(), mini_game.state_counter___number_of_outbreaks, mini_game.state_counter___number_of_epidemics, mini_game.flag___insufficient_disease_cubes_during_infection, mini_game.flag___insufficient_player_cards_to_draw, mini_game.flag___operations_expert_flight_used_this_turn ); //////////////////////////////////////////////////////////// /// players //////////////////////////////////////////////////////////// List <int> PLAYERS = mini_game.players.CustomDeepCopy(); //////////////////////////////////////////////////////////// /// map //////////////////////////////////////////////////////////// // map PD_Map MAP = new PD_Map( mini_game.map___number_of_cities, mini_game.map___cities, mini_game.map___infection_type__per__city, mini_game.map___neighbors__per__city ); //////////////////////////////////////////////////////////// /// game element references... //////////////////////////////////////////////////////////// // city cards List <int> city_cards = new List <int>(); foreach (int cc in mini_game.map___cities) { city_cards.Add(cc); } // infection cards List <int> infection_cards = new List <int>(); foreach (int ic in mini_game.map___cities) { infection_cards.Add(ic); } // epidemic cards List <int> epidemic_cards = new List <int>(); for (int ec = 0; ec < 6; ec++) { epidemic_cards.Add(128 + ec); } // role cards List <int> role_cards = new List <int>(); role_cards.Add(PD_Player_Roles.Operations_Expert); role_cards.Add(PD_Player_Roles.Researcher); role_cards.Add(PD_Player_Roles.Medic); role_cards.Add(PD_Player_Roles.Scientist); Dictionary <int, int> ROLE_CARDS__PER__PLAYER_ID = new Dictionary <int, int>(); foreach (int p in mini_game.players) { int mini_player_role = mini_game.role__per__player[p]; int player_role = PlayerRole__From__MiniGamePlayerRole(mini_player_role); ROLE_CARDS__PER__PLAYER_ID.Add(p, player_role); } //////////////////////////////////////////////////////////// /// map elements //////////////////////////////////////////////////////////// /// // location per player Dictionary <int, int> location__per__player = new Dictionary <int, int>(); foreach (int p in mini_game.players) { int location = mini_game.map_elements___location__per__player[p]; location__per__player.Add(p, location); } // inactive_infection_cubes_per_type Dictionary <int, int> inactive_infection_cubes_per_type = mini_game.map_elements___available_infection_cubes__per__type.CustomDeepCopy(); // infection_cubes_per_city_id Dictionary <int, Dictionary <int, int> > infections__per__type__per__city = mini_game.map_elements___infection_cubes__per__type__per__city.CustomDeepCopy(); // inactive_research_stations int inactive_research_stations = mini_game.map_elements___available_research_stations; // research_stations_per_city Dictionary <int, bool> research_stations_per_city = mini_game.map_elements___research_station__per__city.CustomDeepCopy(); // map elements... PD_MapElements MAP_ELEMENTS = new PD_MapElements( location__per__player, inactive_infection_cubes_per_type, infections__per__type__per__city, inactive_research_stations, research_stations_per_city ); //////////////////////////////////////////////////////////// /// CARDS //////////////////////////////////////////////////////////// // divided_deck_of_infection_cards List <List <int> > divided_deck_of_infection_cards = new List <List <int> >(); foreach (List <int> mini_cards_group in mini_game.cards___divided_deck_of_infection_cards) { List <int> cards_group = new List <int>(); foreach (int mini_infection_card in mini_cards_group) { cards_group.Add(mini_infection_card); } divided_deck_of_infection_cards.Add(cards_group); } // active_infection_cards List <int> active_infection_cards = new List <int>(); foreach (int mini_card in mini_game.cards___active_infection_cards) { active_infection_cards.Add(mini_card); } // deck_of_discarded_infection_cards List <int> deck_of_discarded_infection_cards = new List <int>(); foreach (int mini_card in mini_game.cards___deck_of_discarded_infection_cards) { deck_of_discarded_infection_cards.Add(mini_card); } // divided_deck_of_player_cards List <List <int> > divided_deck_of_player_cards = mini_game.cards___divided_deck_of_player_cards.CustomDeepCopy(); // deck_of_dicarded_player_cards List <int> deck_of_dicarded_player_cards = mini_game.cards___deck_of_discarded_player_cards.CustomDeepCopy(); // player_cards_per_player Dictionary <int, List <int> > player_cards_per_player = mini_game.cards___player_cards__per__player.CustomDeepCopy(); List <int> all_role_cards = new List <int>() { PD_Player_Roles.Operations_Expert, PD_Player_Roles.Researcher, PD_Player_Roles.Medic, PD_Player_Roles.Scientist }; List <int> inactive_role_cards = all_role_cards.CustomDeepCopy(); foreach (int player in mini_game.players) { int mini_role = mini_game.role__per__player[player]; int game_role = PlayerRole__From__MiniGamePlayerRole(mini_role); inactive_role_cards.Remove(game_role); } PD_GameCards CARDS = new PD_GameCards( divided_deck_of_infection_cards, active_infection_cards, deck_of_discarded_infection_cards, divided_deck_of_player_cards, deck_of_dicarded_player_cards, player_cards_per_player ); PD_Game game = new PD_Game( mini_game.unique_id, // unique id DateTime.UtcNow, // start time DateTime.UtcNow, // end time GAME_SETTINGS, // game settings GAME_FSM, // game fsm GAME_STATE_COUNTER, // game state counter PLAYERS, // players MAP, // map MAP_ELEMENTS, // map elements CARDS, // cards ROLE_CARDS__PER__PLAYER_ID, // role cards per player id new List <PD_Action>(), // player actions history new List <PD_InfectionReport>(), // infection reports new List <PD_Action>(), // current aavailable player actions new List <PD_MacroAction>() // current available player actions ); game.UpdateAvailablePlayerActions(); return(game); }