public override void Execute( Random randomness_provider, PD_Game game ) { #if DEBUG if (Player != game.GQ_CurrentPlayer()) { throw new System.Exception("wrong player!"); } else if ((game.game_FSM.CurrentState is PD_GS_ApplyingInfectionCards) == false) { throw new System.Exception("wrong state!"); } #endif int infectionType = game.GQ_City_InfectionType(InfectionCardToApply); bool diseaseEradicated = game.GQ_Is_Disease_Eradicated(infectionType); if (diseaseEradicated == false) { PD_InfectionReport initialReport = new PD_InfectionReport( false, // not game setup Player, InfectionCardToApply, infectionType, 1 ); PD_InfectionReport finalReport = PD_Game_Operators.GO_InfectCity( game, InfectionCardToApply, 1, initialReport, false ); game.InfectionReports.Add(finalReport); if (finalReport.FailureReason == InfectionFailureReasons.notEnoughDiseaseCubes) { game.game_state_counter.insufficient_disease_cubes_for_infection = true; } } // remove the infection card from the active infection cards pile game.cards.active_infection_cards.Remove(InfectionCardToApply); game.cards.deck_of_discarded_infection_cards.Add(InfectionCardToApply); }
/// <summary> /// The process of infecting a city /// </summary> /// <param name="game"></param> /// <param name="target_city"></param> /// <param name="infection_size"></param> /// <param name="existingReport"></param> /// <param name="infectionDuringGameSetup"></param> /// <returns></returns> public static PD_InfectionReport GO_InfectCity( this PD_Game game, int target_city, int infection_size, PD_InfectionReport existingReport, bool infectionDuringGameSetup ) { int infection_type = existingReport.InfectionType; if (infectionDuringGameSetup == false) { int medic_location = game.GQ_Medic_Location(); bool currentDiseaseIsCured = game.GQ_Is_DiseaseCured_OR_Eradicated(infection_type); bool medicIsAtInfectionLocation = medic_location == target_city; if ( currentDiseaseIsCured && medicIsAtInfectionLocation ) { existingReport.AddInfectionPreventedByMedic(target_city); return(existingReport); } } existingReport.AddInfectedCity(target_city); int occupied_infection_positions_on_city = game.GQ_Num_InfectionCubes_OfType_OnCity(target_city, infection_type); int remaining_infection_positions_on_city = 3 - occupied_infection_positions_on_city; int available_infection_cubes_this_type = game.GQ_Num_AvailableInfectionCubes_OfType(infection_type); bool enough_available_infection_cubes = available_infection_cubes_this_type >= infection_size; bool city_causes_outbreak = remaining_infection_positions_on_city < infection_size; // CASE 1: CITY DOES NOT CAUSE AN OUTBREAK if (city_causes_outbreak == false) { // NOT ENOUGH CUBES FOR THIS INFECTION... GAME LOST if (enough_available_infection_cubes == false) { // place the remaining inactive cubes, either way... for (int i = 0; i < available_infection_cubes_this_type; i++) { GO_Place_InfectionCube_OnCity(game, target_city, infection_type); } // game lost... existingReport.SetFailureReason(InfectionFailureReasons.notEnoughDiseaseCubes); return(existingReport); } // ENOUGH CUBES TO COMPLETE THIS INFECTION, JUST PROCEED! for (int i = 0; i < infection_size; i++) { GO_Place_InfectionCube_OnCity(game, target_city, infection_type); } existingReport.AddUsedCubes(infection_size); return(existingReport); } // CASE 2: CITY DOES CAUSE AN OUTBREAK!!! bool enoughCubesToFillUpCity = available_infection_cubes_this_type >= remaining_infection_positions_on_city; existingReport.AddCityThatCausedOutbreak(target_city); if (enoughCubesToFillUpCity == false) { // place the remaining inactive cubes, either way... for (int i = 0; i < available_infection_cubes_this_type; i++) { GO_Place_InfectionCube_OnCity(game, target_city, infection_type); } // game lost existingReport.SetFailureReason(InfectionFailureReasons.notEnoughDiseaseCubes); return(existingReport); } // fill up this city for (int i = 0; i < remaining_infection_positions_on_city; i++) { GO_Place_InfectionCube_OnCity( game, target_city, existingReport.InfectionType ); } existingReport.AddUsedCubes(remaining_infection_positions_on_city); game.game_state_counter.IncreaseOutbreaksCounter(); if (game.GQ_SS_DeadlyOutbreaks() == true) { existingReport.SetFailureReason(InfectionFailureReasons.maximumOutbreaksSurpassed); return(existingReport); } var neighbors = game.map.neighbors__per__city[target_city]; // cityToInfect.AdjacentCities; var neighborsThatHaveNotCausedAnOutbreak = neighbors.FindAll( x => existingReport.CitiesThatHaveCausedOutbreaks.Any(xx => xx == x) == false ); foreach (var neighbor in neighborsThatHaveNotCausedAnOutbreak) { existingReport = GO_InfectCity( game, neighbor, 1, existingReport, infectionDuringGameSetup ); if (existingReport.FailureReason != InfectionFailureReasons.none) { return(existingReport); } } return(existingReport); }
// 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 override void Execute( Random randomness_provider, PD_Game game ) { #if DEBUG if (Player != game.GQ_CurrentPlayer()) { throw new System.Exception("wrong player!"); } else if ((game.game_FSM.CurrentState is PD_GS_ApplyingEpidemicCard) == false) { throw new System.Exception("wrong state!"); } #endif // 0. discard the epidemic card... var allCards_InPlayerHand = game.cards.player_hand__per__player[Player]; var epidemicCard = allCards_InPlayerHand.Find( x => x >= 128 ); game.cards.player_hand__per__player[Player].Remove(epidemicCard); game.cards.deck_of_discarded_player_cards.Add(epidemicCard); // 1. move the infection rate marker by one position game.game_state_counter.IncreaseEpidemicsCounter(); // 2. Infect: Draw the bottom card from the Infection Deck. // Unless its disease color has been eradicated, put 3 disease cubes of that color on the named city. // If the city already has cubes of this color, do not add 3 cubes to it. // Instead, add just enough cubes so that it has 3 cubes of this color and then an outbreak of this disease occurs in the city(see Outbreaks below). // Discard this card to the Infection Discard Pile. var cardFromBottom = game.cards.divided_deck_of_infection_cards.DrawFirstElementOfFirstSubList(); int epidemicInfectionType = game.GQ_City_InfectionType(cardFromBottom); bool diseaseTypeEradicated = game.GQ_Is_Disease_Eradicated(epidemicInfectionType); if (diseaseTypeEradicated == false) { // actually apply the epidemic infection here... PD_InfectionReport initialReport = new PD_InfectionReport( false, // not game setup... Player, cardFromBottom, epidemicInfectionType, 3 ); // apply infection of this city here PD_InfectionReport finalReport = PD_Game_Operators.GO_InfectCity( game, cardFromBottom, 3, initialReport, false ); game.InfectionReports.Add(finalReport); if (finalReport.FailureReason == InfectionFailureReasons.notEnoughDiseaseCubes) { game.game_state_counter.insufficient_disease_cubes_for_infection = true; } } // put card in discarded infection cards pile game.cards.deck_of_discarded_infection_cards.Add(cardFromBottom); // 3. intensify: Reshuffle just the cards in the Infection Discard Pile // and place them on top of the Infection Deck. game.cards.deck_of_discarded_infection_cards.Shuffle(randomness_provider); game.cards.divided_deck_of_infection_cards.Add( game.cards.deck_of_discarded_infection_cards.DrawAll() ); }