Game-Apps für Smartphones und Tablets

Bern University oh Teacher Education  
HomeOnline-Editor startenDruckenAndroid-TurtlegrafikJava-Online

TCP PearlGame

Pearl Game ist eine Erweiterung des Nimspiels. Die Gewinnstrategie lässt sich aber nicht mehr so einfach ermitteln. Zu Beginn sind 18 Perlen in 4 Reihen angeordnet. Der erste Spieler entfernt mit Berührung (Mausklick) eine beliebige Anzahl Perlen allerdings nur aus der gleichen Reihe und drückt anschliessend den Ok-Button. Danach kommt der zweite Spieler zum Zug. Wer die letzte Perle entfernen muss, hat verloren.

Unser Tcp PearlGame ermöglicht zwei Spielern, die sich mit der gleichen SessionID anmelden, über das Internet zu spielen. Die Verwaltung der Session ID's übernimmt unser TcpRelay Server, somit können mehrere Spielgruppen gleichzeitig spielen. Die Kommunikation erfolgt mit Hilfe von zwei TcpNodes.



Beispiel im Online-Editor bearbeiten

App installieren auf Smartphone oder Tablet

 

QR-Code

Programmcode herunterladen (TcpPearlGame.zip)

 


Programmcode:

// TcpPearlGame.java

package app.tcppearlgame;

import ch.aplu.android.*;
import ch.aplu.tcp.*;
import ch.aplu.util.Monitor;
import android.graphics.Color;

