Previous Cycle
Next Cycle
Back to Exercise Overview

Cycle 6: Restrict player, find loser and terminate game

In the last cycle two remaining problems need to be solved. First, according to the game rules, we must restrict the players to pick the cards only from the partner sitting to the right. Second we must handle the game over situation when one of the players has only the ugly card.

Because every player instance has the full game state information, both problems can be solved without a server intervention. To let the player only select cards from his/her right hand partner, we add some additional code at the beginning of the CardTable's leftDoubleClicked() callback, to return immediately when the card does not belong to the player sitting to the right. Because the current player always has handId = 0, the partner to the right has handId = nbPlayers - 1. But we have to be careful and check if he/she is not already dropped out. So we search anti-clockwise for the first player still in the game and check if this is the player the clicked card belongs to. Now that we know what to do, the code is straightforward:

// Search anti-clockwise the id of the first hand that is not empty
int rightHandId = nbPlayers - 1;
while (hands[rightHandId].getNumberOfCards() == 0)
  rightHandId--;

// Quit if not the hand of the clicked card
if (rightHandId != toHandId(getPlayerId(card)))
  return;

The game over situation can be checked locally without any server intervention. To do this, we add a checkOver() method in the class GameTable. As you see, we announce the game over situation twice: once by showing an actor image in the center of the game table and once by displaying the name of the loser in the status bar. We then stop any further actions by calling doPause():

protected boolean checkOver()
{
  for (int i = 0; i < nbPlayers; i++)
  {
    if (hands[i].getNumberOfCards() == 1)
    {
      Card card = hands[i].getFirst();
      if (card.equals(blackPeter))
      {
        card.setVerso(false);
        addActor(new Actor("sprites/gameover.gif"), textLocation);
        setStatusText("Game over. Loser is player: " 
          + playerNames[toPlayerId(i)]);
        doPause();
        return true;
      }
    }
  }
  return false;
}

It is your work to find out where to put the invocation of checkOver(). Here a hint: The check must be performed for both kinds of players: For the player that just picked a card and for all waiting players after the card pairs are moved to the stock.

Congratulations for your work!

(If you need some more work, try to solve Cycle 7).

Execute the solution you should obtain.

Previous Cycle
Next Cycle
Back to Exercise Overview