Exemple #1
0
        public List <City> GetShortestPath(IPandemicState state, City fromCity, City toCity)
        {
            var citiesWithResearchStations = state.Cities.Where(n => n.HasResearchStation).ToList();
            var cacheKey     = citiesWithResearchStations.Count < 2 ? $"Pandemic.ShortestPath.{fromCity}-{toCity}" :  $"Pandemic.{state.Id}.ShortestPath.{fromCity}-{toCity}";
            var cacheExpires = citiesWithResearchStations.Count < 2 ? TimeSpan.FromMinutes(30) : TimeSpan.FromMilliseconds(2000);

            List <City> cacheEntry;

            if (_memoryCache.TryGetValue(cacheKey, out cacheEntry))
            {
                return(cacheEntry);
            }

            var cityGraph = GetCityGraph(state);

            var route = cityGraph.Dijkstra((uint)fromCity + 1, (uint)toCity + 1);
            var path  = route.GetPath();

            var citiesTravelledTo = new List <City>();

            foreach (var node in path)
            {
                citiesTravelledTo.Add((City)(node - 1));
            }

            cacheEntry = citiesTravelledTo;
            var cacheEntryOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(cacheExpires);

            _memoryCache.Set(cacheKey, cacheEntry, cacheEntryOptions);

            return(citiesTravelledTo);
        }
        public bool ShouldBuildResearchStation(IPandemicState state, City currentLocation, PlayerRole playerRole, List <PandemicPlayerCard> playerHand)
        {
            if (!CouldBuildResearchStation(state, currentLocation, playerRole, playerHand))
            {
                return(false);
            }

            var nearestCityWithResearchStation = _routeHelper.GetNearestCitywithResearchStation(state, currentLocation);

            if (nearestCityWithResearchStation == null)
            {
                return(true);
            }

            var minimumDistanceBetweenResearchStations = 2; // could be dynamic

            var routeToNearestResearchStation = _routeHelper.GetShortestPath(state, currentLocation, nearestCityWithResearchStation.Value);

            if (routeToNearestResearchStation.Count > minimumDistanceBetweenResearchStations)
            {
                return(true);
            }

            return(false);
        }
        public bool CouldBuildResearchStation(IPandemicState state, City currentLocation, PlayerRole playerRole, List <PandemicPlayerCard> playerHand)
        {
            if (state.ResearchStationStock < 1)
            {
                return(false);
            }

            var atResearchStation = state.Cities.Single(c => c.City.Equals(currentLocation)).HasResearchStation;

            if (atResearchStation)
            {
                return(false);
            }

            if (playerRole == PlayerRole.OperationsExpert)
            {
                return(true);
            }

            if (playerHand.Any(c => c.PlayerCardType == PlayerCardType.City && (City)c.Value == currentLocation))
            {
                return(true);
            }

            return(false);
        }
        private void TreatDisease(IPandemicState state, City city, Disease disease)
        {
            _state = state;
            var diseaseState      = _state.DiscoveredCures[disease];
            var currentPlayerRole = _state.PlayerStates[_currentPlayerId].PlayerRole;

            var node = _state.Cities.Single(c => c.City == city);

            if (disease == 0)
            {
                return;
            }

            if (diseaseState == DiseaseState.Cured || currentPlayerRole == PlayerRole.Medic)
            {
                _state.DiseaseCubeReserve[disease] += node.DiseaseCubes[disease];
                node.DiseaseCubes[disease]          = 0;
            }
            else
            {
                node.DiseaseCubes[disease]--;
                _state.DiseaseCubeReserve[disease]++;
            }

            _stateDeltas.Add(new DiseaseChangedDelta()
            {
                City      = node.City,
                Disease   = disease,
                NewAmount = node.DiseaseCubes[disease]
            });
        }
