Game-Apps für Smartphones und Tablets |
|
Bern University oh Teacher Education |
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.
|
![]() |
|
|
// 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, GGTouchListener, GGSoftButtonListener { 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(this, GGTouch.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 k = 0; k < nbRows; k++) { for (int i = 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 x = loc.x; int y = 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) { } } |