예제 #1
0
        public Game(
            IList <Player> players,
            IList <InternalThreat> internalThreats,
            IList <ExternalThreat> externalThreats,
            IList <Threat> bonusThreats,
            IDictionary <ZoneLocation, TrackConfiguration> externalTrackConfigurationsByZone,
            TrackConfiguration internalTrackConfiguration,
            ILookup <ZoneLocation, DamageToken> initialDamage)
        {
            EventMaster   = new EventMaster();
            GameStatus    = GameStatus.InProgress;
            NumberOfTurns = 12;
            var externalTracksByZone = externalTrackConfigurationsByZone.ToDictionary(
                trackConfigurationWithZone => trackConfigurationWithZone.Key,
                trackConfigurationWithZone => new Track(trackConfigurationWithZone.Value));
            var internalTrack = new Track(internalTrackConfiguration);

            ThreatController = new ThreatController(externalTracksByZone, internalTrack, externalThreats, internalThreats, EventMaster);
            ThreatController.PhaseStarting += (sender, args) => PhaseStarting(this, args);
            SittingDuck = new SittingDuck(ThreatController, this, initialDamage);
            var allThreats = bonusThreats.Concat(internalThreats).Concat(externalThreats);

            foreach (var threat in allThreats)
            {
                threat.Initialize(SittingDuck, ThreatController, EventMaster);
            }
            SittingDuck.SetPlayers(players);
            Players = players;
            foreach (var player in players)
            {
                player.Initialize(SittingDuck);
            }
            PadPlayerActions();
        }
예제 #2
0
        internal SittingDuck(ThreatController threatController, Game game, ILookup <ZoneLocation, DamageToken> initialDamage)
        {
            ThreatController = threatController;
            threatController.ThreatAttackedShip += TakeAttack;
            Game = game;

            var redDoors  = new Doors();
            var blueDoors = new Doors();


            var interceptors = new Interceptors();

            var interceptorStation1 = CreateInterceptorStation1(threatController);
            var interceptorStation2 = CreateInterceptorStation2(threatController);
            var interceptorStation3 = CreateInterceptorStation3(threatController);

            BlueDoors = blueDoors;
            RedDoors  = redDoors;
            WhiteZone = CreateWhiteZone(threatController, initialDamage, redDoors, blueDoors);
            RedZone   = CreateRedZone(threatController, initialDamage, redDoors, WhiteZone, interceptors);
            BlueZone  = CreateBlueZone(threatController, initialDamage, WhiteZone, blueDoors);

            ZonesByLocation     = new Zone[] { RedZone, WhiteZone, BlueZone }.ToDictionary(zone => zone.ZoneLocation);
            InterceptorStations = new [] { interceptorStation1, interceptorStation2, interceptorStation3 };
            StationsByLocation  = Zones
                                  .SelectMany(zone => new Station[] { zone.LowerStation, zone.UpperStation })
                                  .Concat(InterceptorStations)
                                  .ToDictionary(station => station.StationLocation);
            StandardStationsByLocation = Zones
                                         .SelectMany(zone => new StandardStation[] { zone.LowerStation, zone.UpperStation })
                                         .ToDictionary(station => station.StationLocation);
        }
예제 #3
0
        private void PerformPlayerActions()
        {
            PhaseStarting(this, new PhaseEventArgs
            {
                PhaseHeader = ResolutionPhase.PerformPlayerActions.GetDescription()
            });
            foreach (var player in Players)
            {
                player.PerformStartOfPlayerActions(CurrentTurn);
            }

            var playerOrder = Players
                              .Where(player => !player.IsKnockedOut)
                              .OrderByDescending(player => player.IsPerformingMedic(CurrentTurn))
                              .ThenBy(player => player.Index);

            foreach (var player in playerOrder)
            {
                EventMaster.LogEvent(player.PlayerColor.ToString());
                while (!player.GetActionForTurn(CurrentTurn).AllActionsPerformed())
                {
                    player.CurrentStation.PerformNextPlayerAction(player, CurrentTurn);
                }
            }
            ThreatController.OnPlayerActionsEnded();
        }