Exemple #5
0
        private List <int> PlayersWeCouldKnowledgeShareWith(int currentPlayerId, IPandemicState state)
        {
            var currentPlayerState     = state.PlayerStates[currentPlayerId];
            var currentPlayerLocation  = currentPlayerState.Location;
            var currentPlayerRole      = currentPlayerState.PlayerRole;
            var currentPlayerCityCards = currentPlayerState.PlayerHand
                                         .Where(c => c.PlayerCardType == PlayerCardType.City).ToList();

            // If there are no other players in the same location as this player, then no knowledge sharing is possible
            var otherPlayersInSameCity = state.PlayerStates
                                         .Where(p => p.Key != currentPlayerId && p.Value.Location == currentPlayerLocation).ToList();

            if (!otherPlayersInSameCity.Any())
            {
                return(new List <int>());
            }

            var weCanShareWithPlayerIds = new List <int>();

            // If a researcher is in this city, and has at least one city card, then knowledge sharing is possible
            if ((currentPlayerRole == PlayerRole.Researcher && currentPlayerCityCards.Any()) ||
                (otherPlayersInSameCity.Any(p => p.Value.PlayerRole == PlayerRole.Researcher &&
                                            p.Value.PlayerHand.Any(c => c.PlayerCardType == PlayerCardType.City))))
            {
                weCanShareWithPlayerIds.AddRange(otherPlayersInSameCity.Select(p => p.Key).ToList());
            }

            // If another player in this city, has the city card of this city, then knowledge sharing is possible
            weCanShareWithPlayerIds.AddRange(otherPlayersInSameCity
                                             .Where(c => c.Value.PlayerHand.Any(ph => ph.PlayerCardType == PlayerCardType.City && (City)ph.Value == currentPlayerLocation))
                                             .Select(p => p.Key).ToList());

            return(weCanShareWithPlayerIds);
        }
        private void BuildResearchStation(IPandemicState state, City city, bool haveGrant = false)
        {
            _state = state;
            var playerState = _state.PlayerStates[_currentPlayerId];

            var node = _state.Cities.Single(c => c.City == city);

            node.HasResearchStation = true;
            _state.ResearchStationStock--;

            if (!haveGrant && playerState.PlayerRole != PlayerRole.OperationsExpert)
            {
                var cardToDiscard = playerState.PlayerHand.Single(c => c.PlayerCardType == PlayerCardType.City && (City)c.Value == city);
                playerState.PlayerHand.Remove(cardToDiscard);
                _state.PlayerDiscardPile.AddCard(cardToDiscard);
                _stateDeltas.Add(new CardIsDrawnOrDiscardedDelta {
                    PlayerId = _currentPlayerId, PandemicPlayerCard = cardToDiscard, DrawnOrDiscarded = DrawnOrDiscarded.Discarded
                });
            }

            _stateDeltas.Add(new ResearchStationDelta()
            {
                City = city
            });
        }
Exemple #7
0
        public City GetBestCityToTravelToWithoutDiscarding(IPandemicState state, City startingLocation)
        {
            var startingNode    = state.Cities.Single(n => n.City == startingLocation);
            var threeCubeCities = state.Cities.Where(c => c.DiseaseCubeCount >= 3).ToList();

            var bestCandidate =
                threeCubeCities.OrderBy(c => GetDistance(state, startingLocation, c.City)).FirstOrDefault();

            if (bestCandidate != null)
            {
                var connections = startingNode.ConnectedCities.ToList();
                if (startingNode.HasResearchStation)
                {
                    var researchStationNodes = state.Cities
                                               .Where(n => n.HasResearchStation && n.City != startingLocation)
                                               .Select(n => n.City);
                    connections.AddRange(researchStationNodes);
                }
                var bestDriveFerryOrShuttleFlightTo = connections.OrderBy(c => GetDistance(state, bestCandidate.City, c)).First();

                return(bestDriveFerryOrShuttleFlightTo);
            }

            return(bestCandidate == null?GetRandomNeighbour(state, startingLocation) : bestCandidate.City);
        }
