Android Open Source - DistributedMemory Client Game Manager






From Project

Back to project page DistributedMemory.

License

The source code is released under:

Apache License

If you think the Android project DistributedMemory listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.faudroids.distributedmemory.core;
/*from  www .java  2 s  .c o m*/
import android.os.Handler;
import android.os.Looper;

import com.fasterxml.jackson.databind.JsonNode;

import org.faudroids.distributedmemory.network.ConnectionHandler;
import org.faudroids.distributedmemory.utils.Assert;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Singleton;

import timber.log.Timber;


@Singleton
public final class ClientGameManager implements ConnectionHandler.MessageListener<JsonNode> {

  private final GameStateManager gameStateManager;

  private final Map<Integer, Card> closedCards = new HashMap<>();
  private final Map<Integer, Card> matchedCards = new HashMap<>();
  private final Map<Integer, Card> selectedCards = new HashMap<>();

    private int currentPlayerIdx;
  private final List<Player> players = new LinkedList<>();
  private final List<Integer> playerPoints = new LinkedList<>();

  private final MessageWriter messageWriter;
  private final MessageReader messageReader;
  private ConnectionHandler<JsonNode> connectionHandler;
  private Device device;

  private final List<ClientGameListener> clientGameListeners = new LinkedList<>();

  // used to delay actions that should run on the main (UI) thread
  private final Handler handler = new Handler(Looper.getMainLooper());

  @Inject
  public ClientGameManager(GameStateManager gameStateManager, MessageWriter messageWriter, MessageReader messageReader) {
    this.gameStateManager = gameStateManager;
    this.messageWriter = messageWriter;
    this.messageReader = messageReader;
  }


  public void initGame() {
    gameStateManager.reset();
    closedCards.clear();
    matchedCards.clear();
    selectedCards.clear();
  }


  /**
   * Registers the local device with this manager.
   * Call in state {@link GameState#CONNECTING}.
   */
  public void registerDevice(ConnectionHandler<JsonNode> connectionHandler, String deviceName, int pairsCount) {
    assertValidState(GameState.CONNECTING);

    this.connectionHandler = connectionHandler;
    this.device = new Device(deviceName, pairsCount);

    connectionHandler.registerMessageListener(this, new Handler(Looper.myLooper()));
    connectionHandler.start();
  }


  /**
   * Returns the current player or null if the game has not yet started.
   */
  public Player getCurrentPlayer() {
    if (players.isEmpty()) return null;
    return players.get(currentPlayerIdx);
    }


  public GameState getCurrentState() {
    return gameStateManager.getState();
  }


  public Map<Integer, Card> getClosedCards() {
    return closedCards;
  }


  public Map<Integer, Card> getMatchedCards() {
    return matchedCards;
  }


  public Map<Integer, Card> getSelectedCards() {
    return selectedCards;
  }


  public List<Player> getPlayers() {
    return players;
  }


  public List<Integer> getPlayerPoints() {
    return playerPoints;
  }


  public void stopGame() {
    if (connectionHandler != null) connectionHandler.stop();
  }


  public void registerClientGameListener(ClientGameListener listener) {
    Assert.assertTrue(!clientGameListeners.contains(listener), "already registered");
    clientGameListeners.add(listener);
  }


  public void unregisterClientGameListener(ClientGameListener listener) {
    Assert.assertTrue(clientGameListeners.contains(listener), "not registered");
    clientGameListeners.remove(listener);
  }


  public void selectCard(int cardId) {
    connectionHandler.sendMessage(messageWriter.createCardIdMessage(cardId));
    // update local card maps only when receiving confirmation from host
  }


