Example #1
0
 public static void GhostEaten(GameState gameState, Ghost ghost, Game game, GameNotifications gameNotifications)
 {
     SendGhostHome(gameState, ghost);
     IncreaseScoreAfterEatingGhost(gameState, game);
     MakeGhostNotEdible(gameState, ghost);
     gameNotifications.Publish(GameNotification.EatGhost);
 }
Example #2
0
 public static void SetupGame(GameState gameState, DateTime now, GameNotifications gameNotifications)
 {
     gameState.RecordLastTick(now);
     MoveGhostsHome(gameState);
     gameState.ShowGhosts();
     gameNotifications.Publish(GameNotification.Beginning);
 }
Example #3
0
 internal Actions(IGameSettings gameSettings, GameNotifications gameNotifications)
 {
     _gameSettings = gameSettings;
     _gameNotifications = gameNotifications;
 }
Example #4
0
        public GameStateMachine(IGameActions game, IGameSettings settings, GameNotifications gameNotifications)
        {
            InstanceState(x => x.Status);

            DuringAny(
                When(Tick)
                .Then(context => context.Instance.LastTick = context.Data.Now));

            Initially(
                When(Tick)
                .Then(context => context.Instance.LastTick = context.Data.Now)
                .Then(context => game.MoveGhostsHome())
                .Then(context => game.ShowGhosts(context.Instance))
                .Then(context => gameNotifications.Publish(GameNotification.Beginning))
                .TransitionTo(Scatter));

            WhenEnter(Scatter,
                      binder => binder
                      .Then(context => context.Instance.TimeToChangeState = context.Instance.LastTick.AddSeconds(settings.InitialScatterTimeInSeconds))
                      .Then(context => game.ScatterGhosts()));

            During(Scatter,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .TransitionTo(GhostChase));

            WhenEnter(GhostChase,
                      binder => binder
                      .Then(context => context.Instance.TimeToChangeState = context.Instance.LastTick.AddSeconds(settings.ChaseTimeInSeconds))
                      .Then(context => game.GhostToChase()));

            During(GhostChase,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .TransitionTo(Scatter));

            During(Frightened,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .Then(x => game.MakeGhostsNotEdible())
                   .TransitionTo(Scatter));

            During(Scatter, GhostChase, Frightened,
                   When(Tick)
                   .ThenAsync(async context => await game.MoveGhosts(context, this))
                   .Then(context => game.MovePacMan(context, this)),
                   When(CoinEaten)
                   .Then(context => context.Instance.Score += 10)
                   .Then(context => gameNotifications.Publish(GameNotification.EatCoin)),
                   When(PowerPillEaten)
                   .Then(context => context.Instance.Score += 50)
                   .Then(context => gameNotifications.Publish(GameNotification.EatPowerPill))
                   .Then(context => game.MakeGhostsEdible())
                   .Then(context => context.Instance.TimeToChangeState = context.Instance.LastTick.AddSeconds(7))
                   .TransitionTo(Frightened),
                   When(GhostCollision)
                   .IfElse(x => x.Data.Ghost.Edible,
                           binder => binder.Then(x => game.SendGhostHome(x.Data.Ghost)),
                           binder => binder.Then(context => context.Instance.Lives -= 1)
                           .TransitionTo(Dying)));

            WhenEnter(Dying,
                      binder => binder
                      .Then(context => context.Instance.TimeToChangeState = context.Instance.LastTick.AddSeconds(4))
                      .Then(context => gameNotifications.Publish(GameNotification.Dying)));

            During(Dying,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .Then(context => game.HideGhosts(context.Instance))
                   .Then(context => context.Instance.TimeToChangeState = context.Data.Now.AddSeconds(4))
                   .IfElse(context => context.Instance.Lives > 0,
                           binder => binder.TransitionTo(Respawning),
                           binder => binder.TransitionTo(Dead)));

            WhenEnter(Respawning,
                      binder => binder
                      .Then(context => gameNotifications.Publish(GameNotification.Respawning)));

            During(Respawning,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .Then(context => context.Instance.TimeToChangeState = context.Data.Now.AddSeconds(4))
                   .Then(context => game.MoveGhostsHome())
                   .Then(context => game.MovePacManHome())
                   .Then(context => game.ShowGhosts(context.Instance))
                   .TransitionTo(GhostChase));

            During(Dead, Ignore(Tick));
        }
