diff --git a/src/Application/Gaas.GobbletGobblers.Application/GameModel.cs b/src/Application/Gaas.GobbletGobblers.Application/GameModel.cs index 886da06..2c39363 100644 --- a/src/Application/Gaas.GobbletGobblers.Application/GameModel.cs +++ b/src/Application/Gaas.GobbletGobblers.Application/GameModel.cs @@ -62,4 +62,15 @@ public class ErrorResult { public string Message { get; set; } } + + + public class User + { + public string Id { get; set; } + + public string Email { get; set; } + + public string NickName { get; set; } + } + } diff --git a/src/Application/Gaas.GobbletGobblers.Application/UseCases/CreateGameRequest.cs b/src/Application/Gaas.GobbletGobblers.Application/UseCases/CreateGameRequest.cs index 4ef3aaa..4306551 100644 --- a/src/Application/Gaas.GobbletGobblers.Application/UseCases/CreateGameRequest.cs +++ b/src/Application/Gaas.GobbletGobblers.Application/UseCases/CreateGameRequest.cs @@ -2,6 +2,8 @@ { public class CreateGameRequest { + public Guid PlayerId { get; set; } + public string PlayerName { get; set; } } } \ No newline at end of file diff --git a/src/Application/Gaas.GobbletGobblers.Application/UseCases/CreateGameUseCase.cs b/src/Application/Gaas.GobbletGobblers.Application/UseCases/CreateGameUseCase.cs index d9b5fa8..18fc67c 100644 --- a/src/Application/Gaas.GobbletGobblers.Application/UseCases/CreateGameUseCase.cs +++ b/src/Application/Gaas.GobbletGobblers.Application/UseCases/CreateGameUseCase.cs @@ -16,7 +16,7 @@ public async Task ExecuteAsync(CreateGameRequest request, IRepository throw new Exception(); // 改 - var player = new Player(); + var player = new Player(request.PlayerId); player.Nameself(request.PlayerName); game = new Game(); diff --git a/src/Application/Gaas.GobbletGobblers.Application/UseCases/JoinGameRequest.cs b/src/Application/Gaas.GobbletGobblers.Application/UseCases/JoinGameRequest.cs index 3da293c..7dd10b6 100644 --- a/src/Application/Gaas.GobbletGobblers.Application/UseCases/JoinGameRequest.cs +++ b/src/Application/Gaas.GobbletGobblers.Application/UseCases/JoinGameRequest.cs @@ -4,6 +4,8 @@ public class JoinGameRequest { public Guid Id { get; set; } + public Guid PlayerId { get; set; } + public string PlayerName { get; set; } } } \ No newline at end of file diff --git a/src/Application/Gaas.GobbletGobblers.Application/UseCases/JoinGameUseCase.cs b/src/Application/Gaas.GobbletGobblers.Application/UseCases/JoinGameUseCase.cs index bbb9afb..75aab19 100644 --- a/src/Application/Gaas.GobbletGobblers.Application/UseCases/JoinGameUseCase.cs +++ b/src/Application/Gaas.GobbletGobblers.Application/UseCases/JoinGameUseCase.cs @@ -14,7 +14,7 @@ public async Task ExecuteAsync(JoinGameRequest request, IRepository r throw new Exception(); // 改 - var player = new Player(); + var player = new Player(request.PlayerId); player.Nameself(request.PlayerName); game.JoinPlayer(player); diff --git a/src/Domain/Gaas.GobbletGobblers.Domain/Player.cs b/src/Domain/Gaas.GobbletGobblers.Domain/Player.cs index 61ce5d8..24e5a23 100644 --- a/src/Domain/Gaas.GobbletGobblers.Domain/Player.cs +++ b/src/Domain/Gaas.GobbletGobblers.Domain/Player.cs @@ -17,6 +17,11 @@ public Player() this.Id = Guid.NewGuid(); } + public Player(Guid guid) + { + this.Id = guid; + } + public Player Nameself(string name) { this.Name = name; diff --git a/src/InterfaceAdapter/Gaas.GobbletGobblers.Client/Pages/Game.razor b/src/InterfaceAdapter/Gaas.GobbletGobblers.Client/Pages/Game.razor new file mode 100644 index 0000000..f56a5bd --- /dev/null +++ b/src/InterfaceAdapter/Gaas.GobbletGobblers.Client/Pages/Game.razor @@ -0,0 +1,382 @@ +@page "/games/{gameId?}" +@inject HttpClient Http +@using System.Timers; +@using System.Net; +@using Gaas.GobbletGobblers.Application; +@using Gaas.GobbletGobblers.Application.UseCases; +@using Gaas.GobbletGobblers.Domain; +@using System.Text.Json; + + + + + Gobblet Gobblers + + + +
@GameId
+
@name
+
+ @foreach (var row in Enumerable.Range(0, boardSize)) + { +
+ @foreach (var col in Enumerable.Range(0, boardSize)) + { +
+ @if (board != null && board[boardSize * row + col].Any()) + { + @foreach (var cock in board[boardSize * row + col]) + { + var size = "small"; + switch (cock.Size.Number) + { + case -1: + size = "small"; + break; + case 0: + size = "medium"; + break; + case 1: + size = "large"; + break; + } +
+ } + } +
+ } +
+ } +
+ +
+
+ @if (playerViewModel != null) + { + @foreach (var item in playerViewModel.Cocks.Select((c, i) => (c, i))) + { + var cock = item.c; + var color = cock.Color.ToString(); + var size = "small"; + switch (cock.Size.Number) + { + case -1: + size = "small"; + break; + case 0: + size = "medium"; + break; + case 1: + size = "large"; + break; + } + +
+
+
+ } + } +
+ @if (winnerId.HasValue) + { +
+ 勝利者: @winnerName +
+ } + + @if (errorResult != null) + { +
@errorResult.Message
+ } +
+ + + + + +@code { + [Parameter] + public string? GameId { get; set; } + + [Parameter] + [SupplyParameterFromQuery] + public string? Token { get; set; } + + private Timer timer; + + private ErrorResult? errorResult; + + private Guid playerId; + + private string name = string.Empty; + + private PlayerViewModel? playerViewModel; + + private int? changeCockId; + + private Stack[] board; + + private int boardSize; + + private Guid? winnerId; + + private string winnerName; + + private List moveClick = new List(); + + public Game() + { + timer = new(); + timer.Interval = 2000; + timer.Elapsed += async (object? sender, ElapsedEventArgs e) => + { + var request = new GameInfoRequest + { + Id = Guid.Parse(this.GameId), + }; + + var gameModel = await PostAsJsonAsync("Game/GameInfo", request); + + if (gameModel != null) + { + if (board == null) + { + boardSize = gameModel.BoardSize; + board = gameModel.Board; + } + + var playerModel = gameModel.Players.FirstOrDefault(p => p.Id == playerId); + + playerViewModel = playerModel; + + if (changeCockId.HasValue) + { + var cock = playerViewModel.Cocks.ElementAtOrDefault(changeCockId.Value); + if (cock != null) + { + cock.IsClick = true; + } + } + + board = gameModel.Board; + winnerId = gameModel.WinnerId; + } + + if (!moveClick.Any()) + { + moveClick = Enumerable.Range(0, boardSize * boardSize).Select(x => { return false; }).ToList(); + } + + if (winnerId.HasValue) + { + //Console.WriteLine(winnerId.ToString()); + winnerName = gameModel.Players.FirstOrDefault(p => p.Id == winnerId).Name; + timer.Stop(); + } + + await InvokeAsync(StateHasChanged); + }; + } + + protected override async Task OnInitializedAsync() + { + var user = await GetAsJsonAsync(); + + var bytes = Convert.FromBase64String(user.Id); + + playerId = new Guid(bytes.Take(16).ToArray()); + name = user.NickName; + + timer.Enabled = true; + } + + protected async Task PutCock(int x, int y) + { + if (winnerId.HasValue) + { + return; + } + + if (board[x + (y * boardSize)].TryPeek(out var cockViewModel) && cockViewModel.Owner.Id == playerId) + { + moveClick[x + (y * boardSize)] = true; + playerViewModel.Cocks = playerViewModel.Cocks.Select(x => { x.IsClick = false; return x; }).ToList(); + changeCockId = null; + } + else + { + //Console.WriteLine(changeCockId.HasValue ? changeCockId.Value : ""); + + if (changeCockId.HasValue) + { + var request = new PutCockRequest + { + Id = Guid.Parse(this.GameId), + PlayerId = playerId, + HandCockIndex = changeCockId.Value, + Location = new Location(x, y), + }; + + try + { + var gameModel = await PostAsJsonAsync("Game/PutCock", request); + + if (gameModel != null) + { + board = gameModel.Board; + } + } + catch (Exception ex) + { + throw; + } + } + } + + StateHasChanged(); + } + + protected async Task ChangeCock(CockViewModel cock, int index) + { + moveClick = moveClick.Select(x => false).ToList(); + + //Console.WriteLine(index); + changeCockId = index; + playerViewModel.Cocks.ToList().ForEach(x => { x.IsClick = false; }); + cock.IsClick = true; + Console.WriteLine(JsonSerializer.Serialize(moveClick)); + + StateHasChanged(); + } + + private async Task PostAsJsonAsync(string requestUri, TRequest request) + where TResponse : new() + { + errorResult = null; + + var response = await Http.PostAsJsonAsync(requestUri, request); + + if (response.StatusCode == HttpStatusCode.OK) + { + return await response.Content.ReadFromJsonAsync(); + } + else + { + errorResult = await response.Content.ReadFromJsonAsync(); + + return default; + } + } + + private async Task GetAsJsonAsync() + where TResponse : new() + { + try + { + errorResult = null; + + var http = new HttpClient(); + http.BaseAddress = new Uri("https://api.gaas.waterballsa.tw"); + http.DefaultRequestHeaders.Add("Authorization", $"Bearer {Token}"); + + var response = await http.GetAsync("/users/me"); + + if (response.StatusCode == HttpStatusCode.OK) + { + return await response.Content.ReadFromJsonAsync(); + } + else + { + errorResult = await response.Content.ReadFromJsonAsync(); + + return default; + } + } + catch (Exception ex) + { + throw; + } + } +} diff --git a/src/InterfaceAdapter/Gaas.GobbletGobblers.Client/Program.cs b/src/InterfaceAdapter/Gaas.GobbletGobblers.Client/Program.cs index 35341ba..17d668a 100644 --- a/src/InterfaceAdapter/Gaas.GobbletGobblers.Client/Program.cs +++ b/src/InterfaceAdapter/Gaas.GobbletGobblers.Client/Program.cs @@ -7,5 +7,6 @@ builder.RootComponents.Add("head::after"); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https://putaonini.zeabur.app") }); +//builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://localhost:5075") }); await builder.Build().RunAsync(); diff --git a/src/InterfaceAdapter/Gaas.GobbletGobblers.Core.WebApi/Controllers/GameController.cs b/src/InterfaceAdapter/Gaas.GobbletGobblers.Core.WebApi/Controllers/GameController.cs index 5418856..1bf91a7 100644 --- a/src/InterfaceAdapter/Gaas.GobbletGobblers.Core.WebApi/Controllers/GameController.cs +++ b/src/InterfaceAdapter/Gaas.GobbletGobblers.Core.WebApi/Controllers/GameController.cs @@ -27,6 +27,7 @@ public async Task GamesAsync(GameRequest request) { var createGameRequest = new CreateGameRequest { + PlayerId = new Guid(Convert.FromBase64String(request.Players[0].Id).Take(16).ToArray()), PlayerName = request.Players[0].Nickname }; @@ -35,6 +36,7 @@ public async Task GamesAsync(GameRequest request) var joinGameRequest = new JoinGameRequest { Id = createGameResponse.Id, + PlayerId = new Guid(Convert.FromBase64String(request.Players[1].Id).Take(16).ToArray()), PlayerName = request.Players[1].Nickname }; _ = await new JoinGameUseCase().ExecuteAsync(joinGameRequest, _repository);