package game import ( "encoding/json" "github.com/ryanhamamura/c4/player" ) type Player struct { ID player.ID 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"` }