예제 #4
0
        private void PerformEndOfGame()
        {
            PhaseStarting(this, new PhaseEventArgs {
                PhaseHeader = ResolutionPhase.FinalRocketMove.GetDescription()
            });
            var rocketFiredLastTurn = SittingDuck.BlueZone.LowerBlueStation.RocketsComponent.RocketFiredLastTurn;

            if (rocketFiredLastTurn != null)
            {
                ResolveDamage(new [] { rocketFiredLastTurn.PerformAttack(null) }, new List <PlayerInterceptorDamage>());
            }

            PhaseStarting(this, new PhaseEventArgs {
                PhaseHeader = ResolutionPhase.InterceptorsReturnToShip.GetDescription()
            });
            var playersInFarInterceptors = SittingDuck.InterceptorStations
                                           .Where(station => station.StationLocation.DistanceFromShip() > 1)
                                           .SelectMany(station => station.Players);

            foreach (var player in playersInFarInterceptors)
            {
                player.KnockOut();
            }

            ThreatController.MoveThreats(CurrentTurn);

            PhaseStarting(this, new PhaseEventArgs {
                PhaseHeader = ResolutionPhase.JumpToHyperspace.GetDescription()
            });
            ThreatController.OnJumpingToHyperspace();

            CalculateScore();
            GameStatus = GameStatus.Won;
        }
예제 #5
0
        private InterceptorStation CreateInterceptorStation2(ThreatController threatController)
        {
            var interceptorComponent2 = new InterceptorsInSpaceComponent(this, StationLocation.Interceptor2);
            var interceptorStation2   = new InterceptorStation(
                StationLocation.Interceptor2,
                threatController,
                interceptorComponent2);

            return(interceptorStation2);
        }
예제 #6
0
        private InterceptorStation CreateInterceptorStation3(ThreatController threatController)
        {
            var interceptorComponent3 = new InterceptorsInSpaceComponent(this, StationLocation.Interceptor3);
            var interceptorStation3   = new InterceptorStation(
                StationLocation.Interceptor3,
                threatController,
                interceptorComponent3);

            return(interceptorStation3);
        }
예제 #7
0
        private InterceptorStation CreateInterceptorStation1(ThreatController threatController)
        {
            var interceptorComponent1 = new InterceptorsInSpaceComponent(this, StationLocation.Interceptor1);
            var interceptorStation1   = new InterceptorStation(
                StationLocation.Interceptor1,
                threatController,
                interceptorComponent1);

            return(interceptorStation1);
        }
예제 #8
0
        private WhiteZone CreateWhiteZone(
            ThreatController threatController,
            ILookup <ZoneLocation, DamageToken> initialDamage,
            Doors redDoors,
            Doors blueDoors)
        {
            var whiteZone = new WhiteZone(threatController, redDoors, blueDoors, this);

            DamageZone(initialDamage, ZoneLocation.White, whiteZone);
            whiteZone.UpperWhiteStation.AlphaComponent.CannonFired += (sender, args) => CentralLaserCannonFired(this, EventArgs.Empty);
            return(whiteZone);
        }
예제 #9
0
        private RedZone CreateRedZone(
            ThreatController threatController,
            ILookup <ZoneLocation, DamageToken> initialDamage,
            Doors redDoors,
            WhiteZone whiteZone,
            Interceptors interceptors)
        {
            var redZone = new RedZone(threatController, whiteZone.LowerWhiteStation.CentralReactor, redDoors, this, interceptors);

            DamageZone(initialDamage, ZoneLocation.Red, redZone);
            return(redZone);
        }
예제 #10
0
        private BlueZone CreateBlueZone(
            ThreatController threatController,
            ILookup <ZoneLocation, DamageToken> initialDamage,
            WhiteZone whiteZone,
            Doors blueDoors)
        {
            var blueZone = new BlueZone(threatController, whiteZone.LowerWhiteStation.CentralReactor, blueDoors, this);

            DamageZone(initialDamage, ZoneLocation.Blue, blueZone);
            blueZone.LowerBlueStation.RocketsComponent.RocketsModified += (sender, args) => RocketsModified(sender, args);
            return(blueZone);
        }
