Migrate from the via meta-framework to direct dependencies:
- chi for routing, templ for HTML templates, datastar for SSE/reactivity
- Feature-sliced architecture (features/{auth,lobby,c4game,snakegame}/)
- Shared layouts and components (features/common/)
- Handler factory pattern (HandleX(deps) http.HandlerFunc)
- Embedded NATS server (nats/), SCS sessions (sessions/), chi router wiring (router/)
- Move ChatMessage domain type from ui package to game package
- Remove old ui/ package (gomponents-based via/h views)
- Remove via dependency from go.mod entirely
78 lines
1.8 KiB
Go
78 lines
1.8 KiB
Go
package game
|
|
|
|
import "encoding/json"
|
|
|
|
type PlayerID string
|
|
|
|
type Player struct {
|
|
ID PlayerID
|
|
UserID *string // UUID for authenticated users, nil for guests
|
|
Nickname string
|
|
Color int // 1 = Red, 2 = Yellow
|
|
}
|
|
|
|
type GameStatus int
|
|
|
|
const (
|
|
StatusWaitingForPlayer GameStatus = iota
|
|
StatusInProgress
|
|
StatusWon
|
|
StatusDraw
|
|
)
|
|
|
|
type Game struct {
|
|
ID string
|
|
Board [6][7]int // 6 rows, 7 columns; 0=empty, 1=red, 2=yellow
|
|
Players [2]*Player // Index 0 = creator (Red), Index 1 = joiner (Yellow)
|
|
CurrentTurn int // 1 or 2 (matches player color)
|
|
Status GameStatus
|
|
Winner *Player
|
|
WinningCells [][2]int // Coordinates of winning 4 cells for highlighting
|
|
RematchGameID *string // ID of the rematch game, if one was created
|
|
}
|
|
|
|
func NewGame(id string) *Game {
|
|
return &Game{
|
|
ID: id,
|
|
Board: [6][7]int{},
|
|
CurrentTurn: 1, // Red goes first
|
|
Status: StatusWaitingForPlayer,
|
|
}
|
|
}
|
|
|
|
func (g *Game) IsFinished() bool {
|
|
return g.Status == StatusWon || g.Status == StatusDraw
|
|
}
|
|
|
|
func (g *Game) BoardToJSON() string {
|
|
data, _ := json.Marshal(g.Board)
|
|
return string(data)
|
|
}
|
|
|
|
func (g *Game) BoardFromJSON(data string) error {
|
|
return json.Unmarshal([]byte(data), &g.Board)
|
|
}
|
|
|
|
func (g *Game) WinningCellsToJSON() string {
|
|
if g.WinningCells == nil {
|
|
return ""
|
|
}
|
|
data, _ := json.Marshal(g.WinningCells)
|
|
return string(data)
|
|
}
|
|
|
|
func (g *Game) WinningCellsFromJSON(data string) error {
|
|
if data == "" {
|
|
return nil
|
|
}
|
|
return json.Unmarshal([]byte(data), &g.WinningCells)
|
|
}
|
|
|
|
// ChatMessage is the domain type for persisted C4 chat messages.
|
|
type ChatMessage struct {
|
|
Nickname string `json:"nickname"`
|
|
Color int `json:"color"` // 1=Red, 2=Yellow
|
|
Message string `json:"message"`
|
|
Time int64 `json:"time"`
|
|
}
|