using Minesweeper.Core; using Minesweeper.ECS; namespace Minesweeper.Commands { public sealed class SelectFieldCommandHandler : IGameCommandHandler { private readonly IGameStateService gameStateService; public SelectFieldCommandHandler(IGameStateService gameStateService) { this.gameStateService = gameStateService; } public void Handle(SelectFieldCommand command) { gameStateService.SetState(GameState.FieldSelection); } } public sealed class StartGameCommandHandler : IGameCommandHandler { private readonly IBoardEcsSyncService boardEcsSyncService; private readonly IBoardService boardService; private readonly IGamePauseService pauseService; private readonly IGameStateService gameStateService; private readonly IGameTimerService timerService; public StartGameCommandHandler(IBoardService boardService, IBoardEcsSyncService boardEcsSyncService, IGamePauseService pauseService, IGameStateService gameStateService, IGameTimerService timerService) { this.boardService = boardService; this.boardEcsSyncService = boardEcsSyncService; this.pauseService = pauseService; this.gameStateService = gameStateService; this.timerService = timerService; } public void Handle(StartGameCommand command) { pauseService.Resume(); timerService.Reset(); boardService.InitializeEmptyBoard(); gameStateService.SetState(GameState.Preparing); boardEcsSyncService.SyncBoard(boardService); boardEcsSyncService.SyncGameState(gameStateService.Current, false); } } public sealed class OpenCellCommandHandler : IGameCommandHandler { private readonly IBoardEcsSyncService boardEcsSyncService; private readonly IBoardService boardService; private readonly IGameStateService gameStateService; private readonly IGamePauseService pauseService; public OpenCellCommandHandler(IBoardService boardService, IBoardEcsSyncService boardEcsSyncService, IGameStateService gameStateService, IGamePauseService pauseService) { this.boardService = boardService; this.boardEcsSyncService = boardEcsSyncService; this.gameStateService = gameStateService; this.pauseService = pauseService; } public void Handle(OpenCellCommand command) { if (pauseService.IsPaused) { return; } var state = gameStateService.Current; var generatedOnThisCommand = false; if (state != GameState.Preparing && state != GameState.Playing) { return; } if (state == GameState.Preparing) { if (boardService.TryGetCell(command.X, command.Y, out var cell) && cell.IsFlagged) { return; } if (!boardService.GenerateAfterFirstClick(command.X, command.Y)) { return; } generatedOnThisCommand = true; } var result = boardService.OpenCell(command.X, command.Y); if (result.Invalid || !result.Changed) { return; } if (result.HitMine) { gameStateService.SetState(GameState.Lost); } else if (result.Won) { gameStateService.SetState(GameState.Won); } else if (state == GameState.Preparing) { gameStateService.SetState(GameState.Playing); } if (generatedOnThisCommand) { boardEcsSyncService.SyncBoard(boardService); } else { boardEcsSyncService.SyncCells(result.ChangedCells, boardService); } boardEcsSyncService.SyncGameState(gameStateService.Current, boardService.IsGenerated); } } public sealed class ToggleFlagCommandHandler : IGameCommandHandler { private readonly IBoardEcsSyncService boardEcsSyncService; private readonly IBoardService boardService; private readonly IGameStateService gameStateService; private readonly IGamePauseService pauseService; public ToggleFlagCommandHandler(IBoardService boardService, IBoardEcsSyncService boardEcsSyncService, IGameStateService gameStateService, IGamePauseService pauseService) { this.boardService = boardService; this.boardEcsSyncService = boardEcsSyncService; this.gameStateService = gameStateService; this.pauseService = pauseService; } public void Handle(ToggleFlagCommand command) { if (pauseService.IsPaused) { return; } var state = gameStateService.Current; if (state != GameState.Preparing && state != GameState.Playing) { return; } var result = boardService.ToggleFlag(command.X, command.Y); if (result.Invalid || !result.Changed) { return; } boardEcsSyncService.SyncCells(result.ChangedCells, boardService); boardEcsSyncService.SyncGameState(gameStateService.Current, boardService.IsGenerated); } } public sealed class RestartCommandHandler : IGameCommandHandler { private readonly IBoardEcsSyncService boardEcsSyncService; private readonly IBoardService boardService; private readonly IGamePauseService pauseService; private readonly IGameStateService gameStateService; private readonly IGameTimerService timerService; public RestartCommandHandler(IBoardService boardService, IBoardEcsSyncService boardEcsSyncService, IGamePauseService pauseService, IGameStateService gameStateService, IGameTimerService timerService) { this.boardService = boardService; this.boardEcsSyncService = boardEcsSyncService; this.pauseService = pauseService; this.gameStateService = gameStateService; this.timerService = timerService; } public void Handle(RestartCommand command) { var shouldNotifyReset = gameStateService.Current == GameState.Preparing; pauseService.Resume(); timerService.Reset(); boardService.InitializeEmptyBoard(); gameStateService.SetState(GameState.Preparing); boardEcsSyncService.SyncBoard(boardService); boardEcsSyncService.SyncGameState(gameStateService.Current, false); if (shouldNotifyReset) { gameStateService.NotifyCurrentStateChanged(); } } } public sealed class PauseCommandHandler : IGameCommandHandler { private readonly IGamePauseService pauseService; private readonly IGameStateService gameStateService; public PauseCommandHandler(IGamePauseService pauseService, IGameStateService gameStateService) { this.pauseService = pauseService; this.gameStateService = gameStateService; } public void Handle(PauseCommand command) { var state = gameStateService.Current; if (state == GameState.Preparing || state == GameState.Playing) { pauseService.Pause(); } } } public sealed class ResumeCommandHandler : IGameCommandHandler { private readonly IGamePauseService pauseService; public ResumeCommandHandler(IGamePauseService pauseService) { this.pauseService = pauseService; } public void Handle(ResumeCommand command) { pauseService.Resume(); } } public sealed class GoToMenuCommandHandler : IGameCommandHandler { private readonly IBoardEcsSyncService boardEcsSyncService; private readonly IGamePauseService pauseService; private readonly IGameStateService gameStateService; private readonly IGameTimerService timerService; public GoToMenuCommandHandler(IBoardEcsSyncService boardEcsSyncService, IGamePauseService pauseService, IGameStateService gameStateService, IGameTimerService timerService) { this.boardEcsSyncService = boardEcsSyncService; this.pauseService = pauseService; this.gameStateService = gameStateService; this.timerService = timerService; } public void Handle(GoToMenuCommand command) { pauseService.Resume(); timerService.Reset(); gameStateService.SetState(GameState.FieldSelection); boardEcsSyncService.ClearBoard(); boardEcsSyncService.SyncGameState(gameStateService.Current, false); } } }