diff --git a/API/Controllers/GameHubSocket.cs b/API/Controllers/GameHubSocket.cs index be4df3e..0842dae 100644 --- a/API/Controllers/GameHubSocket.cs +++ b/API/Controllers/GameHubSocket.cs @@ -28,7 +28,7 @@ public class GameHubSocket(IGameManager gameManager) : Hub { var player = new Player(playerName, Context.ConnectionId); - var result = _gameManager.JoinGame(player, gameCode); + var result = await _gameManager.JoinGame(player, gameCode); if (result == null) { @@ -44,4 +44,9 @@ public class GameHubSocket(IGameManager gameManager) : Hub GameCode = gameCode, }); } + + public async Task Place(string gameId, int index) + { + + } } \ No newline at end of file diff --git a/API/Models/Game/Game.cs b/API/Models/Game/Game.cs index efcc1b7..e7784d3 100644 --- a/API/Models/Game/Game.cs +++ b/API/Models/Game/Game.cs @@ -22,7 +22,14 @@ public class Game(Coordinates gFs, SixDigitInt gameCode) if(Players.Count >= 2) return false; + player.PlayerTag = Players.Count + 1; Players.Add(player); + + if (Players.Count == 2) + { + StartGame(); + } + return true; } @@ -30,4 +37,19 @@ public class Game(Coordinates gFs, SixDigitInt gameCode) { Players.RemoveAll(x => x.ConnectionId == playerConnectionId); } + + public Player? GetPlayerByConnectionId(string playerConnectionId) + { + return Players.FirstOrDefault(x => x.ConnectionId == playerConnectionId); + } + + private void StartGame() + { + State = GameState.Running; + } + + public void EndGame() + { + State = GameState.Ended; + } } \ No newline at end of file diff --git a/API/Models/Game/GameField.cs b/API/Models/Game/GameField.cs index 2b61d08..e3e144f 100644 --- a/API/Models/Game/GameField.cs +++ b/API/Models/Game/GameField.cs @@ -27,6 +27,7 @@ public enum FieldState public class GameField(Coordinates gFs) { + private Coordinates _gFs = gFs; public int[,] CurrentField { get; } = new int[gFs.Y, gFs.X]; public int[,] BackupField { get; } = new int[gFs.Y, gFs.X]; @@ -72,6 +73,58 @@ public class GameField(Coordinates gFs) }; } + private int CountInDirection(int startX, int startY, int dx, int dy, int player) + { + var count = 0; + var x = startX; + var y = startY; + + while ( + x >= 0 && x < CurrentField.GetLength(1) && + y >= 0 && y < CurrentField.GetLength(0) && + CurrentField[y, x] == player) + { + count++; + x += dx; + y += dy; + } + + return count; + } + + private bool CheckLine(int startX, int startY, int dx, int dy, int player) + { + int count = CountInDirection(startX + dx, startY + dy, dx, dy, player); + count += CountInDirection(startX - dx, startY - dy, -dx, -dy, player); + return count + 1 >= 4; + } + + public int CheckForWin() + { + int rows = CurrentField.GetLength(0); + int cols = CurrentField.GetLength(1); + + (int dx, int dy)[] directions = [(1, 0), (0, 1), (1, 1), (-1, 1)]; + + for (int y = 0; y < rows; y++) + { + for (int x = 0; x < cols; x++) + { + int player = CurrentField[y, x]; + + if (player != 1 && player != 2) continue; + + foreach (var (dx, dy) in directions) + { + if (CheckLine(x, y, dx, dy, player)) + return player; + } + } + } + + return 0; + } + private void CreateSave() { Array.Copy(CurrentField, BackupField, CurrentField.Length); diff --git a/API/Models/Game/Player.cs b/API/Models/Game/Player.cs index bc56f6e..0598e97 100644 --- a/API/Models/Game/Player.cs +++ b/API/Models/Game/Player.cs @@ -4,4 +4,5 @@ public class Player(string name, string connectionId) { public string Name { get; set; } = name; public string ConnectionId { get; set; } = connectionId; + public int PlayerTag { get; set; } } \ No newline at end of file diff --git a/API/Repository/GameRepo/GameRepository.cs b/API/Repository/GameRepo/GameRepository.cs index 395a7a4..536257d 100644 --- a/API/Repository/GameRepo/GameRepository.cs +++ b/API/Repository/GameRepo/GameRepository.cs @@ -22,11 +22,10 @@ public class GameRepository : IGameRepository return _games.FirstOrDefault(g => g.GameCode == gameCode); } - public Game Create(Coordinates gameFieldSize, Player player) + public Game Create(Coordinates gameFieldSize) { Game newGame = new(gameFieldSize, GenerateGameCode()); _games.Add(newGame); - newGame.AddPlayer(player); return newGame; } @@ -40,9 +39,9 @@ public class GameRepository : IGameRepository { while (true) { - int value = RandomNumberGenerator.GetInt32(100000, 1000000); + var value = RandomNumberGenerator.GetInt32(100000, 1000000); - bool exists = _games.Any(g => g.GameCode.Value == value); + var exists = _games.Any(g => g.GameCode.Value == value); if (!exists) { return new SixDigitInt(value); diff --git a/API/Repository/GameRepo/IGameRepository.cs b/API/Repository/GameRepo/IGameRepository.cs index 25843f0..db508cc 100644 --- a/API/Repository/GameRepo/IGameRepository.cs +++ b/API/Repository/GameRepo/IGameRepository.cs @@ -8,6 +8,6 @@ public interface IGameRepository public List GetAll(); public Game? GetOne(string id); public Game? GetOne(SixDigitInt gameCode); - public Game Create(Coordinates gameFieldSize, Player player); + public Game Create(Coordinates gameFieldSize); public void Destroy(string id); } \ No newline at end of file diff --git a/API/Services/GameManager/GameManager.cs b/API/Services/GameManager/GameManager.cs index 47de874..b1346eb 100644 --- a/API/Services/GameManager/GameManager.cs +++ b/API/Services/GameManager/GameManager.cs @@ -1,24 +1,34 @@ -using API.Models.DataClasses; +using API.Controllers; +using API.Models.DataClasses; using API.Models.Game; using API.Repository.GameRepo; +using Microsoft.AspNetCore.SignalR; namespace API.Services.GameManager; -public class GameManager(IGameRepository gameRepository) : IGameManager +public class GameManager(IGameRepository gameRepository, IHubContext hubContext) : IGameManager { public (string, int) CreateGame(Coordinates gFs, Player player) { - var game = gameRepository.Create(gFs, player); - + var game = gameRepository.Create(gFs); + game.AddPlayer(player); return (game.Id, game.GameCode); } - public string? JoinGame(Player player, int gameCode) + public async Task JoinGame(Player player, int gameCode) { var game = gameRepository.GetOne(new SixDigitInt(gameCode)); var success = game != null && game.AddPlayer(player); - return success ? game?.Id : null; + if (game!.State == GameState.Running) + await hubContext.Clients.Group(game.Id).SendAsync("GameStarted"); + + return game.Id; + } + + public async Task Place(string gameCode, int coordinates, string playerConnectionId) + { + return true; } } \ No newline at end of file diff --git a/API/Services/GameManager/IGameManager.cs b/API/Services/GameManager/IGameManager.cs index a610346..47bffe3 100644 --- a/API/Services/GameManager/IGameManager.cs +++ b/API/Services/GameManager/IGameManager.cs @@ -5,5 +5,6 @@ namespace API.Services.GameManager; public interface IGameManager { public (string, int) CreateGame(Coordinates gFs, Player player); - public string? JoinGame(Player playerName, int gameCode); + public Task JoinGame(Player player, int gameCode) + public Task Place(string gameCode, int coordinates, string playerConnectionId) } \ No newline at end of file