Feat: bot ends game to the stats

This commit is contained in:
Grail Finder
2025-07-10 20:21:10 +03:00
parent 8040586043
commit 89572e8fb5
2 changed files with 73 additions and 0 deletions

View File

@ -107,6 +107,7 @@ func (b *Bot) checkGuess(word string, room *models.Room) error {
} }
room.ActionHistory = append(room.ActionHistory, action) room.ActionHistory = append(room.ActionHistory, action)
b.StopTurnTimer() b.StopTurnTimer()
updateStatsOnGameOver(context.Background(), room)
case string(models.WordColorWhite), string(oppositeColor): case string(models.WordColorWhite), string(oppositeColor):
// end turn // end turn
room.TeamTurn = oppositeColor room.TeamTurn = oppositeColor
@ -132,6 +133,7 @@ func (b *Bot) checkGuess(word string, room *models.Room) error {
} }
room.ActionHistory = append(room.ActionHistory, action) room.ActionHistory = append(room.ActionHistory, action)
b.StopTurnTimer() b.StopTurnTimer()
updateStatsOnGameOver(context.Background(), room)
} }
if room.RedCounter == 0 { if room.RedCounter == 0 {
// red won // red won
@ -149,6 +151,7 @@ func (b *Bot) checkGuess(word string, room *models.Room) error {
} }
room.ActionHistory = append(room.ActionHistory, action) room.ActionHistory = append(room.ActionHistory, action)
b.StopTurnTimer() b.StopTurnTimer()
updateStatsOnGameOver(context.Background(), room)
} }
ctx, tx, err := repo.InitTx(context.Background()) ctx, tx, err := repo.InitTx(context.Background())
// nolint: errcheck // nolint: errcheck

70
llmapi/stats.go Normal file
View File

@ -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)
}
}
}