2

I'm trying to make a simple text turn-based game in node.js using the socket.io module. The player must have a timeout to send the text during his turn. If he fails to do so, he loses the opportunity and now is the turn of the next player.

The timeout is my real problem here. I did some simple setTimeout to advance the turns, like this:

var playerIndex = 0;
var timer = setTimeout(advancePlayer, turnTime);

function advancePlayer() {
    playerIndex = (playerIndex + 1) % numPlayers;

    // Warns the players about whose turn is now:
    aknowledgeTurn(playerIndex);

    timer = setTimeout(advancePlayer, turnTime);
}

The problem is that when the player send his text, I need to check first that it's his turn (and that is a related issue, as I'm not sure how to share the game instance/data across all players, and for now I'm using a database) and this could take enough time to the timer run out and call the next turn, making the move invalid or maybe jumping the next player's turn, because as soon as the text is received, the timer should stop and the turn should advance.

If I just clear the timeout before checking if the move is valid, I don't know how to resume the timer in case of an invalid message (i.e. the player sent a text outside his turn, maybe by fiddling with the client code/console).

How can I close that timeout when the player sends the message without falling into these problems?

George Marques
  • 820
  • 7
  • 21

1 Answers1

3

When you receive a move, you can cancel the current timer with clearTimeout(timer).

Then after you've processed that player's move, just call advancePlayer() from your move handler code. This will advance to the next player and set a new timer.

itsananderson
  • 783
  • 5
  • 9
  • That would be fine in a perfect world, but what if the wrong player sent the message, how would I resume the previous timeout? In this case I can't just go to the next turn. – George Marques Apr 13 '14 at 17:42
  • Wrap all your message handler code (including `clearTimeout(timer)` in a player check like `if (message.playerId === players[playerIndex].id)`. Just modify that use the correct variables to compare the message's player id with the current turn's player id. – itsananderson Apr 13 '14 at 17:47
  • Yes, I think this is the answer. I'm still worried about some edge case (like when the player sends the data in the last second), but I guess I'll have to test it live to see if this will happen. Thanks a lot! – George Marques Apr 13 '14 at 18:52