using Minesweeper.Config; using UnityEngine; namespace Minesweeper.Core { public sealed class GameSettingsService : IGameSettingsService { private const int MinimumMinesCount = 1; private readonly MinesweeperGameConfig config; private readonly IGameSettingsStorage storage; private GameSettingsValue current; public GameSettingsService(MinesweeperGameConfig config, IGameSettingsStorage storage) { this.config = config; this.storage = storage; current = LoadInitialSettings(); } public int SizeX => current.SizeX; public int SizeY => current.SizeY; public int MinesCount => current.MinesCount; public GameSettingsValue Current => current; public GameSettingsValue Clamp(GameSettingsValue value) { var sizeX = Mathf.Clamp(value.SizeX, config.MinSizeX, config.MaxSizeX); var sizeY = Mathf.Clamp(value.SizeY, config.MinSizeY, config.MaxSizeY); EnsureAtLeastTwoCells(ref sizeX, ref sizeY); var mines = Mathf.Clamp(value.MinesCount, MinimumMinesCount, GetMaxMines(sizeX, sizeY)); return new GameSettingsValue(sizeX, sizeY, mines); } public bool ApplyAndSaveIfChanged(GameSettingsValue value) { var clamped = Clamp(value); if (current.Equals(clamped)) { return false; } current = clamped; storage.Save(current); return true; } public int GetMaxMines(int sizeX, int sizeY) { return Mathf.Max(MinimumMinesCount, sizeX * sizeY - 1); } private GameSettingsValue LoadInitialSettings() { if (storage.TryLoad(out var saved)) { return Clamp(saved); } return Clamp(new GameSettingsValue(config.MinSizeX, config.MinSizeY, MinimumMinesCount)); } private void EnsureAtLeastTwoCells(ref int sizeX, ref int sizeY) { if (sizeX * sizeY > 1) { return; } if (sizeX < config.MaxSizeX) { sizeX++; } else if (sizeY < config.MaxSizeY) { sizeY++; } } } }