예제 #11
0
 private void PerformEndOfTurn()
 {
     foreach (var zone in SittingDuck.Zones)
     {
         zone.Gravolift.PerformEndOfTurn();
         zone.UpperStation.PerformEndOfTurn();
         zone.LowerStation.PerformEndOfTurn();
         foreach (var player in Players)
         {
             player.PerformEndOfTurn();
         }
     }
     SittingDuck.WhiteZone.LowerWhiteStation.VisualConfirmationComponent.PerformEndOfTurn();
     SittingDuck.BlueZone.LowerBlueStation.RocketsComponent.PerformEndOfTurn();
     foreach (var interceptorStation in SittingDuck.InterceptorStations)
     {
         interceptorStation.PerformEndOfTurn();
     }
     ThreatController.PerformEndOfTurn();
 }
예제 #12
0
        public void PerformTurn()
        {
            try
            {
                if (CurrentTurn == NumberOfTurns + 1)
                {
                    PerformEndOfGame();
                    return;
                }
                ThreatController.AddNewThreatsToTracks(CurrentTurn);

                PerformPlayerActions();

                var damage            = GetStandardDamage();
                var interceptorDamage = GetInterceptorDamage();
                ResolveDamage(damage, interceptorDamage);

                ThreatController.MoveThreats(CurrentTurn);

                PerformEndOfTurn();

                if (SittingDuck.WhiteZone.UpperWhiteStation.ComputerComponent.ShouldCheckComputer(CurrentTurn))
                {
                    CheckForComputer();
                }

                var isEndOfPhase = phaseEndTurns.Contains(CurrentTurn);
                if (isEndOfPhase)
                {
                    PerformEndOfPhase();
                }

                CurrentTurn++;
            }
            catch (LoseException loseException)
            {
                GameStatus = GameStatus.Lost;
                KilledBy   = loseException.Threat.DisplayName;
                LostGame(this, EventArgs.Empty);
            }
        }
예제 #13
0
        private void ResolveDamage(
            IEnumerable <PlayerDamage> damages,
            IEnumerable <PlayerInterceptorDamage> interceptorDamages)
        {
            PhaseStarting(this, new PhaseEventArgs {
                PhaseHeader = ResolutionPhase.ResolveDamage.GetDescription()
            });
            if (!ThreatController.DamageableExternalThreats.Any())
            {
                return;
            }
            var damagesByThreat = new Dictionary <ExternalThreat, IList <PlayerDamage> >();

            foreach (var damage in damages)
            {
                var priorityThreatsInRange = ThreatController.DamageableExternalThreats
                                             .Where(threat =>
                                                    threat.IsPriorityTargetFor(damage) &&
                                                    threat.CanBeTargetedBy(damage))
                                             .ToList();
                var threatsInRange = ThreatController.DamageableExternalThreats
                                     .Where(threat => threat.CanBeTargetedBy(damage))
                                     .ToList();
                switch (damage.PlayerDamageType.DamageTargetType())
                {
                case DamageTargetType.All:
                    foreach (var threat in threatsInRange)
                    {
                        AddToDamagesByThreat(threat, damage, damagesByThreat);
                    }
                    break;

                case DamageTargetType.Single:
                    var priorityThreatHit = priorityThreatsInRange
                                            .OrderBy(threat => threat.TimeAppears)
                                            .FirstOrDefault();
                    if (priorityThreatHit != null)
                    {
                        AddToDamagesByThreat(priorityThreatHit, damage, damagesByThreat);
                    }
                    else
                    {
                        var threatHit = threatsInRange
                                        .OrderBy(threat => threat.Position)
                                        .ThenBy(threat => threat.TimeAppears)
                                        .FirstOrDefault();
                        if (threatHit != null)
                        {
                            AddToDamagesByThreat(threatHit, damage, damagesByThreat);
                        }
                    }
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }
            foreach (var interceptorDamage in interceptorDamages)
            {
                AddInterceptorDamages(interceptorDamage, damagesByThreat);
            }

            foreach (var threat in damagesByThreat.Keys)
            {
                threat.TakeDamage(damagesByThreat[threat]);
            }

            ThreatController.PerformEndOfDamageResolution();
        }