You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
package session
|
|
|
|
import "time"
|
|
|
|
// Status represents lifecycle state of a game session.
|
|
type Status string
|
|
|
|
const (
|
|
StatusCreated Status = "created"
|
|
StatusActive Status = "active"
|
|
StatusCompleted Status = "completed"
|
|
StatusTimedOut Status = "timed_out"
|
|
StatusAbandoned Status = "abandoned"
|
|
)
|
|
|
|
// GameSession is the aggregate root for gameplay session state.
|
|
type GameSession struct {
|
|
ID string
|
|
PlayerID string
|
|
PlayerName string
|
|
Status Status
|
|
TotalScore int
|
|
QuestionsAsked int
|
|
QuestionsCorrect int
|
|
HintsUsed int
|
|
|
|
CurrentQuestionID string
|
|
CurrentAttempts int
|
|
CurrentHintUsed bool
|
|
QuestionStartedAt *time.Time
|
|
|
|
StartTime time.Time
|
|
EndTime *time.Time
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
// SessionAttempt stores one answer attempt for audit and gameplay history.
|
|
type SessionAttempt struct {
|
|
ID string
|
|
SessionID string
|
|
QuestionID string
|
|
AttemptNumber int
|
|
ProvidedAnswer string
|
|
IsCorrect bool
|
|
UsedHint bool
|
|
AwardedScore int
|
|
LatencyMs int
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// SessionEvent stores lifecycle and anti-cheat events.
|
|
type SessionEvent struct {
|
|
ID string
|
|
SessionID string
|
|
EventType string
|
|
Metadata string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// IsTerminal reports whether the status is terminal.
|
|
func (s Status) IsTerminal() bool {
|
|
return s == StatusCompleted || s == StatusTimedOut || s == StatusAbandoned
|
|
}
|
|
|
|
// Remaining returns remaining attempts under max attempts.
|
|
func (g *GameSession) Remaining(maxAttempts int) int {
|
|
remaining := maxAttempts - g.CurrentAttempts
|
|
if remaining < 0 {
|
|
return 0
|
|
}
|
|
return remaining
|
|
}
|