Exemple #8
0
        public List <PandemicPlayerCard> GetWeakCityCards(IPandemicState state, PlayerRole playerRole, IEnumerable <PandemicPlayerCard> cards)
        {
            var weakCityCards = new List <PandemicPlayerCard>();
            var cardsByColour = GetCityCardsByColour(cards);

            // If we have a city card for a cured or eradicated disease then we can consider that as weak
            var diseaseStates = state.DiscoveredCures;

            foreach (var diseaseState in diseaseStates)
            {
                // if we have a card relating to a cured or eradicated disease, then is a weak card
                // ( we are not taking into account, if card is useful to facilitate flights here )
                if (diseaseState.Value == DiseaseState.Cured || diseaseState.Value == DiseaseState.Eradicated)
                {
                    weakCityCards.AddRange(cardsByColour[diseaseState.Key]);
                }
                else
                {
                    // card still considered weak, for uncured diseases, if there are only 1-2 of these colour in hand
                    // TODO this logic may change when we add in Share-Knowledge action, if other player needs that card
                    if (cardsByColour[diseaseState.Key].Count < 3)
                    {
                        weakCityCards.AddRange(cardsByColour[diseaseState.Key]);
                    }
                }
            }

            return(weakCityCards);
        }
 public void TakeActionsTurn(IPandemicState state, IPandemicTurn turn)
 {
     _state           = state;
     _currentPlayerId = turn.CurrentPlayerId;
     ApplyPlayerAction(_state, turn.ActionTaken);
     _state.ActionsPlayed++;
 }
        public void TakeDiscardCardsTurn(IPandemicState state, IPandemicTurn turn)
        {
            if (!turn.CardsToDiscard.Any())
            {
                return;
            }

            _state           = state;
            _currentPlayerId = turn.CurrentPlayerId;
            var playerState = _state.PlayerStates[_currentPlayerId];

            foreach (var cardToDiscard in turn.CardsToDiscard)
            {
                var cardInPlayerDeck = playerState.PlayerHand
                                       .SingleOrDefault(c => c.PlayerCardType == cardToDiscard.PlayerCardType && c.Value == cardToDiscard.Value);
                if (cardInPlayerDeck != null)
                {
                    playerState.PlayerHand.Remove(cardInPlayerDeck);
                    state.PlayerDiscardPile.AddCard(cardInPlayerDeck);
                    _stateDeltas.Add(new CardIsDrawnOrDiscardedDelta {
                        PlayerId = _currentPlayerId, PandemicPlayerCard = cardInPlayerDeck, DrawnOrDiscarded = DrawnOrDiscarded.Discarded
                    });
                }
            }
        }
        public bool ShouldPlayAirLift(IPandemicState state)
        {
            var bestCityOnBoard      = _routeHelper.GetBestLocationOnBoard(state.Cities);
            var valueOfBestCity      = _routeHelper.GetLocationValue(state, bestCityOnBoard);
            var playerLocationValues = state.PlayerStates.Select(s => _routeHelper.GetLocationValue(state, s.Value.Location));

            return(playerLocationValues.Any(lv => valueOfBestCity - lv > 3));
        }
Exemple #12
0
        public KnowledgeShare GetSuggestedKnowledgeShare(int currentPlayerId, IPandemicState state)
        {
            var currentPlayerState     = state.PlayerStates[currentPlayerId];
            var currentPlayerCityCards = currentPlayerState.PlayerHand
                                         .Where(c => c.PlayerCardType == PlayerCardType.City).Select(c => (City)c.Value).ToList();
            var diseaseStates = state.DiscoveredCures;
            var city          = currentPlayerState.Location;
            var playersWeCouldShareKnowledgeWith = PlayersWeCouldKnowledgeShareWith(currentPlayerId, state);

            // if we are a researcher, then we can give any city card ( can go other way too, but this will be sufficient for bot )
            if (currentPlayerState.PlayerRole == PlayerRole.Researcher)
            {
                var suggestedKnowledgeShare = GetSuggestedKnowledgeShareForResearcher(currentPlayerId, state,
                                                                                      playersWeCouldShareKnowledgeWith,
                                                                                      currentPlayerState, diseaseStates, currentPlayerCityCards);
                return(suggestedKnowledgeShare);
            }

            // if the current city is for a cured or eradicated disease - don't knowledge share
            if (diseaseStates[city.GetDefaultDisease()] != DiseaseState.NotCured)
            {
                return(null);
            }

            var playerToShareKnowledgeWith = playersWeCouldShareKnowledgeWith?.FirstOrDefault();

            if (playerToShareKnowledgeWith == null)
            {
                return(null);
            }

            // do not return a knowledgeShare unless it improves gameState
            // Otherwise we may just be knowledge sharing the same card back and forth !
            var disease = city.GetDefaultDisease();

            if (diseaseStates[disease] != DiseaseState.NotCured)
            {
                return(null);
            }

            var candidatePlayer = state.PlayerStates[playerToShareKnowledgeWith.Value];
            var ourDiseaseCount = currentPlayerState.PlayerHand
                                  .Count(c => c.PlayerCardType == PlayerCardType.City && ((City)c.Value).GetDefaultDisease() == disease);
            var candidateDiseaseCount = candidatePlayer.PlayerHand
                                        .Count(c => c.PlayerCardType == PlayerCardType.City && ((City)c.Value).GetDefaultDisease() == disease);

            if (ourDiseaseCount == 0 || candidateDiseaseCount <= ourDiseaseCount)
            {
                return(null);
            }

            return(new KnowledgeShare
            {
                Player1 = currentPlayerId,
                Player2 = playerToShareKnowledgeWith.Value,
                CityCardToGive = state.PlayerStates[currentPlayerId].Location
            });
        }
