Files
tic-tac-toe/plugins/games/rules.go
Vishesh 'ironeagle' Bangotra bcdc5faea5 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.
2025-12-03 17:52:27 +05:30

47 lines
1.6 KiB
Go

package games
import "localrepo/plugins/structs"
// 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
// Assign symbols/colors/pieces at start.
AssignPlayerSymbols(players []*structs.Player)
// Apply a move.
// Returns: (changed, gameOver, winnerIndex)
ApplyMove(state *structs.MatchState, playerIdx int, payload MovePayload) (bool, bool, int)
// If a player leaves, who wins?
// Return:
// >=0 → winner index
// -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
}