Example #5
0
        public GameStateMachine(IGameSettings settings, GameNotifications gameNotifications, Game game)
        {
            InstanceState(x => x.Status);

            DuringAny(
                When(Tick)
                .Then(context => Actions.Tick(context.Instance, context.Data.Now, gameNotifications)));

            Initially(
                When(Tick)
                .Then(context => Actions.SetupGame(context.Instance, context.Data.Now, gameNotifications))
                .TransitionTo(Scatter));

            WhenEnter(Scatter,
                      binder => binder
                      .Then(context => context.Instance.ChangeStateIn(settings.InitialScatterTimeInSeconds))
                      .Then(context => Actions.ScatterGhosts(context.Instance)));

            During(Scatter,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .TransitionTo(GhostChase));

            During(ChangingLevel,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .TransitionTo(Scatter));

            WhenLeave(ChangingLevel, binder => binder.Then(context => Actions.GetReadyForNextLevel(context.Instance, settings)));

            WhenEnter(GhostChase,
                      binder => binder
                      .Then(context => context.Instance.ChangeStateIn(settings.ChaseTimeInSeconds))
                      .Then(context => Actions.GhostToChase(context.Instance)));

            During(GhostChase,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .TransitionTo(Scatter));

            During(Frightened,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .Then(context => Actions.MakeGhostsNotEdible(context.Instance))
                   .TransitionTo(Scatter));

            During(Scatter, GhostChase, Frightened,
                   When(PlayersWishesToChangeDirection)
                   .Then(context => Actions.ChangeDirection(game, context.Instance, context.Data.NewDirection)),
                   When(Tick)
                   .ThenAsync(async context => await Actions.MoveGhosts(game, context.Instance, context, this))
                   .ThenAsync(async context => await Actions.MovePacMan(game, context.Instance, context, this, settings)),
                   When(CoinCollision)
                   .Then(context => Actions.CoinEaten(game, settings, context.Instance, context.Data.Location, gameNotifications))
                   .If(context => context.Instance.IsLevelComplete(),
                       binder => binder.TransitionTo(ChangingLevel)),
                   When(FruitCollision)
                   .Then(context => Actions.FruitEaten(game, settings, context.Instance, context.Data.Location, gameNotifications)),
                   When(PowerPillCollision)
                   .Then(context => Actions.PowerPillEaten(settings, context.Instance, context.Data.Location, gameNotifications))
                   .IfElse(context => context.Instance.IsLevelComplete(),
                           binder => binder.TransitionTo(ChangingLevel),
                           binder =>
                           binder.Then(context => context.Instance.ChangeStateIn(settings.FrightenedTimeInSeconds))
                           .TransitionTo(Frightened)),
                   When(GhostCollision)
                   .IfElse(x => x.Data.Ghost.Edible,
                           binder => binder.Then(context => Actions.GhostEaten(context.Instance, context.Data.Ghost, game, gameNotifications)),
                           binder => binder.Then(context => Actions.EatenByGhost(context.Instance))
                           .TransitionTo(Dying)));


            WhenEnter(ChangingLevel,
                      binder => binder
                      .Then(context => context.Instance.HideGhosts())
                      .Then(context => context.Instance.ChangeStateIn(4)));


            WhenEnter(Dying,
                      binder => binder
                      .Then(context => Actions.BeginDying(context.Instance, gameNotifications))
                      .Then(context => context.Instance.ChangeStateIn(4)));

            During(Dying,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .IfElse(context => context.Instance.Lives > 0,
                           binder => binder.TransitionTo(Respawning),
                           binder => binder.TransitionTo(Dead)));

            WhenEnter(Respawning,
                      binder => binder
                      .Then(context => context.Instance.ChangeStateIn(4))
                      .Then(context => Actions.BeginRespawning(gameNotifications)));

            During(Respawning,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .Then(context => Actions.CompleteRespawning(context.Instance, settings))
                   .TransitionTo(Scatter));

            During(Dead, Ignore(Tick));

            During(Dying, Respawning, Dead, ChangingLevel,
                   Ignore(PlayersWishesToChangeDirection),
                   Ignore(CoinCollision),
                   Ignore(PowerPillCollision),
                   Ignore(GhostCollision));
        }
Example #6
0
 public static void PowerPillEaten(IGameSettings gameSettings, GameState gameState, CellLocation powerPillLocation, GameNotifications gameNotifications)
 {
     gameState.IncreaseScore(50);
     gameNotifications.Publish(GameNotification.EatPowerPill);
     MakeGhostsEdible(gameSettings, gameState);
     gameState.RemovePowerPill(powerPillLocation);
 }
Example #7
0
 public static void CoinEaten(Game game, IGameSettings settings, GameState gameState, CellLocation coinLocation, GameNotifications gameNotifications)
 {
     gameState.RemoveCoin(coinLocation);
     gameState.IncreaseScore(10);
     if (settings.FruitAppearsAfterCoinsEaten.Contains(game.StartingCoins.Count - game.Coins.Count))
     {
         if (!FruitForLevel.TryGetValue(gameState.Level, out var fruitType))
         {
             fruitType = FruitType.Key;
         }
         gameState.ShowFruit(settings.FruitVisibleForSeconds, fruitType);
     }
     gameNotifications.Publish(GameNotification.EatCoin);
 }
Example #8
0
 public static void BeginRespawning(GameNotifications gameNotifications)
 {
     gameNotifications.Publish(GameNotification.Respawning);
 }
Example #9
0
 public static void BeginDying(GameState gameState, GameNotifications gameNotifications)
 {
     gameState.HideGhosts();
     gameNotifications.Publish(GameNotification.Dying);
 }
Example #10
0
        internal static void FruitEaten(Game game, IGameSettings settings, GameState gameState, CellLocation location, GameNotifications gameNotifications)
        {
            var scoreInc = gameState.FruitTypeToShow switch {
                FruitType.Cherry => 100,
                FruitType.Strawberry => 300,
                FruitType.Orange => 500,
                FruitType.Bell => 700,
                FruitType.Apple => 1000,
                FruitType.Grapes => 2000,
                FruitType.Arcadian => 3000,
                FruitType.Key => 5000,
                _ => throw new NotImplementedException()
            };

            gameState.IncreaseScore(scoreInc);
            gameState.HideFruit();
            gameNotifications.Publish(GameNotification.EatFruit);
        }
Example #11
0
 public static void Tick(GameState gameState, DateTime now, GameNotifications gameNotifications)
 {
     gameNotifications.Publish(GameNotification.PreTick);
     gameState.RecordLastTick(now);
 }