Exemple #13
0
        public City GetRandomNeighbour(IPandemicState state, City startingLocation)
        {
            var connectionCount = state.Cities.Single(n => n.City == startingLocation).ConnectedCities.Count();
            var moveDie         = new Die(connectionCount);
            var moveDieRoll     = moveDie.Roll();
            var moveTo          = state.Cities.Single(n => n.City == startingLocation).ConnectedCities.ToArray()[moveDieRoll - 1];

            return(moveTo);
        }
        public InfectionDeckTests()
        {
            _gameState   = new PandemicState();
            _stateEditor = new PandemicStateEditor(new PandemicActionValidator());
            _stateEditor.Clear(_gameState);
            var players = new List <PandemicBotStandard>();

            _stateEditor.Setup(_gameState, players);
        }
        public void Clear(IPandemicState state, int pandemicCardCount = 6)
        {
            _state               = state;
            _state.Id            = "1"; // TODO Guid.NewGuid().ToString();
            _stateDeltas         = new List <IDelta>();
            _state.ActionsPlayed = 0;
            _state.OutbreakCount = 0;
            var players = new List <IPlayer <IPandemicTurn> >();

            SetupPlayerStates(_state, players);
            _state.IsGameOver = false;
            _state.Cities     = new List <MapNode>();

            _state.InfectionDeck        = new InfectionDeck();
            _state.InfectionDiscardPile = new CardDeck <Card>();
            _state.PlayerDeck           = new PlayerDeck();
            _state.EventCardsQueue      = new PlayerDeck();
            _state.PandemicCardCount    = pandemicCardCount;
            _state.PlayerDiscardPile    = new PlayerDeck();
            SetupPlayerDeck(_state);

            _state.DiscoveredCures     = new Dictionary <Disease, DiseaseState>();
            _state.InfectionRateMarker = 0;
            _state.InfectionRateTrack  = new int[] { 2, 2, 2, 3, 3, 4, 4 };

            var nodeFactory = new MapNodeFactory();

            var cities = Enum.GetValues(typeof(City));

            foreach (var city in cities)
            {
                _state.Cities.Add(nodeFactory.CreateMapNode((City)city));
            }

            _state.ResearchStationStock = 6;

            _state.DiseaseCubeReserve = new Dictionary <Disease, int>
            {
                { Disease.Blue, 24 },
                { Disease.Black, 24 },
                { Disease.Red, 24 },
                { Disease.Yellow, 24 }
            };

            _state.DiscoveredCures = new Dictionary <Disease, DiseaseState>
            {
                { Disease.Blue, DiseaseState.NotCured },
                { Disease.Black, DiseaseState.NotCured },
                { Disease.Red, DiseaseState.NotCured },
                { Disease.Yellow, DiseaseState.NotCured }
            };

            // Atlanta starts with a research station
            _state.Cities.Single(c => c.City == City.Atlanta).HasResearchStation = true;
            _state.ResearchStationStock--;
        }
        private void AddDiseaseCubes(IPandemicState state, City city, int count = 1)
        {
            _state = state;
            var disease = city.GetDefaultDisease();

            for (var i = 0; i < count; i++)
            {
                AddDiseaseCube(_state, disease, city);
            }
        }
 public IEnumerable <IDelta> Setup(IPandemicState state, IEnumerable <IPlayer <IPandemicTurn> > players, int pandemicCardCount = 6)
 {
     _state       = state;
     _stateDeltas = new List <IDelta>();
     Clear(_state);
     _state.PandemicCardCount = pandemicCardCount;
     SetupPlayerStates(_state, players);
     PerformInitialInfections(_state);
     return(_stateDeltas);
 }
        public bool ShouldPlayOneQuietNight(IPandemicState state)
        {
            var citiesWithThreeOfOneDisease = state.Cities
                                              .Where(c => c.DiseaseCubes[Disease.Black] == 3 ||
                                                     c.DiseaseCubes[Disease.Blue] == 3 ||
                                                     c.DiseaseCubes[Disease.Yellow] == 3 ||
                                                     c.DiseaseCubes[Disease.Blue] == 3);

            return(citiesWithThreeOfOneDisease.Count() > 3 && state.InfectionRateMarker > 1);
        }
        // TODO state deltas
        public IEnumerable <IDelta> InfectCities(IPandemicState state)
        {
            _state       = state;
            _stateDeltas = new List <IDelta>();

            var oneQuietNightCard = _state.EventCardsQueue.Cards
                                    .SingleOrDefault(c => c.PlayerCardType == PlayerCardType.Event && (EventCard)c.Value == EventCard.OneQuietNight);

            if (oneQuietNightCard != null)
            {
                state.PlayerDiscardPile.AddCard(oneQuietNightCard);
                state.EventCardsQueue.Cards.Remove(oneQuietNightCard);
                _stateDeltas.Add(new CardIsDrawnOrDiscardedDelta {
                    PlayerId = _currentPlayerId, PandemicPlayerCard = oneQuietNightCard, DrawnOrDiscarded = DrawnOrDiscarded.Discarded
                });
                return(_stateDeltas);
            }

            var infectionRate = _state.InfectionRateTrack[_state.InfectionRateMarker];

            if (_state.InfectionDeck.CardCount < infectionRate)
            {
                _state.IsGameOver     = true;
                _state.GameOverReason = "Infection deck empty";
                return(_stateDeltas);
            }

            var infectionCards = _state.InfectionDeck.Draw(infectionRate).ToList();

            foreach (var infectionCard in infectionCards)
            {
                if (!_state.IsGameOver)
                {
                    var city    = (City)infectionCard.Value;
                    var disease = city.GetDefaultDisease();
                    AddDiseaseCube(_state, disease, city);
                }
            }

            if (!state.IsGameOver)
            {
                _state.InfectionDiscardPile.AddCards(infectionCards);
                foreach (var infectionCard in infectionCards)
                {
                    _stateDeltas.Add(new CardIsDrawnOrDiscardedDelta
                    {
                        InfectionCard    = (City)infectionCard.Value,
                        DrawnOrDiscarded = DrawnOrDiscarded.Discarded
                    });
                }
            }

            return(_stateDeltas);
        }
        private void DriveOrFerry(IPandemicState state, City city)
        {
            _state = state;
            var playerState = _state.PlayerStates[_currentPlayerId];

            playerState.Location = city;
            _stateDeltas.Add(new PlayerMovedDelta()
            {
                PlayerId = _currentPlayerId,
                City     = city
            });
        }
        public IEnumerable <string> ValidatePlayerEventPlayed(int playerId, IPandemicState state, PlayerEventPlayed newEventCard)
        {
            var validationFailures = new List <string>();
            var playerState        = state.PlayerStates[playerId];

            if (!playerState.PlayerHand.Any(c => c.PlayerCardType == PlayerCardType.Event && (EventCard)c.Value == newEventCard.EventCard))
            {
                validationFailures.Add($"Player doesn't have event card {newEventCard.EventCard}");
            }

            return(validationFailures);
        }
 private PandemicPlayerState GetPlayerStateByRole(IPandemicState state, PlayerRole playerRole)
 {
     _state = state;
     foreach (var playerState in _state.PlayerStates)
     {
         if (playerState.Value.PlayerRole == playerRole)
         {
             return(playerState.Value);
         }
     }
     return(null);
 }
        public IEnumerable <string> ValidatePlayerAction(int playerId, IPandemicState state, PlayerAction newPlayerAction)
        {
            var validationFailures = new List <string>();
            var validationFailure  = GetActionValidationFailures(state, playerId, newPlayerAction);

            if (!string.IsNullOrWhiteSpace(validationFailure))
            {
                validationFailures.Add(validationFailure);
            }

            return(validationFailures);
        }
        public void AddDiseaseCube(IPandemicState state, Disease disease, City city, List <City> ignoreCities = null)
        {
            _state = state;
            var node = _state.Cities.Single(n => n.City == city);


            // Dont place disease if quarantineSpecialist is here or in neighbouring city
            var quarantineSpecialist = GetPlayerStateByRole(_state, PlayerRole.QuarantineSpecialist);

            if (quarantineSpecialist != null)
            {
                if (quarantineSpecialist.Location == city || _state.Cities.Single(n => n.City == quarantineSpecialist.Location).ConnectedCities.Contains(city))
                {
                    return;
                }
            }

            ignoreCities = ignoreCities ?? new List <City>();

            if (node.DiseaseCubes[disease] < 3)
            {
                if (_state.DiseaseCubeReserve[disease] == 0)
                {
                    _state.IsGameOver     = true;
                    _state.GameOverReason = $"Ran out of {disease} disease cubes";
                    return;
                }

                node.DiseaseCubes[disease] += 1;
                _state.DiseaseCubeReserve[disease]--;
                _stateDeltas.Add(new DiseaseChangedDelta()
                {
                    City = city, Disease = disease, NewAmount = node.DiseaseCubes[disease]
                });

                return;
            }

            _state.OutbreakCount++;

            if (_state.OutbreakCount > 7)
            {
                _state.IsGameOver     = true;
                _state.GameOverReason = "More than seven outbreaks";
                return;
            }

            ignoreCities.Add(city);
            foreach (var connectedCity in node.ConnectedCities.Where(c => !ignoreCities.Contains(c)))
            {
                AddDiseaseCube(_state, disease, connectedCity, ignoreCities);
            }
        }
