diff --git a/llmapi/main.go b/llmapi/main.go index f74283c..fd3b3f9 100644 --- a/llmapi/main.go +++ b/llmapi/main.go @@ -107,6 +107,7 @@ func (b *Bot) checkGuess(word string, room *models.Room) error { } room.ActionHistory = append(room.ActionHistory, action) b.StopTurnTimer() + updateStatsOnGameOver(context.Background(), room) case string(models.WordColorWhite), string(oppositeColor): // end turn room.TeamTurn = oppositeColor @@ -132,6 +133,7 @@ func (b *Bot) checkGuess(word string, room *models.Room) error { } room.ActionHistory = append(room.ActionHistory, action) b.StopTurnTimer() + updateStatsOnGameOver(context.Background(), room) } if room.RedCounter == 0 { // red won @@ -149,6 +151,7 @@ func (b *Bot) checkGuess(word string, room *models.Room) error { } room.ActionHistory = append(room.ActionHistory, action) b.StopTurnTimer() + updateStatsOnGameOver(context.Background(), room) } ctx, tx, err := repo.InitTx(context.Background()) // nolint: errcheck diff --git a/llmapi/stats.go b/llmapi/stats.go new file mode 100644 index 0000000..211b9a1 --- /dev/null +++ b/llmapi/stats.go @@ -0,0 +1,70 @@ +package llmapi + +import ( + "context" + "gralias/models" + "log/slog" + "os" +) + +var log *slog.Logger + +func init() { + log = slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ + Level: slog.LevelDebug, + AddSource: true, + })) +} + +// updateStatsOnGameOver updates stats for all players in a room when a game ends. +func updateStatsOnGameOver(ctx context.Context, room *models.Room) { + // Get all players in the room + players, err := repo.PlayerListByRoom(ctx, room.ID) + if err != nil { + log.Error("failed to list players by room for stats update", "room_id", room.ID, "error", err) + return + } + + for _, player := range players { + if player.IsBot { + continue + } + + stats, err := repo.GetPlayerStats(ctx, player.Username) + if err != nil { + log.Error("failed to get player stats for game over update", "username", player.Username, "error", err) + continue + } + + stats.GamesPlayed++ + if player.Team == room.TeamWon { + stats.GamesWon++ + } else { + stats.GamesLost++ + } + + if player.Role == models.UserRoleMime { + stats.PlayedAsMime++ + if stats.PlayedAsMime > 0 { + gamesWonAsMime := stats.MimeWinrate * float64(stats.PlayedAsMime-1) + if player.Team == room.TeamWon { + gamesWonAsMime++ + } + stats.MimeWinrate = gamesWonAsMime / float64(stats.PlayedAsMime) + } + } else if player.Role == models.UserRoleGuesser { + stats.PlayedAsGuesser++ + if stats.PlayedAsGuesser > 0 { + gamesWonAsGuesser := stats.GuesserWinrate * float64(stats.PlayedAsGuesser-1) + if player.Team == room.TeamWon { + gamesWonAsGuesser++ + } + stats.GuesserWinrate = gamesWonAsGuesser / float64(stats.PlayedAsGuesser) + } + } + + if err := repo.UpdatePlayerStats(ctx, stats); err != nil { + log.Error("failed to update player stats on game over", "username", player.Username, "error", err) + } + } +}