Add bot play, replay creation, and move phrases

Create replay games when a match ends (win or draw) and include ReplayGameCode in the GameEnded payload; adjust deletion timing to keep the replay longer and clean up original games sooner. Update game deletion logic to only destroy non-running games and schedule immediate deletion for quick timeouts. Add optional local bot support (botPlayer2 flag) with automated random-delayed moves and a UI switch in the game creation menu; expose botPlayer2 in GameSettings and LocalMode defaults. Introduce RandomPlaceMessage utility to generate varied turn descriptions and integrate it into LocalGame and OnlineGame. Also include a minor whitespace fix in Game.cs.
This commit is contained in:
Jonas
2026-03-12 22:15:12 +01:00
parent 4826760d73
commit 0e4fb5d828
8 changed files with 151 additions and 12 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ public class Game(Coordinates gFs, SixDigitInt gameCode)
public int CurrentTurn { get; set; } = 1;
public GameState State { get; private set; } = GameState.Lobby;
public GameField Field { get; } = new(gFs);
public bool AddPlayer(Player player)
{
if(Players.Count >= 2)
+13 -6
View File
@@ -100,27 +100,34 @@ public class GameManager(IGameRepository gameRepository, IHubContext<GameHubSock
var winResult = game.Field.CheckForWin();
if (winResult != 0)
{
var newGame = gameRepository.Create(game.Field.GFs);
var winPlayer = game.GetPlayerByTag(winResult);
game.EndGame();
await hubContext.Clients.Group(game.Id).SendAsync("GameEnded", new
{
Method = "Win",
Player = winPlayer
Player = winPlayer,
ReplayGameCode = newGame.GameCode
});
ScheduleGameDeletion(game.Id, TimeSpan.FromSeconds(5));
ScheduleGameDeletion(newGame.Id, TimeSpan.FromSeconds(20));
ScheduleGameDeletion(game.Id, TimeSpan.FromSeconds(10));
}
if (game.Field.IsFull())
{
var newGame = gameRepository.Create(game.Field.GFs);
game.EndGame();
await hubContext.Clients.Group(game.Id).SendAsync("GameEnded", new
{
Method = "Draw"
Method = "Draw",
ReplayGameCode = newGame.GameCode
});
ScheduleGameDeletion(game.Id, TimeSpan.FromSeconds(5));
ScheduleGameDeletion(newGame.Id, TimeSpan.FromSeconds(15));
ScheduleGameDeletion(game.Id, TimeSpan.FromSeconds(10));
}
}
@@ -142,7 +149,7 @@ public class GameManager(IGameRepository gameRepository, IHubContext<GameHubSock
Player = player
});
ScheduleGameDeletion(game.Id, TimeSpan.FromSeconds(5));
ScheduleGameDeletion(game.Id, TimeSpan.FromSeconds(0));
return Task.CompletedTask;
}
@@ -176,7 +183,7 @@ public class GameManager(IGameRepository gameRepository, IHubContext<GameHubSock
await Task.Delay(delay);
var g = gameRepository.GetOne(gameId);
if (g != null && g.State == GameState.Ended)
if (g != null && g.State != GameState.Running)
{
gameRepository.Destroy(gameId);