Exemple #25
0
        public List <PandemicPlayerCard> GetCardsToDiscardToCure(IPandemicState state, Disease disease, PlayerRole playerRole, IEnumerable <PandemicPlayerCard> cards)
        {
            var cardCountToDiscard = playerRole == PlayerRole.Scientist ? 4 : 5;
            var candidateDiscards  = GetCityCardsByColour(cards)[disease];

            if (cardCountToDiscard > candidateDiscards.Count)
            {
                throw new CardboardException($"Cant find enough cards to discard to cure disease {disease}");
            }

            return(candidateDiscards.Take(cardCountToDiscard).ToList());
        }
        public IEnumerable <IDelta> Epidemic(IPandemicState state)
        {
            _state       = state;
            _stateDeltas = new List <IDelta>();
            var bottomCard = _state.InfectionDeck.DrawBottom();

            _state.InfectionDiscardPile.AddCard(bottomCard);
            AddDiseaseCubes(_state, (City)bottomCard.Value, 3);

            // Intensify
            _state.InfectionDiscardPile.Shuffle();
            _state.InfectionDeck.AddCardDeck(_state.InfectionDiscardPile, CardDeckPosition.Top);

            _state.InfectionRateMarker++;
            return(_stateDeltas);
        }
        public void TakePlayEventCardsTurn(IPandemicState state, IPandemicTurn turn)
        {
            if (turn.EventCardsPlayed == null || !turn.EventCardsPlayed.Any())
            {
                return;
            }

            _state           = state;
            _currentPlayerId = turn.CurrentPlayerId;
            var playerState = _state.PlayerStates[_currentPlayerId];

            foreach (var eventCardToPlay in turn.EventCardsPlayed)
            {
                if (eventCardToPlay.EventCard == EventCard.OneQuietNight)
                {
                    var card = playerState.PlayerHand.Single(c => c.PlayerCardType == PlayerCardType.Event && (EventCard)c.Value == EventCard.OneQuietNight);
                    _state.EventCardsQueue.AddCard(card);
                    playerState.PlayerHand.Remove(card);
                    state.PlayerDiscardPile.AddCard(card);
                    _stateDeltas.Add(new CardIsDrawnOrDiscardedDelta {
                        PlayerId = _currentPlayerId, PandemicPlayerCard = card, DrawnOrDiscarded = DrawnOrDiscarded.Discarded
                    });
                }

                if (eventCardToPlay.EventCard == EventCard.GovernmentGrant)
                {
                    var card = playerState.PlayerHand.Single(c => c.PlayerCardType == PlayerCardType.Event && (EventCard)c.Value == EventCard.GovernmentGrant);
                    BuildResearchStationWithGovernmentGrant(_state, eventCardToPlay.City.Value);
                    playerState.PlayerHand.Remove(card);
                    state.PlayerDiscardPile.AddCard(card);
                    _stateDeltas.Add(new CardIsDrawnOrDiscardedDelta {
                        PlayerId = _currentPlayerId, PandemicPlayerCard = card, DrawnOrDiscarded = DrawnOrDiscarded.Discarded
                    });
                }

                if (eventCardToPlay.EventCard == EventCard.Airlift)
                {
                    var card = playerState.PlayerHand.Single(c => c.PlayerCardType == PlayerCardType.Event && (EventCard)c.Value == EventCard.Airlift);
                    _state.PlayerStates[eventCardToPlay.PlayerId].Location = eventCardToPlay.City.Value;
                    playerState.PlayerHand.Remove(card);
                    state.PlayerDiscardPile.AddCard(card);
                    _stateDeltas.Add(new CardIsDrawnOrDiscardedDelta {
                        PlayerId = _currentPlayerId, PandemicPlayerCard = card, DrawnOrDiscarded = DrawnOrDiscarded.Discarded
                    });
                }
            }
        }
        private void ApplyPlayerAction(IPandemicState state, PlayerAction action)
        {
            _state           = state;
            _currentPlayerId = action.PlayerId;

            var validationFailures = _validator.ValidatePlayerAction(_currentPlayerId, state, action).ToList();

            if (validationFailures.Any())
            {
                throw new CardboardException(validationFailures[0]);
            }

            switch (action.PlayerActionType)
            {
            case PlayerActionType.TreatDisease:
                TreatDisease(_state, action.City, action.Disease);
                break;

            case PlayerActionType.DriveOrFerry:
                DriveOrFerry(_state, action.City);
                break;

            case PlayerActionType.BuildResearchStation:
                BuildResearchStation(_state, action.City);
                break;

            case PlayerActionType.CharterFlight:
                CharterFlight(_state, action.City);
                break;

            case PlayerActionType.DirectFlight:
                DirectFlight(_state, action.City);
                break;

            case PlayerActionType.ShuttleFlight:
                ShuttleFlight(_state, action.City);
                break;

            case PlayerActionType.DiscoverCure:
                DiscoverCure(_state, action.Disease, action.CardsToDiscard);
                break;

            case PlayerActionType.ShareKnowledge:
                ShareKnowledge(_state, action.City, action.PlayerId, action.OtherPlayerId);
                break;
            }
        }
