feat(core): migrate to multi-board architecture and implement per-game InitBoards
### Major changes - Replace single-board MatchState (`Board`) with multi-board map (`Boards`) - Update GenericMatch to initialize empty Boards and populate them via GameRules.InitBoards - Remove legacy `newEmptyBoard` helper from match.go - Update .gitignore to include *BKP* patterns ### GameRules interface - Add InitBoards(players, cfg) to allow games to construct their own board sets - Add detailed documentation explaining method responsibilities and usage - Improve MovePayload comment clarity ### TicTacToe updates - Implement InitBoards to produce a single `"tictactoe"` board - Replace all old references to `state.Board` with `state.Boards["tictactoe"]` - Make CheckGameOver, ValidateMove, and ApplyMove multi-board compatible ### Battleship updates - Implement InitBoards generating per-player ships + shots boards: - p0_ships, p0_shots - p1_ships, p1_shots ### Match flow updates - Boards are now created only when all players have joined - Initial state broadcast now includes `boards` instead of `board` This completes the backend migration for multi-board games and prepares the architecture for Battleship and other complex board-based games.
This commit is contained in:
@@ -2,11 +2,17 @@ package games
|
||||
|
||||
import "localrepo/plugins/structs"
|
||||
|
||||
// MovePayload is used for incoming move data from clients.
|
||||
// MovePayload is the decoded payload sent from clients.
|
||||
// It is intentionally untyped (map[string]interface{}) so each game
|
||||
// can define its own move structure (e.g., row/col, coordinate, action type, etc.)
|
||||
type MovePayload struct {
|
||||
Data map[string]interface{} `json:"data"`
|
||||
}
|
||||
|
||||
// GameRules defines a generic interface for match logic.
|
||||
//
|
||||
// Each game (TicTacToe, Battleship, Chess, etc.) must implement this interface.
|
||||
// The Nakama match handler delegates all game-specific behavior to these methods.
|
||||
type GameRules interface {
|
||||
// Number of players needed to start.
|
||||
MaxPlayers() int
|
||||
@@ -24,4 +30,17 @@ type GameRules interface {
|
||||
// -1 → draw
|
||||
// -2 → invalid
|
||||
ForfeitWinner(state *structs.MatchState, leaverIndex int) int
|
||||
|
||||
// InitBoards initializes all the boards required for the game.
|
||||
//
|
||||
// This is called AFTER all players have joined the match.
|
||||
//
|
||||
// Examples:
|
||||
// - TicTacToe → 1 board shared by both players: {"tictactoe": 3x3}
|
||||
// - Battleship → 2 boards per player:
|
||||
// {"p0_ships":10x10, "p0_shots":10x10, "p1_ships":..., "p1_shots":...}
|
||||
//
|
||||
// The returned map is stored in MatchState.Boards.
|
||||
InitBoards(players []*structs.Player, cfg GameConfiguration) map[string]*structs.Board
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user