Next Cycle

Previous Cycle
Back to Exercise Overview

Cycle 3: Move partner's cards

When the player makes a draw, his/her selected card is moved to his/her hand and pairs are moved to the stock. This game state modification must be transmitted to all other players and the corresponding card transfer must be performed. It is evident how to proceed: We add two commands in the command list found in Command.java:

int TRANSFER_TO_PLAYER = 5;
int TRANSFER_TO_STOCK = 6;

When the player makes his/her selection by double-clicking on a card, the CardTable leftDoubleClicked() callback is called. Here we add a line to send the draw information containing the id of the card owner, the id of the current player and the card number to the game server.

public void leftDoubleClicked(Card card)
{
  agent.sendCommand("", Command.TRANSFER_TO_PLAYER,
    getPlayerId(card), myPlayerId, card.getCardNumber());
  ...
}    

The callback delivers the card reference of the selected card, but we need the player id of the card owner. This is done by the method getPlayerId(Card card) that searches the given card in the card list of every player. Because the class Card overrides equals() and compares suit and rank, we can use the ArrayList.contains() method to find the owner:

private int getPlayerId(Card card)
{
  for (int i = 0; i < nbPlayers; i++)
  {
    if (hands[i].getCardList().contains(card))
      return toPlayerId(i);
  }
  return -1;
}

Simularly we transmit the TRANFER_TO_STOCK information to the server (and from there to the waiting players) just before performing the stock transfer in the current player's hand. Only the current player id and the card number are needed:

for (Card c : searchPairs(hands[0]))
{
  agent.sendCommand("", Command.TRANSFER_TO_STOCK, myPlayerId,
    c.getCardNumber());
  ...
}    

The transfer is done in the GameTable class by calling the methods transferToPlayer() and transferToStock() whose implementation is your main work in this cycle. We just give a skeleton that writes method parameters to the console:

protected void transferToPlayer(int sourceId, int destId, int cardNb)
{
  System.out.println("ToDo: transferToPlayer(" + sourceId + ", "
    + destId + ", " + cardNb + ")");
}

protected void transferToStock(int playerId, int cardNb)
{
  System.out.println("ToDo: transferToStock(" + playerId + ", " 
    + cardNb + ")");
}

Finally the server must pipe the TRANSFER_TO_PLAYER and TRANSFER_TO_STOCK information received from the current player to all waiting players. Because the class Server maintains a list of all players, this is an easy task:

case Command.TRANSFER_TO_PLAYER:
  for (String player : playerList)
  {
    if (!player.equals(source))
    {
      sendCommand("", player, Command.TRANSFER_TO_PLAYER,
        indata[1], indata[2], indata[3]);
      System.out.println("Sent TRANSFER_TO_PLAYER to " + player);
    }
  }
  break;
 
case Command.TRANSFER_TO_STOCK:
  for (String player : playerList)
  {
    if (!player.equals(source))
    {
    sendCommand("", player, Command.TRANSFER_TO_STOCK,
            indata[1], indata[2]);
      System.out.println("Sent TRANSFER_TO_STOCK to " + player);
    }
  }
  break;

In this cycle your work is to put these code segments into your existing code.


Execute the solution you should obtain.

Next Cycle
Previous Cycle
Back to Exercise Overview