title: Solidity bug hunting
body: <p>I've got a piece of code below that attempts to implement a two-player game (with a wager on the line) of Tic-Tac-Toe, also known as Noughts and Crosses.
  It is said that this implementation contains at least 9 bugs which compromise the security of the game, but I only found one, which on line 61, I think selfdestruct() is not the way to send the pot. Can you guys find any more bugs and bring up some corresponding fixes? Any help is welcomed.</p>
  <pre><code>contract TicTacToe {
  // game configuration
  address [2] _playerAddress ; // address of both players
  uint32 _turnLength ; // max time for each turn
  
  
  // nonce material used to pick the first player
  bytes32 _p1Commitment ;
  uint8 _p2Nonce ;
  
  
  // game state
  uint8 [9] _board ; // serialized 3 x3 array
  uint8 _currentPlayer ; // 0 or 1, indicating whose turn it is
  uint256 _turnDeadline ; // deadline for submitting next move
  
  
  // Create a new game , challenging a named opponent .
  // The value passed in is the stake which the opponent must match .
  // The challenger commits to its nonce used to determine first mover .
  constructor ( address opponent , uint32 turnLength ,
  bytes32 p1Commitment ) public {
  _playerAddress [0] = msg . sender ;
  _playerAddress [1] = opponent ;
  _turnLength = turnLength ;
  _p1Commitment = p1Commitment ;
  }
  
  // Join a game as the second player .
  function joinGame ( uint8 p2Nonce ) public payable {
  // only the specified opponent may join
  if ( msg . sender != _playerAddress [1])
  revert () ;
  // must match player 1’s stake .
  require ( msg . value &gt;= this . balance ) ;
  _p2Nonce = p2Nonce ;
  }
  
  // Revealing player 1’s nonce to choose who goes first .
  function startGame ( uint8 p1Nonce ) public {
  // must open the original commitment
  require ( sha3 ( p1Nonce ) == _p1Commitment );
  // XOR both nonces and take the last bit to pick the first player
  _currentPlayer = ( p1Nonce ^ _p2Nonce ) &amp; 0 x01 ;
  
  // start the clock for the next move
  _turnDeadline = block . number + _turnLength ;
  }
  
  
  // Submit a move
  function playMove ( uint8 squareToPlay ) public {
  // make sure correct player is submitting a move
  require ( msg . sender != _playerAddress [ _currentPlayer ]) ;
  
  // claim this square for the current player .
  _board [ squareToPlay ] = _currentPlayer ;
  
  // If the game is won , send the pot to the winner
  if ( checkGameOver () )
  selfdestruct ( msg . sender );
  
  // Flip the current player
  _currentPlayer ^= 0 x1 ;
  
  // start the clock for the next move
  _turnDeadline = block . number + _turnLength ;
  }
  
  // Default the game if a player takes too long to submit a move
  function defaultGame () public {
  if ( block . number &gt; _turnDeadline )
  selfdestruct ( msg . sender );
  }
  }
  </code></pre>