Project 2 bug-fixes explained

sacrifice move bug

Some quibbling has been heard regarding the possibility of losing after making a sacrafice move. The scenario is that your player, x for example, makes a move to block y, but in doing so x blocks his own future moves. Now neither player can move! Here are some pictures of the scenario on a simplified board.


 X makes a "sacrafice" move
* * * * *          * * * * *
* - * O *          * - * O *
* - X - *   ===>   * - * X *
* - * * *          * - * * *
* * * * *          * * * * *

In the original implementation, the game checked first if player 1, X, had lost and then if player 2, O, had lost. In this scenario since neither player can move X would have lost simply due to the order in which the game checked the players abilities to move. Shame on X for blocking himself in!

The revised game code, checks first for the situation where neither player can move. If this is the case, then the last player must have made a sacrafice move, otherwise there is no way to achieve a board state where neither player can move. In this situation the game decides that the player who's turn is next is the loser. In the above example O would lose under this revision.

time switch bug

Another bug has been found in the code. This one is fairly simple in that when the players switch on the board, their remaining time counts were not switched. This would allow a player to simply waste a large amount of time in the first 10 moves, thus leaving no time for his opponent after the switch. This was not the intended behavior. The code has been edited to switch the times along with the player functions, so that the time remaining is consistent for each player even after the switch takes place.

switch-/loser- check ordering bug

There have been questions about the specifics of the bug-fix that I mentioned yesterday. This fix was aimed at resolving an unfairness in the game playing code, which gave the second player an advantage over the first player in one particular scenario of game play. If you think your player may have been trying to exploit this unfairness or you're just interested then please read on for the specific details.

The issue centered around the order in which the game code administered the game. Here is a high-level overview of what happened each round:

  1. switch players if its beginning of round 11
  2. see if anyone has lost
  3. let first player make a move
  4. switch players if it’s the beginning of round 11
  5. see if anyone has lost
  6. let second player move
  7. update round number and goto 1

This created an unfairness for the first player. Consider the scenario where a player blocks himself on round 10. If the first player does this the check in step 5 makes him the loser. If the second player does this, the players switch in step 1 and the first player is again deemed the loser in step 2.

The solution that has been implemented in the new version of isolation.lisp simply changes the ordering of events such that the game consistently checks for losing players first and then tries to switch sides. Specifically swap steps 1 and 2 and swap steps 4 and 5. Then the same scenario results in both players losing if they box themselves in at the round just before the break.