### 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.
Updated TicTacToeRules and BattleshipRules to implement ApplyMove(state, playerIdx, payload) (bool, bool, int) as required by GameRules.
Added win/draw resolution logic directly inside each game’s ApplyMove return.
Removed obsolete convertToGamePlayers helper.
Updated GenericMatch to call AssignPlayerSymbols with []*structs.Player directly.
Ensured all rule implementations now fully satisfy the GameRules interface.