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

@@ -12,6 +12,11 @@ import (
func SnakeStatusBanner(sg *snake.SnakeGame, mySlot int, rematchClick h.H) h.H {
switch sg.Status {
case snake.StatusWaitingForPlayers:
if sg.Mode == snake.ModeSinglePlayer {
return h.Div(h.Class("alert bg-base-200 text-xl font-bold"),
h.Text("Ready?"),
)
}
return h.Div(h.Class("alert bg-base-200 text-xl font-bold"),
h.Text("Waiting for players..."),
)
@@ -35,6 +40,12 @@ func SnakeStatusBanner(sg *snake.SnakeGame, mySlot int, rematchClick h.H) h.H {
)
}
}
// Show score during single player gameplay
if sg.Mode == snake.ModeSinglePlayer {
return h.Div(h.Class("alert alert-success text-xl font-bold"),
h.Text(fmt.Sprintf("Score: %d", sg.Score)),
)
}
return h.Div(h.Class("alert alert-success text-xl font-bold"),
h.Text("Go!"),
)
@@ -42,7 +53,11 @@ func SnakeStatusBanner(sg *snake.SnakeGame, mySlot int, rematchClick h.H) h.H {
case snake.StatusFinished:
var msg string
var class string
if sg.Winner != nil {
if sg.Mode == snake.ModeSinglePlayer {
msg = fmt.Sprintf("Game Over! Score: %d", sg.Score)
class = "alert alert-info text-xl font-bold"
} else if sg.Winner != nil {
if sg.Winner.Slot == mySlot {
msg = "You win!"
class = "alert alert-success text-xl font-bold"