sunjay / reversi

Reversi implemented in Haskell as a terminal game
MIT License
4 stars 0 forks source link

"Correct" End Conditions #1

Closed sunjay closed 8 years ago

sunjay commented 8 years ago

Currently, the game ends whenever either player runs out of moves.

This is slightly different from the actual rules:

Players take alternate turns. If one player can not make a valid move, play passes back to the other player. When neither player can move, the game ends. This occurs when the grid has filled up or when neither player can legally place a piece in any of the remaining squares. This means the game may end before the grid is completely filled.

The main loop code should be adjusted to fix this. When there are no valid moves, the game's current player must be changed to the other player. Then if there are still no valid moves, the game should end.

sunjay commented 8 years ago

Note: Fixing this only in mainloop will break the AI implementation because the AI will not be able to account for this bug.

Possible fix: in the Reversi.move function, check if there are any valid moves (via not $ null xs) and if there aren't, change the current piece to the next player automatically. This should require no other changes in the mainloop or AI code.

By doing this, in the mainloop, if the check for any valid moves returns nothing, this means that both players have no moves. We just skipped one of the player's turns, so by returning no moves for the other, both players have no moves. This won't get reflected in the interface (maybe there is a way?) so that is kind of unfortunate.

In the AI code, this shouldn't matter because the current piece is taken into account in each node of the game tree. The implications of this fix still need to be explored further before its implementation can actually be accepted.

The weird thing about this bug is it makes it clear that there is a state where last move can be Nothing after the start of the game. Maybe considering that will lead to an even better solution?

sunjay commented 8 years ago

Fixed in https://github.com/sunjay/reversi/commit/c0b44edfb152340e66bf3b1c21dedc36a359482b and https://github.com/sunjay/reversi/commit/68292a0873657b4b030827af367039aa2a0491d7

Fixed this in a very Haskell way by adding a new type called ValidMoves which represents that either the turn must be skipped, or that there are zero or more valid moves.