mirror of
https://github.com/averel10/crypto_clash.git
synced 2026-03-12 19:08:11 +01:00
5.1 KiB
5.1 KiB
Multi-Game Implementation Summary
Overview
The Game smart contract has been updated to support multiple concurrent games. Each player can participate in only one active game at a time, and games are identified by unique game IDs and tracked by player addresses.
Key Changes
1. Data Structure Updates
Previous Structure:
- Single
currentGamevariable
New Structure:
See Data Structure Diagram for visual representation.
// Mapping from player address to their active game ID
mapping(address => uint) private playerToActiveGame;
// Mapping from game ID to game state
mapping(uint => GameState) private games;
// Array to track all game IDs (for enumeration)
uint[] private gameIds;
// Counter for generating unique game IDs
uint private nextGameId = 1;
// Array to store completed games
GameState[] private pastGames;
GameState struct updated with:
uint gameId- Unique identifier for each gamebool isActive- Flag to track if game is currently active
2. Registration System
New register(uint gameId) function:
- If
gameId = 0: Automatically finds an open game or creates a new one - If
gameId > 0: Joins the specified game (if valid and has space) - Returns both player ID (1 or 2) and the game ID
- Enforces one active game per address
Helper functions:
findOrCreateGame()- Finds a game with one player or creates new gamecreateNewGame()- Creates a new game with unique ID
3. Game Flow Updates
All game functions now work with the player's active game:
play(bytes32 encrMove)- Commits move to player's active gamereveal(string memory clearMove)- Reveals move in player's active gamegetOutcome()- Calculates outcome for player's active game
4. Game Lifecycle
Active Games:
- Players are automatically assigned to their active game via
playerToActiveGamemapping - All modifiers check the player's active game ID
Game Completion:
- When
getOutcome()is called:- Game outcome is calculated
- Game is moved to
pastGamesarray resetGame()clears player mappings and marks game as inactive- Winners are paid
- Players are free to join new games
5. New Helper Functions
Game Management:
getMyActiveGameId()- Returns caller's active game IDgetGameDetails(uint gameId)- View any game's detailsgetActiveGameIds()- Returns array of all active game IDsgetPastGamesCount()- Returns number of completed gamesgetPastGame(uint index)- Returns details of a past game
Updated Helper Functions: All existing helper functions now operate on the caller's active game:
whoAmI()- Returns player ID in their active gamebothPlayed()- Checks if both players committed in caller's gamebothRevealed()- Checks if both players revealed in caller's gameplayerARevealed()- Check player A status in caller's gameplayerBRevealed()- Check player B status in caller's gamerevealTimeLeft()- Time remaining in caller's gamegetLastWinner()- Outcome of caller's game
Usage Examples
Example 1: Auto-join or create game
// Player registers with gameId = 0 to auto-find/create game
(uint playerId, uint gameId) = game.register{value: 0.01 ether}(0);
// Returns: (1, 1) if creating new game, or (2, X) if joining existing game
Example 2: Join specific game
// Player joins game ID 5
(uint playerId, uint gameId) = game.register{value: 0.01 ether}(5);
// Returns: (2, 5) if successful
Example 3: Query active games
// Get all active game IDs
uint[] memory activeGames = game.getActiveGameIds();
// Check details of a specific game
(address playerA, address playerB, uint bet, Outcomes outcome, bool isActive)
= game.getGameDetails(gameId);
Example 4: View game history
// Get number of completed games
uint totalPastGames = game.getPastGamesCount();
// Get details of a specific past game
(address playerA, address playerB, uint bet, Outcomes outcome)
= game.getPastGame(0);
Benefits
- Concurrent Games: Multiple games can run simultaneously
- Player Isolation: Each player can only be in one game at a time
- Game Tracking: All games are tracked with unique IDs
- History: Completed games are preserved in
pastGames - Flexibility: Players can auto-join available games or specify game IDs
- Backwards Compatible: Existing game flow (commit-reveal-outcome) unchanged
Security Considerations
- Reentrancy Protection: Payment happens after game state is reset
- One Game Per Address: Enforced via
notAlreadyInGamemodifier - Game Isolation: Players can only interact with their active game
- State Consistency: Game marked inactive before clearing mappings
Migration Notes
Breaking Changes:
register()now returns(uint playerId, uint gameId)instead of justuint playerIdregister()now requires auint gameIdparameter (use 0 for auto-join)
Non-Breaking:
- All other function signatures remain the same
- Existing game flow unchanged