public class TcpPearlGame extends GameGrid implements TcpNodeListener,
  GGTouchListenerGGSoftButtonListener
{
  interface Command
  {
    char change = 'c'// change player
    char move = 'm'// move pearl
    char over = 'o'// game over
    char start = 's'// start game
    char terminate = 't'// terminate game
  }
  private String roomID = "";
  private TcpNode node = new TcpNode();
  private final static int size = 6;
  private boolean isMyMove = false;
  private int activeRow;
  private int nbPearl = 0;
  private String sessionID = "$xx";
  private final String nickname = "pearl";
  private int nbTakenPearl = 0;
  private int nbRows = 4;
  private final String moveInfo = "Remove any pearls and press Ok.";

  public TcpPearlGame()
  {
    super(size, size, cellZoom(55));
    setScreenOrientation(FIXED);
    addSoftButton(0, "Ok");
    addSoftButton(1, "New");
  }

  public void main()
  {
    getBg().clear(Color.rgb(80, 15, 247));
    addTouchListener(thisGGTouch.click);
    addSoftButtonListener(this);
    init();
    node.addTcpNodeListener(this);
    showToast("Connecting to relay...");
    connect();
    Monitor.putSleep(4000);
    if (node.getNodeState() == TcpNodeState.CONNECTED)
    {
      setStatusText("Connection established.");
    }
    else
      setStatusText("Connection failed");
  }

  public void init()
  {
    int nb = 6;
    for (int = 0; k < nbRows; k++)
    {
      for (int = 0; i < nb; i++)
      {
        Actor pearl = new Actor("pearl");
        addActor(pearl, new Location(i, k + 1));
        nbPearl++;
      }
      nb--;
    }
    activeRow = -1;
    nbTakenPearl = 0;
    refresh();
  }

  private void connect()
  {
    while (roomID.length() < 3)
    {
      roomID = requestEntry("Enter room name (more than 2 characters):");
      if (roomID == null)
      {
        showToast("User canceled");
        TcpTools.delay(4000);
        System.exit(1);
      }
    }
    sessionID = sessionID + roomID;
    node.connect(sessionID, nickname);
  }

  private String requestEntry(String prompt)
  {
    return GGInputDialog.show("TcpPearlGame"prompt, "");
  }

  public void nodeStateChanged(TcpNodeState state)
  {
    if (state == TcpNodeState.DISCONNECTED)
      setStatusText("Connection broken.");
  }

  public boolean touchEvent(GGTouch touch)
  {
    if (!isMyMove)
      return true;

    Location loc = toLocationInGrid(touch.getX(), touch.getY());
    int = loc.x;
    int = loc.y;
    if (activeRow != -1 && activeRow != y)
      showToast("You must remove pearls from the same row");
    else
    {
      Actor actor = getOneActorAt(loc);
      if (actor != null)
      {
        actor.removeSelf();
        nbPearl--;
        // +1 adapt to pc-version
        node.sendMessage("" + Command.move + (x + 1) + y);
        activeRow = y;
        nbTakenPearl++;
        System.out.println("nbPearl " + nbPearl);
        if (nbPearl == 0)
        {
          setStatusText("Press 'New Game' to play again.");
          showToast("You lost!");
          node.sendMessage("" + Command.over);
          isMyMove = false;
        }
      }
    }
    refresh();
    return true;
  }

  public void messageReceived(String sender, String text)
  {
    char command = text.charAt(0);
    switch (command)
    {
      case Command.start:
        init();
        if (isMyMove)
        {
          setStatusText("" + moveInfo);
        }
        else
        {
          setStatusText("Wait to play.");
        }
        break;
      case Command.terminate:
        setStatusText("Partner disconnected");
        TcpTools.delay(4000);
        System.exit(0);
        break;
      case Command.move:
        removeActors(TextActor.class);
        // -1 adapt to android version
        int x = text.charAt(1) - 48 - 1; // We get ASCII code of number
        int y = text.charAt(2) - 48;
        Location loc = new Location(x, y);
        getOneActorAt(loc).removeSelf();
        nbPearl--;
        break;
      case Command.over:
        setStatusText("Press 'New Game' to play again.");
        showToast("You won!");
        isMyMove = true;
        break;
      case Command.change:
        isMyMove = true;
        setStatusText(moveInfo);
        showToast("Play");
        nbTakenPearl = 0;
        activeRow = -1;
        break;
    }
    refresh();
  }

  public void statusReceived(String text)
  {
    System.out.println("Status: " + text);
    if (text.contains("In session:--- (0)"))
    {
      showToast("Connected. Waiting for a partner...");
      addActor(new TextActor("Waiting in room " + roomID, Color.BLACK,
        Color.TRANSPARENT, 18), new Location(0, 0));
    }
    else if (text.contains("In session:--- (1)"))
    {
      isMyMove = true// Second player starts
      showToast("Partner connected" + (isMyMove ? " Play" : " Wait"));
      removeActors(TextActor.class);
    }
    else if (text.contains("In session:--- ")// third or more
    {
      showToast("Game in progress. Terminating now...");
      TcpTools.delay(4000);
      System.exit(0);
    }
    else if (text.equals("Disconnected:---pearl") || 
             text.equals("Disconnected:---pearl(1)")
    {
      showToast("Partner disconnected...");
      TcpTools.delay(4000);   
    }
  }

  public void buttonClicked(int button)
  {
    if (!isMyMove)
    {
      showToast("Wait to play");
      return;
    }
    switch (button)
    {
      case 0: // ok button
        if (nbTakenPearl == 0)
          showToast("You must remove at least 1 pearl.");
        else
        {
          isMyMove = false;
          node.sendMessage("" + Command.change);
          setStatusText(nbPearl + " pearls remaining.");
        }
        break;
      case 1: // new game button
        if (nbPearl > 0)
        {
          showToast("You must first finish this game!");
          return;
        }
        init();
        node.sendMessage("" + Command.start);
        if (isMyMove)
        {
          setStatusText("Game started. " + moveInfo);
        }
        else
        {
          setStatusText("Game started. Wait for the partner's move.");
        }
        break;
    }
  }

  public void buttonPressed(int arg0)
  {
  }

  public void buttonReleased(int arg0)
  {
  }

  public void buttonRepeated(int arg0)
  {
  }
}