Exemple #29
0
        public Graph <City, string> GetCityGraph(IPandemicState state)
        {
            var citiesWithResearchStations = state.Cities.Where(n => n.HasResearchStation).ToList();
            var cacheKey     = citiesWithResearchStations.Count < 2 ? "Pandemic.CityGraph" : $"Pandemic.{state.Id}.CityGraph.R{state.ResearchStationStock}";
            var cacheExpires = citiesWithResearchStations.Count < 2 ? TimeSpan.FromMinutes(30) : TimeSpan.FromMilliseconds(2000);

            Graph <City, string> cacheEntry;

            if (_memoryCache.TryGetValue(cacheKey, out cacheEntry))
            {
                return(cacheEntry);
            }

            var graph = new Graph <City, string>();

            foreach (var city in Enum.GetValues(typeof(City)))
            {
                graph.AddNode((City)city);
            }

            foreach (var cityNode in state.Cities)
            {
                foreach (var connectedCity in cityNode.ConnectedCities)
                {
                    graph.Connect((uint)cityNode.City + 1, (uint)connectedCity + 1, 1, $"{cityNode.City}-{connectedCity}");
                }

                // Connect all cities with research stations together
                if (cityNode.HasResearchStation)
                {
                    foreach (var researchStationCity in citiesWithResearchStations)
                    {
                        if (researchStationCity.City != cityNode.City)
                        {
                            graph.Connect((uint)cityNode.City + 1, (uint)researchStationCity.City + 1, 1, $"Shuttle:{cityNode.City}-{researchStationCity.City}");
                        }
                    }
                }
            }

            cacheEntry = graph;
            var cacheEntryOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(cacheExpires);

            _memoryCache.Set(cacheKey, cacheEntry, cacheEntryOptions);

            return(graph);
        }
Exemple #30
0
        public Tests()
        {
            _serviceProvider = ServiceProviderFactory.GetServiceProvider(new MessageSenderConfiguration());
            _stateEditor     = _serviceProvider.GetService <IPandemicStateEditor>();
            _playerFactory   = _serviceProvider.GetService <IPlayerFactory <IPandemicTurn> >();

            _sut = _playerFactory.CreatePlayers(new PlayerConfiguration {
                PlayerCount = 1
            }).SingleOrDefault();

            _state = _serviceProvider.GetService <IPandemicState>();
            _stateEditor.Clear(_state, 6);

            var turnValidator = A.Fake <IPandemicActionValidator>();

            _turn = new PandemicTurn(turnValidator);
        }