This is what I currently have: A singleton class GameManager
which mostly consists of a ConcurrentDictionary
that contains all ongoing games (binds the game board and nicks of both players to the game's ID). I also have a SignalR hub, GameHub
with a method MakeAMove(ulong gameId, Move move)
that retrieves the relevant gameId
game from the dictionary, lock
s on it, checks if the player who has invoked the method is the player who is now supposed to make a move and if yes, makes appropriate changes to the game's board, broadcasts this move to all observers of this game and if necessary, concludes the game, declaring it to be a victory of player X or a draw and removing it from the dictionary.
What I don't have is the timer. I think the timer is necessary, because without it many games may never conclude and forever linger in this dict. The timer should work in such a way that if a player fails to make a move within the allocated time, the game is automatically concluded and such a player is declared to be the loser.
I don't know how should such a timer be implemented. I have a few ideas, but I'm not sure which one is correct, if any.
The only idea I have to solve this task that doesn't seem to be horrible to me would look like this: ConcurrentDictionary
binds gameId
s to instances of Game
class. Then each such instance has a method that await
s until the timer for the player who is supposed to make a move runs out or until GameHub
notifies this method that a move order has been made, whichever happens first. However, I am ignorant how to implement this.
Is this the right way to go? If yes, then how am I supposed to make this method wait until the timer runs out or until a move order comes to GameHub
?
EDIT: I SUPPOSE I should write something like this:
await Task.WhenAny(
Task.Delay(players_available_time_left),
??something_to_mean_a_move_order_has_arrived??
);
- is this correct? If yes, what should I write instead of the question marks?