From a9767c530115905dca16264296de56d24cda6a50 Mon Sep 17 00:00:00 2001 From: Konstantin Dyachenko Date: Sat, 6 Jun 2026 23:48:55 +0700 Subject: [PATCH] [Add] Menu with configs and size fix --- Assets/Config/MinesweeperGameConfig.asset | 8 +- Assets/Prefabs/Cells/ButtonMine.prefab | 12 +-- Assets/Prefabs/Screens/MainMenuPanel.prefab | 60 ++++++++----- .../Runtime/Config/MinesweeperGameConfig.cs | 10 +-- Assets/Runtime/Core/BoardService.cs | 33 ++----- Assets/Runtime/Core/GameSettingsService.cs | 81 +++++++++++++++++ .../Runtime/Core/GameSettingsService.cs.meta | 2 + Assets/Runtime/Core/GameSettingsValue.cs | 21 +++++ Assets/Runtime/Core/GameSettingsValue.cs.meta | 2 + Assets/Runtime/Core/IGameSettingsService.cs | 14 +++ .../Runtime/Core/IGameSettingsService.cs.meta | 2 + Assets/Runtime/Core/IGameSettingsStorage.cs | 8 ++ .../Runtime/Core/IGameSettingsStorage.cs.meta | 2 + .../MinesweeperLifetimeScope.cs | 3 +- .../PlayerPrefsGameSettingsStorage.cs | 32 +++++++ .../PlayerPrefsGameSettingsStorage.cs.meta | 2 + .../Infrastructure/RestartKeyInputService.cs | 50 ----------- .../RestartKeyInputService.cs.meta | 11 --- .../Presentation/Factories/CellViewFactory.cs | 4 +- .../MinesweeperScreenBootstrapper.cs | 3 +- .../Presenters/MainMenuPresenter.cs | 27 +++++- .../Presentation/ReadModels/GameReadModel.cs | 13 ++- Assets/Runtime/Presentation/Views/CellView.cs | 22 ++++- Assets/Runtime/Presentation/Views/GameView.cs | 15 +++- .../Presentation/Views/IMainMenuView.cs | 7 ++ .../Presentation/Views/MainMenuView.cs | 50 ++++++++--- .../Presentation/Views/MenuSliderView.cs | 89 +++++++++++++++++++ .../Presentation/Views/MenuSliderView.cs.meta | 2 + .../Presentation/Views/NullMainMenuView.cs | 21 +++++ 29 files changed, 453 insertions(+), 153 deletions(-) create mode 100644 Assets/Runtime/Core/GameSettingsService.cs create mode 100644 Assets/Runtime/Core/GameSettingsService.cs.meta create mode 100644 Assets/Runtime/Core/GameSettingsValue.cs create mode 100644 Assets/Runtime/Core/GameSettingsValue.cs.meta create mode 100644 Assets/Runtime/Core/IGameSettingsService.cs create mode 100644 Assets/Runtime/Core/IGameSettingsService.cs.meta create mode 100644 Assets/Runtime/Core/IGameSettingsStorage.cs create mode 100644 Assets/Runtime/Core/IGameSettingsStorage.cs.meta create mode 100644 Assets/Runtime/Infrastructure/PlayerPrefsGameSettingsStorage.cs create mode 100644 Assets/Runtime/Infrastructure/PlayerPrefsGameSettingsStorage.cs.meta delete mode 100644 Assets/Runtime/Infrastructure/RestartKeyInputService.cs delete mode 100644 Assets/Runtime/Infrastructure/RestartKeyInputService.cs.meta create mode 100644 Assets/Runtime/Presentation/Views/MenuSliderView.cs create mode 100644 Assets/Runtime/Presentation/Views/MenuSliderView.cs.meta diff --git a/Assets/Config/MinesweeperGameConfig.asset b/Assets/Config/MinesweeperGameConfig.asset index 908453a..4293807 100644 --- a/Assets/Config/MinesweeperGameConfig.asset +++ b/Assets/Config/MinesweeperGameConfig.asset @@ -12,7 +12,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: b4e8d5c36f36bb443b640a85df3e7077, type: 3} m_Name: MinesweeperGameConfig m_EditorClassIdentifier: Assembly-CSharp::Minesweeper.Config.MinesweeperGameConfig - k__BackingField: 9 - k__BackingField: 9 - k__BackingField: 1 - k__BackingField: 114 + k__BackingField: 2 + k__BackingField: 50 + k__BackingField: 2 + k__BackingField: 50 diff --git a/Assets/Prefabs/Cells/ButtonMine.prefab b/Assets/Prefabs/Cells/ButtonMine.prefab index 3abf9ed..30f8400 100644 --- a/Assets/Prefabs/Cells/ButtonMine.prefab +++ b/Assets/Prefabs/Cells/ButtonMine.prefab @@ -35,7 +35,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: -15, y: -15} + m_SizeDelta: {x: -8, y: -8} m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &3798432596530835849 GameObject: @@ -162,7 +162,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 30, y: 30} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &4574882275002937660 CanvasRenderer: @@ -219,12 +219,12 @@ MonoBehaviour: m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_fontSize: 54.6 + m_fontSize: 35.8 m_fontSizeBase: 15 m_fontWeight: 400 m_enableAutoSizing: 1 - m_fontSizeMin: 18 - m_fontSizeMax: 72 + m_fontSizeMin: 1 + m_fontSizeMax: 300 m_fontStyle: 0 m_HorizontalAlignment: 2 m_VerticalAlignment: 512 @@ -258,7 +258,7 @@ MonoBehaviour: m_VertexBufferAutoSizeReduction: 0 m_useMaxVisibleDescender: 1 m_pageToDisplay: 1 - m_margin: {x: 2, y: 2, z: 2, w: 2} + m_margin: {x: 1, y: 1, z: 1, w: 1} m_isUsingLegacyAnimationComponent: 0 m_isVolumetricText: 0 m_hasFontAssetChanged: 0 diff --git a/Assets/Prefabs/Screens/MainMenuPanel.prefab b/Assets/Prefabs/Screens/MainMenuPanel.prefab index 5a0442f..ccce8f8 100644 --- a/Assets/Prefabs/Screens/MainMenuPanel.prefab +++ b/Assets/Prefabs/Screens/MainMenuPanel.prefab @@ -428,7 +428,7 @@ GameObject: - component: {fileID: 2154271443323945884} - component: {fileID: 6204093840248163070} m_Layer: 5 - m_Name: Text (Mine) (1) + m_Name: Text (Max) m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -722,10 +722,10 @@ RectTransform: m_Children: [] m_Father: {fileID: 6299792064077961574} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 250, y: 48} + m_SizeDelta: {x: 0, y: 48} m_Pivot: {x: 0.5, y: 0} --- !u!222 &7925194886356738603 CanvasRenderer: @@ -996,10 +996,10 @@ RectTransform: m_Children: [] m_Father: {fileID: 4947738170035721252} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 250, y: 48} + m_SizeDelta: {x: 0, y: 48} m_Pivot: {x: 0.5, y: 0} --- !u!222 &4764443876518541376 CanvasRenderer: @@ -1208,10 +1208,10 @@ RectTransform: m_Children: [] m_Father: {fileID: 8549637007489853463} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 250, y: 48} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 1} + m_SizeDelta: {x: 0, y: 48} m_Pivot: {x: 0.5, y: 0} --- !u!222 &929277193634291900 CanvasRenderer: @@ -1421,8 +1421,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -391, y: -192} - m_SizeDelta: {x: -20, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &3877081085258266573 GameObject: @@ -1609,7 +1609,7 @@ GameObject: - component: {fileID: 7567565223110830849} - component: {fileID: 3264166992253475585} m_Layer: 5 - m_Name: Text (Mine) + m_Name: Text (Min) m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -2028,8 +2028,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -391, y: -192} - m_SizeDelta: {x: -20, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &6455657920195163342 GameObject: @@ -2068,7 +2068,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 0, y: -21} - m_SizeDelta: {x: -120, y: -162} + m_SizeDelta: {x: -150, y: -162} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &6446935312079034905 MonoBehaviour: @@ -2420,8 +2420,8 @@ MonoBehaviour: m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_fontSize: 57 - m_fontSizeBase: 57 + m_fontSize: 54 + m_fontSizeBase: 54 m_fontWeight: 400 m_enableAutoSizing: 0 m_fontSizeMin: 18 @@ -2664,6 +2664,24 @@ MonoBehaviour: m_EditorClassIdentifier: Assembly-CSharp::Minesweeper.Presentation.Views.MainMenuView root: {fileID: 7682962739562644362} startButton: {fileID: 3904309382312306706} + sizeXSlider: + slider: {fileID: 2334871180416613717} + minText: {fileID: 4504773017523582976} + maxText: {fileID: 6866883084726833735} + valueText: {fileID: 4474316482196456833} + valueLabel: 'Size X:' + sizeYSlider: + slider: {fileID: 4051923562216906313} + minText: {fileID: 1453579952739003993} + maxText: {fileID: 8013579874201281113} + valueText: {fileID: 8926983590126121119} + valueLabel: 'Size Y:' + minesSlider: + slider: {fileID: 6456819381917595383} + minText: {fileID: 3264166992253475585} + maxText: {fileID: 6204093840248163070} + valueText: {fileID: 7868341748139096968} + valueLabel: 'Mines count:' --- !u!1 &7723311763242053893 GameObject: m_ObjectHideFlags: 0 @@ -2847,8 +2865,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -391, y: -192} - m_SizeDelta: {x: -20, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &8648434963355287167 GameObject: diff --git a/Assets/Runtime/Config/MinesweeperGameConfig.cs b/Assets/Runtime/Config/MinesweeperGameConfig.cs index ae0de2d..378eb71 100644 --- a/Assets/Runtime/Config/MinesweeperGameConfig.cs +++ b/Assets/Runtime/Config/MinesweeperGameConfig.cs @@ -5,11 +5,11 @@ namespace Minesweeper.Config [CreateAssetMenu(fileName = "MinesweeperGameConfig", menuName = "Minesweeper/Game Config")] public sealed class MinesweeperGameConfig : ScriptableObject { - [field: SerializeField, Min(1)] public int Width { get; private set; } = 9; - [field: SerializeField, Min(1)] public int Height { get; private set; } = 9; - [field: SerializeField, Min(1)] public int MinesCount { get; private set; } = 10; - [field: SerializeField] public KeyCode RestartKey { get; private set; } = KeyCode.R; + [field: SerializeField, Min(1)] public int MinSizeX { get; private set; } = 2; + [field: SerializeField, Min(1)] public int MaxSizeX { get; private set; } = 50; + [field: SerializeField, Min(1)] public int MinSizeY { get; private set; } = 2; + [field: SerializeField, Min(1)] public int MaxSizeY { get; private set; } = 50; - public bool IsValid => Width > 0 && Height > 0 && MinesCount > 0 && MinesCount < Width * Height; + public bool IsValid => MinSizeX > 0 && MinSizeY > 0 && MaxSizeX >= MinSizeX && MaxSizeY >= MinSizeY && MaxSizeX * MaxSizeY > 1; } } diff --git a/Assets/Runtime/Core/BoardService.cs b/Assets/Runtime/Core/BoardService.cs index a2e8ba2..24e7fc6 100644 --- a/Assets/Runtime/Core/BoardService.cs +++ b/Assets/Runtime/Core/BoardService.cs @@ -1,22 +1,17 @@ using System; using System.Collections.Generic; -using Minesweeper.Config; namespace Minesweeper.Core { public sealed class BoardService : IBoardService { - private const int DefaultWidth = 9; - private const int DefaultHeight = 9; - private const int DefaultMinesCount = 10; - - private readonly MinesweeperGameConfig config; + private readonly IGameSettingsService settingsService; private readonly Random random = new Random(); private CellData[,] cells; - public BoardService(MinesweeperGameConfig config) + public BoardService(IGameSettingsService settingsService) { - this.config = config; + this.settingsService = settingsService; } public int Width { get; private set; } @@ -28,11 +23,9 @@ namespace Minesweeper.Core public void InitializeEmptyBoard() { - ResolveConfig(out var width, out var height, out var minesCount); - - Width = width; - Height = height; - MinesCount = minesCount; + Width = settingsService.SizeX; + Height = settingsService.SizeY; + MinesCount = Math.Min(settingsService.MinesCount, Width * Height - 1); OpenedSafeCellsCount = 0; IsGenerated = false; cells = new CellData[Width, Height]; @@ -147,20 +140,6 @@ namespace Minesweeper.Core return result; } - private void ResolveConfig(out int width, out int height, out int minesCount) - { - width = config.Width; - height = config.Height; - minesCount = config.MinesCount; - - if (width <= 0 || height <= 0 || minesCount <= 0 || minesCount >= width * height) - { - width = DefaultWidth; - height = DefaultHeight; - minesCount = DefaultMinesCount; - } - } - private void EnsureInitialized() { if (cells == null) diff --git a/Assets/Runtime/Core/GameSettingsService.cs b/Assets/Runtime/Core/GameSettingsService.cs new file mode 100644 index 0000000..bcb406c --- /dev/null +++ b/Assets/Runtime/Core/GameSettingsService.cs @@ -0,0 +1,81 @@ +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++; + } + } + } +} diff --git a/Assets/Runtime/Core/GameSettingsService.cs.meta b/Assets/Runtime/Core/GameSettingsService.cs.meta new file mode 100644 index 0000000..183647f --- /dev/null +++ b/Assets/Runtime/Core/GameSettingsService.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 38b7be3d055b5c34bbba9b36c0e11fc6 \ No newline at end of file diff --git a/Assets/Runtime/Core/GameSettingsValue.cs b/Assets/Runtime/Core/GameSettingsValue.cs new file mode 100644 index 0000000..a1dbc16 --- /dev/null +++ b/Assets/Runtime/Core/GameSettingsValue.cs @@ -0,0 +1,21 @@ +namespace Minesweeper.Core +{ + public readonly struct GameSettingsValue + { + public GameSettingsValue(int sizeX, int sizeY, int minesCount) + { + SizeX = sizeX; + SizeY = sizeY; + MinesCount = minesCount; + } + + public int SizeX { get; } + public int SizeY { get; } + public int MinesCount { get; } + + public bool Equals(GameSettingsValue other) + { + return SizeX == other.SizeX && SizeY == other.SizeY && MinesCount == other.MinesCount; + } + } +} diff --git a/Assets/Runtime/Core/GameSettingsValue.cs.meta b/Assets/Runtime/Core/GameSettingsValue.cs.meta new file mode 100644 index 0000000..57cf453 --- /dev/null +++ b/Assets/Runtime/Core/GameSettingsValue.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5a48645a1753ceb4ba0401ec44d70070 \ No newline at end of file diff --git a/Assets/Runtime/Core/IGameSettingsService.cs b/Assets/Runtime/Core/IGameSettingsService.cs new file mode 100644 index 0000000..fd750e0 --- /dev/null +++ b/Assets/Runtime/Core/IGameSettingsService.cs @@ -0,0 +1,14 @@ +namespace Minesweeper.Core +{ + public interface IGameSettingsService + { + int SizeX { get; } + int SizeY { get; } + int MinesCount { get; } + GameSettingsValue Current { get; } + + GameSettingsValue Clamp(GameSettingsValue value); + bool ApplyAndSaveIfChanged(GameSettingsValue value); + int GetMaxMines(int sizeX, int sizeY); + } +} diff --git a/Assets/Runtime/Core/IGameSettingsService.cs.meta b/Assets/Runtime/Core/IGameSettingsService.cs.meta new file mode 100644 index 0000000..beaa1f6 --- /dev/null +++ b/Assets/Runtime/Core/IGameSettingsService.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 3dcff3a940f664b4b96722f28e46636d \ No newline at end of file diff --git a/Assets/Runtime/Core/IGameSettingsStorage.cs b/Assets/Runtime/Core/IGameSettingsStorage.cs new file mode 100644 index 0000000..a464040 --- /dev/null +++ b/Assets/Runtime/Core/IGameSettingsStorage.cs @@ -0,0 +1,8 @@ +namespace Minesweeper.Core +{ + public interface IGameSettingsStorage + { + bool TryLoad(out GameSettingsValue value); + void Save(GameSettingsValue value); + } +} diff --git a/Assets/Runtime/Core/IGameSettingsStorage.cs.meta b/Assets/Runtime/Core/IGameSettingsStorage.cs.meta new file mode 100644 index 0000000..2383d09 --- /dev/null +++ b/Assets/Runtime/Core/IGameSettingsStorage.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 54d04c5398018bc418e1a2528c559d0a \ No newline at end of file diff --git a/Assets/Runtime/Infrastructure/MinesweeperLifetimeScope.cs b/Assets/Runtime/Infrastructure/MinesweeperLifetimeScope.cs index 6128962..2a8c782 100644 --- a/Assets/Runtime/Infrastructure/MinesweeperLifetimeScope.cs +++ b/Assets/Runtime/Infrastructure/MinesweeperLifetimeScope.cs @@ -28,6 +28,8 @@ namespace Minesweeper.Infrastructure builder.RegisterInstance(GetConfig()); var resolvedUiConfig = GetUiConfig(); builder.RegisterInstance(resolvedUiConfig); + builder.Register(Lifetime.Singleton).As(); + builder.Register(Lifetime.Singleton).As(); builder.Register(Lifetime.Singleton).As(); builder.Register(Lifetime.Singleton).As(); builder.Register(Lifetime.Singleton).As(); @@ -86,7 +88,6 @@ namespace Minesweeper.Infrastructure builder.Register(Lifetime.Singleton); builder.Register(Lifetime.Singleton); builder.Register(Lifetime.Singleton).As(); - builder.Register(Lifetime.Singleton).As(); builder.Register(Lifetime.Singleton); builder.Register(Lifetime.Singleton); diff --git a/Assets/Runtime/Infrastructure/PlayerPrefsGameSettingsStorage.cs b/Assets/Runtime/Infrastructure/PlayerPrefsGameSettingsStorage.cs new file mode 100644 index 0000000..836bf1f --- /dev/null +++ b/Assets/Runtime/Infrastructure/PlayerPrefsGameSettingsStorage.cs @@ -0,0 +1,32 @@ +using Minesweeper.Core; +using UnityEngine; + +namespace Minesweeper.Infrastructure +{ + public sealed class PlayerPrefsGameSettingsStorage : IGameSettingsStorage + { + private const string SizeXKey = "Minesweeper.Settings.SizeX"; + private const string SizeYKey = "Minesweeper.Settings.SizeY"; + private const string MinesCountKey = "Minesweeper.Settings.MinesCount"; + + public bool TryLoad(out GameSettingsValue value) + { + if (!PlayerPrefs.HasKey(SizeXKey) || !PlayerPrefs.HasKey(SizeYKey) || !PlayerPrefs.HasKey(MinesCountKey)) + { + value = default; + return false; + } + + value = new GameSettingsValue(PlayerPrefs.GetInt(SizeXKey), PlayerPrefs.GetInt(SizeYKey), PlayerPrefs.GetInt(MinesCountKey)); + return true; + } + + public void Save(GameSettingsValue value) + { + PlayerPrefs.SetInt(SizeXKey, value.SizeX); + PlayerPrefs.SetInt(SizeYKey, value.SizeY); + PlayerPrefs.SetInt(MinesCountKey, value.MinesCount); + PlayerPrefs.Save(); + } + } +} diff --git a/Assets/Runtime/Infrastructure/PlayerPrefsGameSettingsStorage.cs.meta b/Assets/Runtime/Infrastructure/PlayerPrefsGameSettingsStorage.cs.meta new file mode 100644 index 0000000..45a7027 --- /dev/null +++ b/Assets/Runtime/Infrastructure/PlayerPrefsGameSettingsStorage.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a001fc2e924d95643a075190b6cadda1 \ No newline at end of file diff --git a/Assets/Runtime/Infrastructure/RestartKeyInputService.cs b/Assets/Runtime/Infrastructure/RestartKeyInputService.cs deleted file mode 100644 index 77d2514..0000000 --- a/Assets/Runtime/Infrastructure/RestartKeyInputService.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Minesweeper.Commands; -using Minesweeper.Config; -using Minesweeper.Core; -using UnityEngine.InputSystem; -using VContainer.Unity; - -namespace Minesweeper.Infrastructure -{ - public sealed class RestartKeyInputService : ITickable - { - private readonly IGameCommandDispatcher commandDispatcher; - private readonly MinesweeperGameConfig config; - private readonly IGameStateService gameStateService; - - public RestartKeyInputService(IGameCommandDispatcher commandDispatcher, MinesweeperGameConfig config, IGameStateService gameStateService) - { - this.commandDispatcher = commandDispatcher; - this.config = config; - this.gameStateService = gameStateService; - } - - public void Tick() - { - var keyboard = Keyboard.current; - if (keyboard == null || !IsRestartPressed(keyboard)) - { - return; - } - - if (gameStateService.Current == GameState.FieldSelection) - { - commandDispatcher.Dispatch(new StartGameCommand()); - } - else - { - commandDispatcher.Dispatch(new RestartCommand()); - } - } - - private bool IsRestartPressed(Keyboard keyboard) - { - if (config.RestartKey == UnityEngine.KeyCode.R) - { - return keyboard.rKey.wasPressedThisFrame; - } - - return false; - } - } -} diff --git a/Assets/Runtime/Infrastructure/RestartKeyInputService.cs.meta b/Assets/Runtime/Infrastructure/RestartKeyInputService.cs.meta deleted file mode 100644 index fcf2611..0000000 --- a/Assets/Runtime/Infrastructure/RestartKeyInputService.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c87c15d092dd420b85a09cc786496948 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Runtime/Presentation/Factories/CellViewFactory.cs b/Assets/Runtime/Presentation/Factories/CellViewFactory.cs index a88b81f..a9f2a2a 100644 --- a/Assets/Runtime/Presentation/Factories/CellViewFactory.cs +++ b/Assets/Runtime/Presentation/Factories/CellViewFactory.cs @@ -11,6 +11,7 @@ namespace Minesweeper.Presentation.Factories { private const string ContentImagePath = "Content/Image"; private const string ContentLabelPath = "Content/Text (TMP)"; + private const string ContentPath = "Content"; private readonly MinesweeperUiConfig uiConfig; @@ -33,9 +34,10 @@ namespace Minesweeper.Presentation.Factories var button = go.GetComponent