feat: add single player snake mode

Add solo mode where players survive as long as possible while tracking
score (food eaten). Single player games start with a shorter 3-second
countdown vs 10 seconds for multiplayer, maintain exactly 1 food item
for classic snake feel, and end when the player dies rather than when
one player remains.

- Add GameMode type (ModeMultiplayer/ModeSinglePlayer) and Score field
- Filter single player games from "Join a Game" lobby list
- Show "Ready?" and "Score: X" UI for single player mode
- Hide invite link for single player games
- Preserve game mode on rematch
This commit is contained in:
Ryan Hamamura
2026-02-04 07:33:02 -10:00
parent 7faf94fa6d
commit f454e0d220
14 changed files with 205 additions and 78 deletions

View File

@@ -14,6 +14,13 @@ const (
DirRight
)
type GameMode int
const (
ModeMultiplayer GameMode = iota // Default (0) - backward compatible
ModeSinglePlayer // Single player survival mode
)
// Opposite returns true if a and b are 180-degree reversals.
func (d Direction) Opposite(other Direction) bool {
switch d {
@@ -88,6 +95,8 @@ type SnakeGame struct {
Winner *Player // nil if draw
CountdownEnd time.Time // when countdown reaches 0
RematchGameID *string
Mode GameMode // ModeMultiplayer or ModeSinglePlayer
Score int // tracks food eaten in single player
}
func (sg *SnakeGame) IsFinished() bool {
@@ -132,6 +141,7 @@ func (sg *SnakeGame) snapshot() *SnakeGame {
}
cp.Players = make([]*Player, len(sg.Players))
copy(cp.Players, sg.Players)
// Mode and Score are value types, already copied by *sg
return &cp
}