I'm developing a contract that stores multiple Games between two players.
struct Game {
address player1;
address player2;
bool complete;
}
Game[] public games;
I would like to add functionality for the contract to randomly-ish assign player2 to a Game that is not yet complete.
function joinGame(bytes32 _commitment) public payable {
uint256 gameId = notReallyRandomButBetterThanNothing(games.length);
Game storage game = games[gameId];
game.player2 = msg.sender;
}
function notReallyRandomButBetterThanNothing(uint256 _max) internal
pure returns(uint256) {
return uint256(keccak256(block.timestamp)) % _max + 1;
}
In the example above, this will get a gameId to point to an index in the games array, but the issue is that that game might be complete.
I do not want to delete indexes from the games array when the game is complete because it will leave gaps and I do not want to shift and delete indexes because this will screw up the gameIds for other games in the array.
I also do not want to loop through the games array looking for a complete game because this could become costly.
What is the recommended storage pattern to deal with items that could be active or inactive?