Files
2026-06-07 01:12:10 +07:00

210 lines
6.9 KiB
C#

using Minesweeper.Commands;
using Minesweeper.Core;
using Minesweeper.Presentation.Factories;
using Minesweeper.Presentation.ReadModels;
using Minesweeper.Presentation.Views;
namespace Minesweeper.Presentation.Presenters
{
public sealed class GamePresenter : IPresenter
{
private readonly IGameCommandDispatcher commandDispatcher;
private readonly ICellViewFactory cellViewFactory;
private readonly IGamePauseService pauseService;
private readonly IGameReadModel readModel;
private readonly IGameStateService gameStateService;
private readonly TopPanelPresenter topPanelPresenter;
private readonly IBoardView boardView;
private readonly IPauseView pauseView;
private readonly IResultView resultView;
private bool boardBuilt;
public GamePresenter(IGameCommandDispatcher commandDispatcher, ICellViewFactory cellViewFactory, IGamePauseService pauseService, IGameReadModel readModel, IGameStateService gameStateService, TopPanelPresenter topPanelPresenter, IBoardView boardView, IPauseView pauseView, IResultView resultView)
{
this.commandDispatcher = commandDispatcher;
this.cellViewFactory = cellViewFactory;
this.pauseService = pauseService;
this.readModel = readModel;
this.gameStateService = gameStateService;
this.topPanelPresenter = topPanelPresenter;
this.boardView = boardView;
this.pauseView = pauseView;
this.resultView = resultView;
}
public void Initialize()
{
boardView.CellPressStarted += OnCellPressStarted;
boardView.CellPressEnded += OnCellPressEnded;
boardView.PauseRequested += OnPauseRequested;
boardView.CellOpenRequested += OnCellOpenRequested;
boardView.CellFlagRequested += OnCellFlagRequested;
pauseView.RestartRequested += OnRestartRequested;
pauseView.ResumeRequested += OnResumeRequested;
pauseView.GoToMenuRequested += OnGoToMenuRequested;
resultView.RestartRequested += OnRestartRequested;
resultView.GoToMenuRequested += OnGoToMenuRequested;
gameStateService.StateChanged += OnStateChanged;
pauseService.PauseChanged += OnPauseChanged;
OnStateChanged(gameStateService.Current);
OnPauseChanged(pauseService.IsPaused);
}
public void Dispose()
{
boardView.CellPressStarted -= OnCellPressStarted;
boardView.CellPressEnded -= OnCellPressEnded;
boardView.PauseRequested -= OnPauseRequested;
boardView.CellOpenRequested -= OnCellOpenRequested;
boardView.CellFlagRequested -= OnCellFlagRequested;
pauseView.RestartRequested -= OnRestartRequested;
pauseView.ResumeRequested -= OnResumeRequested;
pauseView.GoToMenuRequested -= OnGoToMenuRequested;
resultView.RestartRequested -= OnRestartRequested;
resultView.GoToMenuRequested -= OnGoToMenuRequested;
gameStateService.StateChanged -= OnStateChanged;
pauseService.PauseChanged -= OnPauseChanged;
}
private void OnCellOpenRequested(int x, int y)
{
topPanelPresenter.SetCellPressActive(false);
commandDispatcher.Dispatch(new OpenCellCommand(x, y));
RefreshChangedCellsOrBoard();
topPanelPresenter.RefreshCounters();
UpdateBoardInput();
}
private void OnCellFlagRequested(int x, int y)
{
commandDispatcher.Dispatch(new ToggleFlagCommand(x, y));
RefreshChangedCellsOrBoard();
topPanelPresenter.RefreshCounters();
UpdateBoardInput();
}
private void OnCellPressStarted()
{
topPanelPresenter.SetCellPressActive(true);
}
private void OnCellPressEnded()
{
topPanelPresenter.SetCellPressActive(false);
}
private void OnStateChanged(GameState state)
{
if (state == GameState.FieldSelection)
{
boardBuilt = false;
boardView.Hide();
pauseView.Hide();
resultView.Hide();
return;
}
boardView.Show();
if (state == GameState.Won || state == GameState.Lost)
{
pauseView.Hide();
resultView.Show(state);
}
else
{
resultView.Hide();
}
if (!boardBuilt || state == GameState.Preparing)
{
RebuildBoard();
}
else
{
RefreshBoard();
}
UpdateBoardInput();
}
private void OnPauseChanged(bool isPaused)
{
if (isPaused && CanPause(gameStateService.Current))
{
pauseView.Show();
}
else
{
pauseView.Hide();
}
UpdateBoardInput();
}
private void RebuildBoard()
{
var cells = readModel.GetCells();
boardView.Rebuild(cells, readModel.Width, readModel.Height, cellViewFactory, IsFinalState());
boardBuilt = true;
topPanelPresenter.RefreshCounters();
UpdateBoardInput();
}
private void RefreshBoard()
{
boardView.Refresh(readModel.GetCells(), IsFinalState());
}
private void RefreshChangedCellsOrBoard()
{
if (IsFinalState())
{
RefreshBoard();
return;
}
boardView.RefreshCells(readModel.GetChangedCells(), false);
}
private bool IsFinalState()
{
var state = gameStateService.Current;
return state == GameState.Lost || state == GameState.Won;
}
private void UpdateBoardInput()
{
var state = gameStateService.Current;
boardView.SetInputEnabled(!pauseService.IsPaused && (state == GameState.Preparing || state == GameState.Playing));
}
private void OnRestartRequested()
{
commandDispatcher.Dispatch(new RestartCommand());
RebuildBoard();
topPanelPresenter.RefreshCounters();
}
private void OnGoToMenuRequested()
{
commandDispatcher.Dispatch(new GoToMenuCommand());
}
private void OnResumeRequested()
{
commandDispatcher.Dispatch(new ResumeCommand());
}
private void OnPauseRequested()
{
commandDispatcher.Dispatch(new PauseCommand());
}
private static bool CanPause(GameState state)
{
return state == GameState.Preparing || state == GameState.Playing;
}
}
}