package bingo.game;
import java.util.Stack;
import bingo.shared.*;
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'.";
}
}
}
|