  @Override
  public void onNewMessage(JsonNode msg) {
    Timber.d("received msg from host" + msg);
    if (messageReader.isBackoffMessage(msg)) {
      for (ClientGameListener listener : clientGameListeners) listener.onHostBusy();
      return;
    }

    switch(gameStateManager.getState()) {
      case CONNECTING:
        connectionHandler.sendMessage(messageWriter.createDeviceInfoMessage(device));
        gameStateManager.changeState(GameState.SETUP);
        break;

      case SETUP:
        GameSetupInfo setupInfo = messageReader.readSetupMessage(msg);
        for (Map.Entry<Integer, Integer> entry : setupInfo.getCards().entrySet()) {
          Card card = new Card(entry.getKey(), entry.getValue());
          closedCards.put(card.getId(), card);
        }

        currentPlayerIdx = setupInfo.getStartingPlayerIdx();
        players.clear();
        players.addAll(setupInfo.getPlayers());
        for (int i = 0; i < players.size(); ++i) playerPoints.add(0);

                connectionHandler.sendMessage(messageWriter.createAck());
        for (ClientGameListener listener : clientGameListeners) listener.onGameStarted();
        gameStateManager.changeState(GameState.SELECT_1ST_CARD);
        for (ClientGameListener listener : clientGameListeners) listener.onNewRound(players.get(currentPlayerIdx), playerPoints.get(currentPlayerIdx));
        break;

      case SELECT_1ST_CARD:
        int card1Id = messageReader.readCardIdMessage(msg);
        if (closedCards.containsKey(card1Id)) selectedCards.put(card1Id, closedCards.remove(card1Id));
        Timber.d("selected first card with id " + card1Id);
        connectionHandler.sendMessage(messageWriter.createAck());
        gameStateManager.changeState(GameState.SELECT_2ND_CARD);
        break;

      case SELECT_2ND_CARD:
        int card2Id = messageReader.readCardIdMessage(msg);
        if (closedCards.containsKey(card2Id)) selectedCards.put(card2Id, closedCards.remove(card2Id));
        Timber.d("selected second card with id " + card2Id);
        connectionHandler.sendMessage(messageWriter.createAck());
        gameStateManager.changeState(GameState.UPDATE_CARDS);
        break;

      case UPDATE_CARDS:
                Timber.d("Result: " + msg);
        Evaluation evaluation = messageReader.readEvaluation(msg);

        // update players
        currentPlayerIdx = evaluation.getNextPlayerId();
        playerPoints.clear();
        playerPoints.addAll(evaluation.getPlayerPoints());

        // update cards
        if (evaluation.getCardsMatched()) {
          if (!selectedCards.isEmpty()) {
            for (ClientGameListener listener : clientGameListeners) listener.onCardsMatch(new LinkedList<>(selectedCards.values()));
            matchedCards.putAll(selectedCards);
            selectedCards.clear();
          }
        } else {
          if (!selectedCards.isEmpty()) {
            for (ClientGameListener listener : clientGameListeners) listener.onCardsMismatch(new LinkedList<>(selectedCards.values()));
            closedCards.putAll(selectedCards);
            selectedCards.clear();
          }
        }

        // change state
        if (!evaluation.getContinueGame()) {
          gameStateManager.changeState(GameState.FINISHED);
          for (ClientGameListener listener : clientGameListeners) listener.onGameFinished();
          // delay closing of connection such that server can receive ack
          handler.postDelayed(new Runnable() {
            @Override
            public void run() {
              stopGame();
            }
          }, 100);
        } else {
          gameStateManager.changeState(GameState.SELECT_1ST_CARD);
          for (ClientGameListener listener : clientGameListeners) listener.onNewRound(players.get(currentPlayerIdx), playerPoints.get(currentPlayerIdx));
        }

        connectionHandler.sendMessage(messageWriter.createAck());
        break;
    }
  }


  @Override
  public void onConnectionError() {
    // if already finished this is expected as connections are being closed
    if (gameStateManager.getState() == GameState.FINISHED) return;
    gameStateManager.setEndState();
    for (ClientGameListener listener : clientGameListeners) listener.onHostLost();
  }


