Beispiel #1
0
        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);
        }
Beispiel #2
0
        /// <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()
                );
        }