See on konkreetne näide. Käsitsi tehtud, kohati ei vasta pakutud skeemile. Lõpus on lähtetekst (plain). Ilmselt tahavad reavahed sättimist.


[Sketch0]



[Sketch0.0.0] RingMaster




[Sketch0.0.0.0.0] RingMaster




[Sketch0.0.0.0.1]getGameParameters




[Sketch0.0.0.0.2] getRoster




[Sketch0.0.0.0.3]getGameNumber




[Sketch0.0.0.0.4]waitForFirstPlayer




[Sketch0.0.0.0.5]waitForFirstPlayer




[Sketch0.0.0.0.6]ready




[Sketch0.0.0.0.7]isCountingDown




[Sketch0.0.0.0.8] isRegistering




[Sketch0.0.0.0.9]isCheckingForWinner




[Sketch0.0.0.0.10]gameInProgress




[Sketch0.0.0.0.11]startCountDown




[Sketch0.0.0.0.12]startGame




[Sketch0.0.0.0.13] setCheckingForWinner




[Sketch0.0.0.0.14]setGameResumed




[Sketch0.0.0.0.15] setGameOver




[Sketch0.0.0.0.16]signTheCards






[Sketch0.0.0.0.17] verify




[*:Sketch0.0.0.0.17.0.1:]




[*:Sketch0.0.0.0.17.0.1.0.0:]



[:Sketch0.0.0.0.4.0.0:]wait



[:Sketch0.0.0.0.5.0.0:]wait



[!!|Sketch0.0.0.0.4.0.0.0.0]





[!!|Sketch0.0.0.0.5.0.0.0.0]





[!!|Sketch0.0.0.0.16.0.0]





[Sketch0.0.0.0.22]statusString

class RingMaster implements States { private SocketGate socketGate; private GameParameters gameParameters; private NotaryPublic notary; private Roster roster; private Stack announcedBalls; private int gameNumber = 0; private int state = BEFOREINITIALIZATION; RingMaster() throws java.io.IOException { socketGate = new SocketGate(); gameParameters = new GameParameters(); notary = new NotaryPublic(); roster = new Roster(); announcedBalls = new Stack(); announcedBalls.push(new BingoBall(BingoBall.FREE_SPACE)); } GameParameters getGameParameters() { return gameParameters; } Roster getRoster() { return roster; } int getGameNumber() { return gameNumber; } synchronized void waitForFirstPlayer() { gameNumber++; state = WAITING; socketGate.sendGameStatusMessage(statusString()); while (state == WAITING) { try { wait(); } catch (InterruptedException e) { } } socketGate.sendGameStatusMessage("Beginning count down ... "); } synchronized void waitForGameToEnd() { while (gameInProgress()) { try { wait(); } catch (InterruptedException e) { } } } boolean ready() { return (state == BEFOREINITIALIZATION) ? false : true; } boolean isCountingDown() { return (state == COUNTINGDOWN) ? true : false; } synchronized boolean isRegistering() { return (state == WAITING || state == COUNTINGDOWN) ? true : false; } boolean isCheckingForWinner() { return (state == CHECKINGFORWINNER) ? true : false; } synchronized boolean gameInProgress() { return (state == PLAYING || state == CHECKINGFORWINNER) ? true : false; } synchronized void startCountDown() { state = COUNTINGDOWN; notifyAll(); } void startGame() { state = PLAYING; socketGate.sendGameStatusMessage("Game Starting..."); } void setCheckingForWinner() { state = CHECKINGFORWINNER; } synchronized void setGameResumed() { if (state == CHECKINGFORWINNER) state = PLAYING; } synchronized void setGameOver() { state = GAMEOVER; announceBall(new BingoBall(BingoBall.GAME_OVER)); announcedBalls.removeAllElements(); announcedBalls.push(new BingoBall(BingoBall.FREE_SPACE)); roster.removeAllElements(); notifyAll(); } void signTheCards(Card[] cards) { try { for (int i = 0; i < cards.length; i++) notary.signTheCard(cards[i], gameNumber); } catch (Exception e) { // PENDING: can't sign the cards, what to do? } } boolean verify(Card c) { int colMatches = 0; int rowMatches = 0; int diagMatches = 0; int otherDiagMatches = 0; if (!(notary.verifyTheSignature(c, gameNumber))) return false; for (int i = 0; i < Card.SIZE; i ++) { for (int j = 0; j < Card.SIZE; j ++) { if (announcedBalls.contains(c.boardValues[i][j])) rowMatches ++; if (announcedBalls.contains(c.boardValues[j][i])) colMatches ++; if ((i == j) && announcedBalls.contains(c.boardValues[i][j])) diagMatches ++; if (((i + j) == (Card.SIZE-1)) && announcedBalls.contains(c.boardValues[j][i])) otherDiagMatches ++; } if (colMatches == Card.SIZE) { return true; } else if (rowMatches == Card.SIZE) { return true; } else { rowMatches = 0; colMatches = 0; } } if (diagMatches == Card.SIZE) { return true; } else if (otherDiagMatches == Card.SIZE) { return true; } return false; } void announceBall(BingoBall b) { socketGate.sendBall(b); socketGate.sendGameStatusMessage(statusString()); announcedBalls.push(b); } void sendTimeRemainingMessage(int timeRemaining) { socketGate.sendGameStatusMessage(statusString(timeRemaining)); } void sendPlayerStatusMessage(PlayerRecord p) { socketGate.sendPlayerStatusMessage(p); } String statusString() { return statusString(-1); } private String statusString(int anArgument) { switch (state) { case BEFOREINITIALIZATION: return "The BINGO server isn't ready yet."; case WAITING: return "Waiting for first player to register for game # " + gameNumber + "."; case COUNTINGDOWN: return "Game # " + gameNumber + " starts in " + anArgument + " seconds."; case PLAYING: return "Game #" + gameNumber + " in progress. " + announcedBalls.size() + " balls announced."; case CHECKINGFORWINNER: return "Game paused while checking for winner." + announcedBalls.size() + " balls announced."; case GAMEOVER: return "Game over."; default: return "Nuttin'."; } } }