  private void assertValidState(GameState state) {
    if (!gameStateManager.getState().equals(state)) throw new IllegalStateException("must be in state " + state + " to perform this action");
  }

}




Java Source Code List

org.faudroids.distributedmemory.ApplicationTest.java
org.faudroids.distributedmemory.app.AppModule.java
org.faudroids.distributedmemory.app.DistributedMemoryApplication.java
org.faudroids.distributedmemory.common.BaseActivity.java
org.faudroids.distributedmemory.common.BaseApplication.java
org.faudroids.distributedmemory.common.BaseListActivity.java
org.faudroids.distributedmemory.common.BaseService.java
org.faudroids.distributedmemory.common.CommonModule.java
org.faudroids.distributedmemory.common.Injector.java
org.faudroids.distributedmemory.core.Card.java
org.faudroids.distributedmemory.core.ClientGameListener.java
org.faudroids.distributedmemory.core.ClientGameManager.java
org.faudroids.distributedmemory.core.CoreModule.java
org.faudroids.distributedmemory.core.Device.java
org.faudroids.distributedmemory.core.Evaluation.java
org.faudroids.distributedmemory.core.GameSetupInfo.java
org.faudroids.distributedmemory.core.GameStateManager.java
org.faudroids.distributedmemory.core.GameState.java
org.faudroids.distributedmemory.core.HostGameListener.java
org.faudroids.distributedmemory.core.HostGameManager.java
org.faudroids.distributedmemory.core.HostGameStateManager.java
org.faudroids.distributedmemory.core.HostStateTransitionListener.java
org.faudroids.distributedmemory.core.HostStateTransition.java
org.faudroids.distributedmemory.core.MessageConstants.java
org.faudroids.distributedmemory.core.MessageReader.java
org.faudroids.distributedmemory.core.MessageWriter.java
org.faudroids.distributedmemory.core.Player.java
org.faudroids.distributedmemory.network.BroadcastMessage.java
org.faudroids.distributedmemory.network.ClientNetworkListener.java
org.faudroids.distributedmemory.network.ConnectionHandlerFactory.java
org.faudroids.distributedmemory.network.ConnectionHandler.java
org.faudroids.distributedmemory.network.HostInfo.java
org.faudroids.distributedmemory.network.HostNetworkListener.java
org.faudroids.distributedmemory.network.HostSocketHandler.java
org.faudroids.distributedmemory.network.JsonConnectionHandler.java
org.faudroids.distributedmemory.network.NetworkManager.java
org.faudroids.distributedmemory.network.NetworkModule.java
org.faudroids.distributedmemory.network.StringConnectionHandler.java
org.faudroids.distributedmemory.ui.AboutActivity.java
org.faudroids.distributedmemory.ui.BitmapCache.java
org.faudroids.distributedmemory.ui.ClientUtils.java
org.faudroids.distributedmemory.ui.GameActivity.java
org.faudroids.distributedmemory.ui.HelpActivity.java
org.faudroids.distributedmemory.ui.HelpDialogActivity.java
org.faudroids.distributedmemory.ui.HostGameActivity.java
org.faudroids.distributedmemory.ui.HostService.java
org.faudroids.distributedmemory.ui.JoinGameActivity.java
org.faudroids.distributedmemory.ui.LobbyActivity.java
org.faudroids.distributedmemory.ui.MainActivity.java
org.faudroids.distributedmemory.ui.QRCodeUtils.java
org.faudroids.distributedmemory.ui.StopServerBroadcastReceiver.java
org.faudroids.distributedmemory.ui.UiModule.java
org.faudroids.distributedmemory.utils.Assert.java
org.faudroids.distributedmemory.utils.NotificationUtils.java
org.faudroids.distributedmemory.utils.QRCodeEncoder.java
org.faudroids.distributedmemory.utils.ServiceUtils.java
org.faudroids.distributedmemory.utils.UtilsModule.java