diff --git a/Assets/Minesweeper.meta b/Assets/Minesweeper.meta new file mode 100644 index 0000000..5e5120f --- /dev/null +++ b/Assets/Minesweeper.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 224675c5999574f4b8cc858e17e34eed +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Config.meta b/Assets/Minesweeper/Config.meta new file mode 100644 index 0000000..41c2781 --- /dev/null +++ b/Assets/Minesweeper/Config.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 167a3599d465fb2438304d672c850377 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Config/MinesweeperGameConfig.asset b/Assets/Minesweeper/Config/MinesweeperGameConfig.asset new file mode 100644 index 0000000..d41b3e9 --- /dev/null +++ b/Assets/Minesweeper/Config/MinesweeperGameConfig.asset @@ -0,0 +1,18 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b4e8d5c36f36bb443b640a85df3e7077, type: 3} + m_Name: MinesweeperGameConfig + m_EditorClassIdentifier: Assembly-CSharp::Minesweeper.Config.MinesweeperGameConfig + width: 9 + height: 9 + minesCount: 10 + restartKey: 114 diff --git a/Assets/Minesweeper/Config/MinesweeperGameConfig.asset.meta b/Assets/Minesweeper/Config/MinesweeperGameConfig.asset.meta new file mode 100644 index 0000000..fa94588 --- /dev/null +++ b/Assets/Minesweeper/Config/MinesweeperGameConfig.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4c24a7c2a548eff4fb21fa4a4bf3e741 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime.meta b/Assets/Minesweeper/Runtime.meta new file mode 100644 index 0000000..7bc17fa --- /dev/null +++ b/Assets/Minesweeper/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d7d59007b2f263148ae29878cc0dd0a5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Commands.meta b/Assets/Minesweeper/Runtime/Commands.meta new file mode 100644 index 0000000..c93ee6d --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a7c135ae68601e5439b15457e8027a3f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Commands/GameCommandDispatcher.cs b/Assets/Minesweeper/Runtime/Commands/GameCommandDispatcher.cs new file mode 100644 index 0000000..f450c21 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/GameCommandDispatcher.cs @@ -0,0 +1,69 @@ +using System; + +namespace Minesweeper.Commands +{ + public sealed class GameCommandDispatcher : IGameCommandDispatcher + { + private readonly SelectFieldCommandHandler selectFieldHandler; + private readonly StartGameCommandHandler startGameHandler; + private readonly OpenCellCommandHandler openCellHandler; + private readonly ToggleFlagCommandHandler toggleFlagHandler; + private readonly RestartCommandHandler restartHandler; + private readonly PauseCommandHandler pauseHandler; + private readonly ResumeCommandHandler resumeHandler; + private readonly GoToMenuCommandHandler goToMenuHandler; + + public GameCommandDispatcher( + SelectFieldCommandHandler selectFieldHandler, + StartGameCommandHandler startGameHandler, + OpenCellCommandHandler openCellHandler, + ToggleFlagCommandHandler toggleFlagHandler, + RestartCommandHandler restartHandler, + PauseCommandHandler pauseHandler, + ResumeCommandHandler resumeHandler, + GoToMenuCommandHandler goToMenuHandler) + { + this.selectFieldHandler = selectFieldHandler; + this.startGameHandler = startGameHandler; + this.openCellHandler = openCellHandler; + this.toggleFlagHandler = toggleFlagHandler; + this.restartHandler = restartHandler; + this.pauseHandler = pauseHandler; + this.resumeHandler = resumeHandler; + this.goToMenuHandler = goToMenuHandler; + } + + public void Dispatch(TCommand command) where TCommand : IGameCommand + { + switch (command) + { + case SelectFieldCommand selectFieldCommand: + selectFieldHandler.Handle(selectFieldCommand); + return; + case StartGameCommand startGameCommand: + startGameHandler.Handle(startGameCommand); + return; + case OpenCellCommand openCellCommand: + openCellHandler.Handle(openCellCommand); + return; + case ToggleFlagCommand toggleFlagCommand: + toggleFlagHandler.Handle(toggleFlagCommand); + return; + case RestartCommand restartCommand: + restartHandler.Handle(restartCommand); + return; + case PauseCommand pauseCommand: + pauseHandler.Handle(pauseCommand); + return; + case ResumeCommand resumeCommand: + resumeHandler.Handle(resumeCommand); + return; + case GoToMenuCommand goToMenuCommand: + goToMenuHandler.Handle(goToMenuCommand); + return; + default: + throw new InvalidOperationException($"No handler registered for command {typeof(TCommand).Name}."); + } + } + } +} diff --git a/Assets/Minesweeper/Runtime/Commands/GameCommandDispatcher.cs.meta b/Assets/Minesweeper/Runtime/Commands/GameCommandDispatcher.cs.meta new file mode 100644 index 0000000..33b654e --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/GameCommandDispatcher.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6383c559964ec3545a7cd911b90586ce \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Commands/GameCommandHandlers.cs b/Assets/Minesweeper/Runtime/Commands/GameCommandHandlers.cs new file mode 100644 index 0000000..8d72e33 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/GameCommandHandlers.cs @@ -0,0 +1,92 @@ +using Minesweeper.Core; + +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 IGameStateService gameStateService; + + public StartGameCommandHandler(IGameStateService gameStateService) + { + this.gameStateService = gameStateService; + } + + public void Handle(StartGameCommand command) + { + gameStateService.SetState(GameState.Preparing); + } + } + + public sealed class OpenCellCommandHandler : IGameCommandHandler + { + public void Handle(OpenCellCommand command) + { + } + } + + public sealed class ToggleFlagCommandHandler : IGameCommandHandler + { + public void Handle(ToggleFlagCommand command) + { + } + } + + public sealed class RestartCommandHandler : IGameCommandHandler + { + private readonly IGameStateService gameStateService; + + public RestartCommandHandler(IGameStateService gameStateService) + { + this.gameStateService = gameStateService; + } + + public void Handle(RestartCommand command) + { + gameStateService.SetState(GameState.Preparing); + } + } + + public sealed class PauseCommandHandler : IGameCommandHandler + { + public void Handle(PauseCommand command) + { + } + } + + public sealed class ResumeCommandHandler : IGameCommandHandler + { + public void Handle(ResumeCommand command) + { + } + } + + public sealed class GoToMenuCommandHandler : IGameCommandHandler + { + private readonly IGameStateService gameStateService; + + public GoToMenuCommandHandler(IGameStateService gameStateService) + { + this.gameStateService = gameStateService; + } + + public void Handle(GoToMenuCommand command) + { + gameStateService.SetState(GameState.FieldSelection); + } + } +} diff --git a/Assets/Minesweeper/Runtime/Commands/GameCommandHandlers.cs.meta b/Assets/Minesweeper/Runtime/Commands/GameCommandHandlers.cs.meta new file mode 100644 index 0000000..f661d60 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/GameCommandHandlers.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 31bfefc0901594043aae51cabba89234 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Commands/GameCommands.cs b/Assets/Minesweeper/Runtime/Commands/GameCommands.cs new file mode 100644 index 0000000..31e28fd --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/GameCommands.cs @@ -0,0 +1,60 @@ +namespace Minesweeper.Commands +{ + public readonly struct SelectFieldCommand : IGameCommand + { + public SelectFieldCommand(int width, int height, int minesCount) + { + Width = width; + Height = height; + MinesCount = minesCount; + } + + public int Width { get; } + public int Height { get; } + public int MinesCount { get; } + } + + public readonly struct StartGameCommand : IGameCommand + { + } + + public readonly struct OpenCellCommand : IGameCommand + { + public OpenCellCommand(int x, int y) + { + X = x; + Y = y; + } + + public int X { get; } + public int Y { get; } + } + + public readonly struct ToggleFlagCommand : IGameCommand + { + public ToggleFlagCommand(int x, int y) + { + X = x; + Y = y; + } + + public int X { get; } + public int Y { get; } + } + + public readonly struct RestartCommand : IGameCommand + { + } + + public readonly struct PauseCommand : IGameCommand + { + } + + public readonly struct ResumeCommand : IGameCommand + { + } + + public readonly struct GoToMenuCommand : IGameCommand + { + } +} diff --git a/Assets/Minesweeper/Runtime/Commands/GameCommands.cs.meta b/Assets/Minesweeper/Runtime/Commands/GameCommands.cs.meta new file mode 100644 index 0000000..c5fc9ea --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/GameCommands.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9bd93535958ca574999f8ec6de84baa3 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Commands/IGameCommand.cs b/Assets/Minesweeper/Runtime/Commands/IGameCommand.cs new file mode 100644 index 0000000..0cbcdde --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/IGameCommand.cs @@ -0,0 +1,6 @@ +namespace Minesweeper.Commands +{ + public interface IGameCommand + { + } +} diff --git a/Assets/Minesweeper/Runtime/Commands/IGameCommand.cs.meta b/Assets/Minesweeper/Runtime/Commands/IGameCommand.cs.meta new file mode 100644 index 0000000..c8872d6 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/IGameCommand.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 50cd27fcb4d423e43b2a56cc23badbfb \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Commands/IGameCommandDispatcher.cs b/Assets/Minesweeper/Runtime/Commands/IGameCommandDispatcher.cs new file mode 100644 index 0000000..d4feef0 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/IGameCommandDispatcher.cs @@ -0,0 +1,7 @@ +namespace Minesweeper.Commands +{ + public interface IGameCommandDispatcher + { + void Dispatch(TCommand command) where TCommand : IGameCommand; + } +} diff --git a/Assets/Minesweeper/Runtime/Commands/IGameCommandDispatcher.cs.meta b/Assets/Minesweeper/Runtime/Commands/IGameCommandDispatcher.cs.meta new file mode 100644 index 0000000..0f874b2 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/IGameCommandDispatcher.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f1c291311029640428d2ea8820fdfeaa \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Commands/IGameCommandHandler.cs b/Assets/Minesweeper/Runtime/Commands/IGameCommandHandler.cs new file mode 100644 index 0000000..20c9330 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/IGameCommandHandler.cs @@ -0,0 +1,7 @@ +namespace Minesweeper.Commands +{ + public interface IGameCommandHandler where TCommand : IGameCommand + { + void Handle(TCommand command); + } +} diff --git a/Assets/Minesweeper/Runtime/Commands/IGameCommandHandler.cs.meta b/Assets/Minesweeper/Runtime/Commands/IGameCommandHandler.cs.meta new file mode 100644 index 0000000..b1dbc3b --- /dev/null +++ b/Assets/Minesweeper/Runtime/Commands/IGameCommandHandler.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e7b5f5892af9c184ba720b2b3f352b32 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Config.meta b/Assets/Minesweeper/Runtime/Config.meta new file mode 100644 index 0000000..16d3f02 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Config.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a904ba5489d53724692eb73dd2a68f2e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Config/MinesweeperGameConfig.cs b/Assets/Minesweeper/Runtime/Config/MinesweeperGameConfig.cs new file mode 100644 index 0000000..9bd3550 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Config/MinesweeperGameConfig.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +namespace Minesweeper.Config +{ + [CreateAssetMenu(fileName = "MinesweeperGameConfig", menuName = "Minesweeper/Game Config")] + public sealed class MinesweeperGameConfig : ScriptableObject + { + [SerializeField, Min(1)] private int width = 9; + [SerializeField, Min(1)] private int height = 9; + [SerializeField, Min(1)] private int minesCount = 10; + [SerializeField] private KeyCode restartKey = KeyCode.R; + + public int Width => width; + public int Height => height; + public int MinesCount => minesCount; + public KeyCode RestartKey => restartKey; + + public bool IsValid => width > 0 && height > 0 && minesCount > 0 && minesCount < width * height; + } +} diff --git a/Assets/Minesweeper/Runtime/Config/MinesweeperGameConfig.cs.meta b/Assets/Minesweeper/Runtime/Config/MinesweeperGameConfig.cs.meta new file mode 100644 index 0000000..01f2f55 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Config/MinesweeperGameConfig.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b4e8d5c36f36bb443b640a85df3e7077 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Core.meta b/Assets/Minesweeper/Runtime/Core.meta new file mode 100644 index 0000000..5648129 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Core.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 391f2b5ec87a6634694fe2c31faee82e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Core/GameState.cs b/Assets/Minesweeper/Runtime/Core/GameState.cs new file mode 100644 index 0000000..d344d5f --- /dev/null +++ b/Assets/Minesweeper/Runtime/Core/GameState.cs @@ -0,0 +1,11 @@ +namespace Minesweeper.Core +{ + public enum GameState + { + FieldSelection, + Preparing, + Playing, + Lost, + Won + } +} diff --git a/Assets/Minesweeper/Runtime/Core/GameState.cs.meta b/Assets/Minesweeper/Runtime/Core/GameState.cs.meta new file mode 100644 index 0000000..1be91bd --- /dev/null +++ b/Assets/Minesweeper/Runtime/Core/GameState.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c06ebf54d6bacdf4888fabbf29bea1cd \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Core/GameStateService.cs b/Assets/Minesweeper/Runtime/Core/GameStateService.cs new file mode 100644 index 0000000..6b33236 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Core/GameStateService.cs @@ -0,0 +1,22 @@ +using System; + +namespace Minesweeper.Core +{ + public sealed class GameStateService : IGameStateService + { + public event Action StateChanged; + + public GameState Current { get; private set; } = GameState.FieldSelection; + + public void SetState(GameState state) + { + if (Current == state) + { + return; + } + + Current = state; + StateChanged?.Invoke(Current); + } + } +} diff --git a/Assets/Minesweeper/Runtime/Core/GameStateService.cs.meta b/Assets/Minesweeper/Runtime/Core/GameStateService.cs.meta new file mode 100644 index 0000000..a7f45a3 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Core/GameStateService.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: cf69805439993c14887ea7bb9b15bd02 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Core/IGameStateService.cs b/Assets/Minesweeper/Runtime/Core/IGameStateService.cs new file mode 100644 index 0000000..271a543 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Core/IGameStateService.cs @@ -0,0 +1,13 @@ +using System; + +namespace Minesweeper.Core +{ + public interface IGameStateService + { + event Action StateChanged; + + GameState Current { get; } + + void SetState(GameState state); + } +} diff --git a/Assets/Minesweeper/Runtime/Core/IGameStateService.cs.meta b/Assets/Minesweeper/Runtime/Core/IGameStateService.cs.meta new file mode 100644 index 0000000..b496329 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Core/IGameStateService.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7aea04a8c0e8d3a4e8d991a4348430db \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/ECS.meta b/Assets/Minesweeper/Runtime/ECS.meta new file mode 100644 index 0000000..8db5024 --- /dev/null +++ b/Assets/Minesweeper/Runtime/ECS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ebd50c14109e96541aa49542a07986aa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/ECS/Components.meta b/Assets/Minesweeper/Runtime/ECS/Components.meta new file mode 100644 index 0000000..5d0d4e1 --- /dev/null +++ b/Assets/Minesweeper/Runtime/ECS/Components.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2ebb3bd7d4baf544fadefb7718c935d2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/ECS/Components/BoardConfigComponent.cs b/Assets/Minesweeper/Runtime/ECS/Components/BoardConfigComponent.cs new file mode 100644 index 0000000..4cf36be --- /dev/null +++ b/Assets/Minesweeper/Runtime/ECS/Components/BoardConfigComponent.cs @@ -0,0 +1,11 @@ +using Unity.Entities; + +namespace Minesweeper.ECS.Components +{ + public struct BoardConfigComponent : IComponentData + { + public int Width; + public int Height; + public int MinesCount; + } +} diff --git a/Assets/Minesweeper/Runtime/ECS/Components/BoardConfigComponent.cs.meta b/Assets/Minesweeper/Runtime/ECS/Components/BoardConfigComponent.cs.meta new file mode 100644 index 0000000..a2abdb1 --- /dev/null +++ b/Assets/Minesweeper/Runtime/ECS/Components/BoardConfigComponent.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b0024f7b9432b3740bdb6ae9ab132529 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/ECS/Components/CellComponent.cs b/Assets/Minesweeper/Runtime/ECS/Components/CellComponent.cs new file mode 100644 index 0000000..f474513 --- /dev/null +++ b/Assets/Minesweeper/Runtime/ECS/Components/CellComponent.cs @@ -0,0 +1,14 @@ +using Unity.Entities; + +namespace Minesweeper.ECS.Components +{ + public struct CellComponent : IComponentData + { + public int X; + public int Y; + public byte IsMine; + public byte IsOpened; + public byte IsFlagged; + public int NeighborMines; + } +} diff --git a/Assets/Minesweeper/Runtime/ECS/Components/CellComponent.cs.meta b/Assets/Minesweeper/Runtime/ECS/Components/CellComponent.cs.meta new file mode 100644 index 0000000..5fa95af --- /dev/null +++ b/Assets/Minesweeper/Runtime/ECS/Components/CellComponent.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 50ce9bb3f8ca1c142a28adb88899afec \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/ECS/Components/GameStateComponent.cs b/Assets/Minesweeper/Runtime/ECS/Components/GameStateComponent.cs new file mode 100644 index 0000000..1583025 --- /dev/null +++ b/Assets/Minesweeper/Runtime/ECS/Components/GameStateComponent.cs @@ -0,0 +1,11 @@ +using Minesweeper.Core; +using Unity.Entities; + +namespace Minesweeper.ECS.Components +{ + public struct GameStateComponent : IComponentData + { + public GameState State; + public byte HasFirstClick; + } +} diff --git a/Assets/Minesweeper/Runtime/ECS/Components/GameStateComponent.cs.meta b/Assets/Minesweeper/Runtime/ECS/Components/GameStateComponent.cs.meta new file mode 100644 index 0000000..2ab883c --- /dev/null +++ b/Assets/Minesweeper/Runtime/ECS/Components/GameStateComponent.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a89195585a555b54e909b4f8797f20ed \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/ECS/Systems.meta b/Assets/Minesweeper/Runtime/ECS/Systems.meta new file mode 100644 index 0000000..38de214 --- /dev/null +++ b/Assets/Minesweeper/Runtime/ECS/Systems.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 210d08f5d5948674fa0df51ed6a785b0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Infrastructure.meta b/Assets/Minesweeper/Runtime/Infrastructure.meta new file mode 100644 index 0000000..3ebf851 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Infrastructure.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cbb80c6f3d55e8d418e4f3369b2e1623 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperEntryPoint.cs b/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperEntryPoint.cs new file mode 100644 index 0000000..1a3b71a --- /dev/null +++ b/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperEntryPoint.cs @@ -0,0 +1,30 @@ +using System; +using Minesweeper.Presentation.Presenters; +using VContainer.Unity; + +namespace Minesweeper.Infrastructure +{ + public sealed class MinesweeperEntryPoint : IStartable, IDisposable + { + private readonly MainMenuPresenter mainMenuPresenter; + private readonly GamePresenter gamePresenter; + + public MinesweeperEntryPoint(MainMenuPresenter mainMenuPresenter, GamePresenter gamePresenter) + { + this.mainMenuPresenter = mainMenuPresenter; + this.gamePresenter = gamePresenter; + } + + public void Start() + { + mainMenuPresenter.Initialize(); + gamePresenter.Initialize(); + } + + public void Dispose() + { + gamePresenter.Dispose(); + mainMenuPresenter.Dispose(); + } + } +} diff --git a/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperEntryPoint.cs.meta b/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperEntryPoint.cs.meta new file mode 100644 index 0000000..a6a15e1 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperEntryPoint.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5eae713b4d801be4996a70d4b630eeee \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperLifetimeScope.cs b/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperLifetimeScope.cs new file mode 100644 index 0000000..bf0c15e --- /dev/null +++ b/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperLifetimeScope.cs @@ -0,0 +1,54 @@ +using Minesweeper.Commands; +using Minesweeper.Config; +using Minesweeper.Core; +using Minesweeper.Presentation.Adapters; +using Minesweeper.Presentation.Factories; +using Minesweeper.Presentation.Presenters; +using Minesweeper.Presentation.ReadModels; +using Minesweeper.Presentation.Views; +using UnityEngine; +using VContainer; +using VContainer.Unity; + +namespace Minesweeper.Infrastructure +{ + public sealed class MinesweeperLifetimeScope : LifetimeScope + { + [SerializeField] private MinesweeperGameConfig gameConfig; + + protected override void Configure(IContainerBuilder builder) + { + builder.RegisterInstance(GetConfig()); + 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(); + builder.Register(Lifetime.Singleton).As(); + + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton).As(); + + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); + builder.RegisterEntryPoint(); + } + + private MinesweeperGameConfig GetConfig() + { + if (gameConfig != null) + { + return gameConfig; + } + + return ScriptableObject.CreateInstance(); + } + } +} diff --git a/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperLifetimeScope.cs.meta b/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperLifetimeScope.cs.meta new file mode 100644 index 0000000..779a4c4 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Infrastructure/MinesweeperLifetimeScope.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d4f9b0c2ad803d84382fbf03ba3096fa \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation.meta b/Assets/Minesweeper/Runtime/Presentation.meta new file mode 100644 index 0000000..7750620 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b1435ba5f7e9b514cb863ee06385cb77 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Presentation/Adapters.meta b/Assets/Minesweeper/Runtime/Presentation/Adapters.meta new file mode 100644 index 0000000..f6b902c --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Adapters.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 648cba2aa826df04aa6de2236d532ff7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Presentation/Adapters/GameStateViewAdapter.cs b/Assets/Minesweeper/Runtime/Presentation/Adapters/GameStateViewAdapter.cs new file mode 100644 index 0000000..c6470db --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Adapters/GameStateViewAdapter.cs @@ -0,0 +1,12 @@ +using Minesweeper.Core; + +namespace Minesweeper.Presentation.Adapters +{ + public sealed class GameStateViewAdapter : IGameStateViewAdapter + { + public string GetDisplayName(GameState state) + { + return state.ToString(); + } + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Adapters/GameStateViewAdapter.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Adapters/GameStateViewAdapter.cs.meta new file mode 100644 index 0000000..f081f66 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Adapters/GameStateViewAdapter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a10e635e4da16d24db457ead4d139896 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Adapters/IGameStateViewAdapter.cs b/Assets/Minesweeper/Runtime/Presentation/Adapters/IGameStateViewAdapter.cs new file mode 100644 index 0000000..c239985 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Adapters/IGameStateViewAdapter.cs @@ -0,0 +1,9 @@ +using Minesweeper.Core; + +namespace Minesweeper.Presentation.Adapters +{ + public interface IGameStateViewAdapter + { + string GetDisplayName(GameState state); + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Adapters/IGameStateViewAdapter.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Adapters/IGameStateViewAdapter.cs.meta new file mode 100644 index 0000000..08d245d --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Adapters/IGameStateViewAdapter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 058bab5bc0f87f64dbbf668e5e390216 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Factories.meta b/Assets/Minesweeper/Runtime/Presentation/Factories.meta new file mode 100644 index 0000000..dcac561 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Factories.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec6192ca6506ac64c8aa089466c86db5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Presentation/Factories/CellViewFactory.cs b/Assets/Minesweeper/Runtime/Presentation/Factories/CellViewFactory.cs new file mode 100644 index 0000000..ef0407d --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Factories/CellViewFactory.cs @@ -0,0 +1,10 @@ +namespace Minesweeper.Presentation.Factories +{ + public sealed class CellViewFactory : ICellViewFactory + { + public string BuildCellName(int x, int y, int value, bool isMine) + { + return $"bt_{x}_{y}_{(isMine ? "M" : value.ToString())}"; + } + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Factories/CellViewFactory.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Factories/CellViewFactory.cs.meta new file mode 100644 index 0000000..3a8054d --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Factories/CellViewFactory.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 681a16a970ddf3546bb4f99d93a184ca \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Factories/ICellViewFactory.cs b/Assets/Minesweeper/Runtime/Presentation/Factories/ICellViewFactory.cs new file mode 100644 index 0000000..09d51e7 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Factories/ICellViewFactory.cs @@ -0,0 +1,7 @@ +namespace Minesweeper.Presentation.Factories +{ + public interface ICellViewFactory + { + string BuildCellName(int x, int y, int value, bool isMine); + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Factories/ICellViewFactory.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Factories/ICellViewFactory.cs.meta new file mode 100644 index 0000000..3a86e57 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Factories/ICellViewFactory.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 34c31a0f01c730440a2bcdac0f775dd8 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Presenters.meta b/Assets/Minesweeper/Runtime/Presentation/Presenters.meta new file mode 100644 index 0000000..299fd1b --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Presenters.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3895ae14930e10841a7562a478c871ec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Presentation/Presenters/GamePresenter.cs b/Assets/Minesweeper/Runtime/Presentation/Presenters/GamePresenter.cs new file mode 100644 index 0000000..2bcca81 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Presenters/GamePresenter.cs @@ -0,0 +1,50 @@ +using Minesweeper.Commands; +using Minesweeper.Presentation.ReadModels; +using Minesweeper.Presentation.Views; + +namespace Minesweeper.Presentation.Presenters +{ + public sealed class GamePresenter : IPresenter + { + private readonly IGameCommandDispatcher commandDispatcher; + private readonly IGameReadModel readModel; + private readonly IGameView view; + + public GamePresenter(IGameCommandDispatcher commandDispatcher, IGameReadModel readModel, IGameView view = null) + { + this.commandDispatcher = commandDispatcher; + this.readModel = readModel; + this.view = view; + } + + public void Initialize() + { + _ = readModel.State; + + if (view != null) + { + view.RestartRequested += OnRestartRequested; + view.GoToMenuRequested += OnGoToMenuRequested; + } + } + + public void Dispose() + { + if (view != null) + { + view.RestartRequested -= OnRestartRequested; + view.GoToMenuRequested -= OnGoToMenuRequested; + } + } + + private void OnRestartRequested() + { + commandDispatcher.Dispatch(new RestartCommand()); + } + + private void OnGoToMenuRequested() + { + commandDispatcher.Dispatch(new GoToMenuCommand()); + } + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Presenters/GamePresenter.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Presenters/GamePresenter.cs.meta new file mode 100644 index 0000000..26bad04 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Presenters/GamePresenter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9f85646fc4851054e9efffa3ab1f6853 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Presenters/IPresenter.cs b/Assets/Minesweeper/Runtime/Presentation/Presenters/IPresenter.cs new file mode 100644 index 0000000..f592d29 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Presenters/IPresenter.cs @@ -0,0 +1,9 @@ +using System; + +namespace Minesweeper.Presentation.Presenters +{ + public interface IPresenter : IDisposable + { + void Initialize(); + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Presenters/IPresenter.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Presenters/IPresenter.cs.meta new file mode 100644 index 0000000..48eecd8 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Presenters/IPresenter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e0fcee9aa500b62429eb4ffa2249de9c \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Presenters/MainMenuPresenter.cs b/Assets/Minesweeper/Runtime/Presentation/Presenters/MainMenuPresenter.cs new file mode 100644 index 0000000..8ad2255 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Presenters/MainMenuPresenter.cs @@ -0,0 +1,38 @@ +using Minesweeper.Commands; +using Minesweeper.Presentation.Views; + +namespace Minesweeper.Presentation.Presenters +{ + public sealed class MainMenuPresenter : IPresenter + { + private readonly IGameCommandDispatcher commandDispatcher; + private readonly IMainMenuView view; + + public MainMenuPresenter(IGameCommandDispatcher commandDispatcher, IMainMenuView view = null) + { + this.commandDispatcher = commandDispatcher; + this.view = view; + } + + public void Initialize() + { + if (view != null) + { + view.StartClicked += OnStartClicked; + } + } + + public void Dispose() + { + if (view != null) + { + view.StartClicked -= OnStartClicked; + } + } + + private void OnStartClicked() + { + commandDispatcher.Dispatch(new StartGameCommand()); + } + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Presenters/MainMenuPresenter.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Presenters/MainMenuPresenter.cs.meta new file mode 100644 index 0000000..348d432 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Presenters/MainMenuPresenter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 835a3b63609e9864fa6154be8b8283ad \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/ReadModels.meta b/Assets/Minesweeper/Runtime/Presentation/ReadModels.meta new file mode 100644 index 0000000..5f26fc0 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/ReadModels.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 590e96d08af41e346b49a7ce43641afb +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Presentation/ReadModels/GameReadModel.cs b/Assets/Minesweeper/Runtime/Presentation/ReadModels/GameReadModel.cs new file mode 100644 index 0000000..452fc2f --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/ReadModels/GameReadModel.cs @@ -0,0 +1,22 @@ +using Minesweeper.Config; +using Minesweeper.Core; + +namespace Minesweeper.Presentation.ReadModels +{ + public sealed class GameReadModel : IGameReadModel + { + private readonly MinesweeperGameConfig config; + private readonly IGameStateService gameStateService; + + public GameReadModel(MinesweeperGameConfig config, IGameStateService gameStateService) + { + this.config = config; + this.gameStateService = gameStateService; + } + + public GameState State => gameStateService.Current; + public int Width => config.Width; + public int Height => config.Height; + public int MinesCount => config.MinesCount; + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/ReadModels/GameReadModel.cs.meta b/Assets/Minesweeper/Runtime/Presentation/ReadModels/GameReadModel.cs.meta new file mode 100644 index 0000000..7dc6e3e --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/ReadModels/GameReadModel.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1b2a816449e034a4f9635960881ec852 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/ReadModels/IGameReadModel.cs b/Assets/Minesweeper/Runtime/Presentation/ReadModels/IGameReadModel.cs new file mode 100644 index 0000000..28351d4 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/ReadModels/IGameReadModel.cs @@ -0,0 +1,12 @@ +using Minesweeper.Core; + +namespace Minesweeper.Presentation.ReadModels +{ + public interface IGameReadModel + { + GameState State { get; } + int Width { get; } + int Height { get; } + int MinesCount { get; } + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/ReadModels/IGameReadModel.cs.meta b/Assets/Minesweeper/Runtime/Presentation/ReadModels/IGameReadModel.cs.meta new file mode 100644 index 0000000..483c709 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/ReadModels/IGameReadModel.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e5c921f20dd6f1b40a1f73746265a63d \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Views.meta b/Assets/Minesweeper/Runtime/Presentation/Views.meta new file mode 100644 index 0000000..57b9752 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0e2357d56da983b478c1cebe1e3ac363 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/IGameView.cs b/Assets/Minesweeper/Runtime/Presentation/Views/IGameView.cs new file mode 100644 index 0000000..d9b02c3 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/IGameView.cs @@ -0,0 +1,10 @@ +using System; + +namespace Minesweeper.Presentation.Views +{ + public interface IGameView : IView + { + event Action RestartRequested; + event Action GoToMenuRequested; + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/IGameView.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Views/IGameView.cs.meta new file mode 100644 index 0000000..21d72a1 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/IGameView.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a8c5423ea37354a4e82b05aadfbf239f \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/IMainMenuView.cs b/Assets/Minesweeper/Runtime/Presentation/Views/IMainMenuView.cs new file mode 100644 index 0000000..a68b89e --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/IMainMenuView.cs @@ -0,0 +1,9 @@ +using System; + +namespace Minesweeper.Presentation.Views +{ + public interface IMainMenuView : IView + { + event Action StartClicked; + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/IMainMenuView.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Views/IMainMenuView.cs.meta new file mode 100644 index 0000000..a7502af --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/IMainMenuView.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 66cad179080f23a479c3418932137653 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/IView.cs b/Assets/Minesweeper/Runtime/Presentation/Views/IView.cs new file mode 100644 index 0000000..5c22884 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/IView.cs @@ -0,0 +1,6 @@ +namespace Minesweeper.Presentation.Views +{ + public interface IView + { + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/IView.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Views/IView.cs.meta new file mode 100644 index 0000000..2803bcd --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/IView.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 66a8b79ae5812744680f9e386b007144 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/NullGameView.cs b/Assets/Minesweeper/Runtime/Presentation/Views/NullGameView.cs new file mode 100644 index 0000000..d0a835f --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/NullGameView.cs @@ -0,0 +1,19 @@ +using System; + +namespace Minesweeper.Presentation.Views +{ + public sealed class NullGameView : IGameView + { + public event Action RestartRequested + { + add { } + remove { } + } + + public event Action GoToMenuRequested + { + add { } + remove { } + } + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/NullGameView.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Views/NullGameView.cs.meta new file mode 100644 index 0000000..29c1f40 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/NullGameView.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c800a42df535f9347bea10f164fd2e15 \ No newline at end of file diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/NullMainMenuView.cs b/Assets/Minesweeper/Runtime/Presentation/Views/NullMainMenuView.cs new file mode 100644 index 0000000..c27b71e --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/NullMainMenuView.cs @@ -0,0 +1,13 @@ +using System; + +namespace Minesweeper.Presentation.Views +{ + public sealed class NullMainMenuView : IMainMenuView + { + public event Action StartClicked + { + add { } + remove { } + } + } +} diff --git a/Assets/Minesweeper/Runtime/Presentation/Views/NullMainMenuView.cs.meta b/Assets/Minesweeper/Runtime/Presentation/Views/NullMainMenuView.cs.meta new file mode 100644 index 0000000..9a85495 --- /dev/null +++ b/Assets/Minesweeper/Runtime/Presentation/Views/NullMainMenuView.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6b41dd95488a1db42adccef0225d2f89 \ No newline at end of file diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 6fbbb0c..bb0d5ce 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -119,6 +119,66 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} +--- !u!1 &204299655 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 204299656} + - component: {fileID: 204299657} + m_Layer: 5 + m_Name: GameObject + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &204299656 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 204299655} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1373940536} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &204299657 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 204299655} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.GridLayoutGroup + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 0 + m_StartCorner: 0 + m_StartAxis: 0 + m_CellSize: {x: 100, y: 100} + m_Spacing: {x: 0, y: 0} + m_Constraint: 0 + m_ConstraintCount: 2 --- !u!1 &239194487 GameObject: m_ObjectHideFlags: 0 @@ -949,7 +1009,7 @@ MonoBehaviour: m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 + m_RaycastTarget: 0 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: @@ -985,6 +1045,7 @@ GameObject: - component: {fileID: 1153970988} - component: {fileID: 1153970987} - component: {fileID: 1153970986} + - component: {fileID: 1153970989} m_Layer: 5 m_Name: Panel (Smile) m_TagString: Untagged @@ -1070,6 +1131,99 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1153970984} m_CullTransparentMesh: 1 +--- !u!114 &1153970989 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1153970984} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1141020856} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!1 &1287266280 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1287266282} + - component: {fileID: 1287266281} + m_Layer: 0 + m_Name: MinesweeperCompositionRoot + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1287266281 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287266280} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d4f9b0c2ad803d84382fbf03ba3096fa, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Minesweeper.Infrastructure.MinesweeperLifetimeScope + parentReference: + TypeName: + autoRun: 1 + autoInjectGameObjects: [] + gameConfig: {fileID: 11400000, guid: 4c24a7c2a548eff4fb21fa4a4bf3e741, type: 2} +--- !u!4 &1287266282 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287266280} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1373940535 GameObject: m_ObjectHideFlags: 0 @@ -1097,13 +1251,14 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 - m_Children: [] + m_Children: + - {fileID: 204299656} m_Father: {fileID: 289057769} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -30} - m_SizeDelta: {x: -30, y: -90} + m_AnchoredPosition: {x: 0, y: -32.5} + m_SizeDelta: {x: -30, y: -95} m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &2098378341 GameObject: @@ -1192,3 +1347,4 @@ SceneRoots: - {fileID: 619394802} - {fileID: 239194491} - {fileID: 2098378344} + - {fileID: 1287266282} diff --git a/Packages/manifest.json b/Packages/manifest.json index 7fcabbb..677a1a5 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -9,6 +9,7 @@ "com.unity.2d.tilemap.extras": "6.0.2", "com.unity.2d.tooling": "1.0.3", "com.unity.collab-proxy": "2.12.4", + "com.unity.entities": "1.4.7", "com.unity.ide.rider": "3.0.40", "com.unity.ide.visualstudio": "2.0.26", "com.unity.inputsystem": "1.19.0", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 701b2f3..4035854 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -101,7 +101,7 @@ }, "com.unity.burst": { "version": "1.8.29", - "depth": 2, + "depth": 1, "source": "registry", "dependencies": { "com.unity.mathematics": "1.2.1", @@ -117,11 +117,11 @@ "url": "https://packages.unity.com" }, "com.unity.collections": { - "version": "2.6.6", + "version": "2.6.7", "depth": 1, "source": "registry", "dependencies": { - "com.unity.burst": "1.8.28", + "com.unity.burst": "1.8.29", "com.unity.mathematics": "1.3.2", "com.unity.test-framework": "1.4.6", "com.unity.nuget.mono-cecil": "1.11.6", @@ -129,6 +129,28 @@ }, "url": "https://packages.unity.com" }, + "com.unity.entities": { + "version": "1.4.7", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.burst": "1.8.29", + "com.unity.collections": "2.6.7", + "com.unity.mathematics": "1.3.2", + "com.unity.modules.audio": "1.0.0", + "com.unity.serialization": "3.1.3", + "com.unity.profiling.core": "1.0.3", + "com.unity.modules.physics": "1.0.0", + "com.unity.nuget.mono-cecil": "1.11.6", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.scriptablebuildpipeline": "1.23.1", + "com.unity.test-framework.performance": "3.0.3" + }, + "url": "https://packages.unity.com" + }, "com.unity.ext.nunit": { "version": "2.0.5", "depth": 1, @@ -179,7 +201,7 @@ }, "com.unity.nuget.mono-cecil": { "version": "1.11.6", - "depth": 2, + "depth": 1, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" @@ -191,6 +213,13 @@ "dependencies": {}, "url": "https://packages.unity.com" }, + "com.unity.profiling.core": { + "version": "1.0.3", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, "com.unity.render-pipelines.core": { "version": "17.3.0", "depth": 1, @@ -223,6 +252,16 @@ "com.unity.render-pipelines.core": "17.0.3" } }, + "com.unity.scriptablebuildpipeline": { + "version": "2.6.1", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.4.5", + "com.unity.modules.assetbundle": "1.0.0" + }, + "url": "https://packages.unity.com" + }, "com.unity.searcher": { "version": "4.9.4", "depth": 2, @@ -230,6 +269,16 @@ "dependencies": {}, "url": "https://packages.unity.com" }, + "com.unity.serialization": { + "version": "3.1.3", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.burst": "1.7.2", + "com.unity.collections": "2.4.2" + }, + "url": "https://packages.unity.com" + }, "com.unity.shadergraph": { "version": "17.3.0", "depth": 1, @@ -251,7 +300,7 @@ }, "com.unity.test-framework.performance": { "version": "3.5.0", - "depth": 2, + "depth": 1, "source": "registry", "dependencies": { "com.unity.test-framework": "1.1.33",