package de.ctdo.crashtest.game; import de.ctdo.crashtest.log.Logger; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; public class Statemachine implements IStatemachine { public enum state { IDLE, ENTERED_ROOM, TABLE_GAME_ONE, TABLE_GAME_TWO, TABLE_GAME_THREE, TABLE_GAME_FOUR, TABLE_GAME_FIVE, TABLE_GAME_SIX, TABLE_GAME_DONE, ROKET_STARTED, ROKET_DONE, LOOSED } private final char RESET = '1'; private final char BLUE_BUTTON = 'E'; private final char LIGHT_BARRIER = 'F'; private final char TABLE_ONE = 'G'; private final char TABLE_TWO = 'H'; private final char TABLE_THREE = 'I'; private final char ROKET_INPUT = 'B'; private final List statemachineListenerList; private Timer timer; private long lastHandleInput; private int stateChangeCounter; private state currentState; private int timertSecondsLast; private int timertSeconds; public Statemachine() { currentState = state.IDLE; statemachineListenerList = new ArrayList(); } @Override public void addListener(StatemachineListener listener) { statemachineListenerList.add(listener); } @Override public state getCurrentState() { return currentState; } @Override public void setNewState(state newState) { currentState = newState; stateChangeCounter++; onStateChanged(); } @Override public int getStateChangeCounter() { return stateChangeCounter; } @Override public void reset() { stateChangeCounter = 0; currentState = state.IDLE; stopTimer(); onStateChanged(); } @Override public void handleInput(char input) { if(System.currentTimeMillis() - lastHandleInput < 200 ) return; state newState = getNewState(input); if( newState != currentState ) { stateChangeCounter++; currentState = newState; onStateChanged(); } lastHandleInput = System.currentTimeMillis(); } @Override public int getTimerSecondsLast() { return timertSecondsLast / 10; } @Override public int getTimerSeconds() { return timertSeconds / 10; } @Override public void startTimer(int seconds) { timertSecondsLast = seconds*10; timertSeconds = seconds*10; scheduleTimer(); } @Override public void stopTimer() { if(timer != null) timer.cancel(); timertSecondsLast = 0; timertSeconds = 0; } @Override public void pauseTimer(boolean pause) { if(pause) { if(timer != null) timer.cancel(); } else { scheduleTimer(); } } /** * notifies all listeners about the changed state */ private void onStateChanged() { for(StatemachineListener listener: statemachineListenerList) { listener.stateChanged(currentState); } } private void onTimerTick() { for(StatemachineListener listener: statemachineListenerList) { listener.timerTick(timertSecondsLast); } } /** * Calculates the new game state from the current state and new input button * @param input the char from the input * @return returns the new state */ private state getNewState(char input) { state retVal = currentState; if(input == RESET) { retVal = state.IDLE; } else { switch (currentState) { case IDLE: if(input == LIGHT_BARRIER) { retVal = state.ENTERED_ROOM; } break; case ENTERED_ROOM: if(input == TABLE_ONE) { retVal = state.TABLE_GAME_ONE; } break; case TABLE_GAME_ONE: if(input == TABLE_TWO) { retVal = state.TABLE_GAME_TWO; } break; case TABLE_GAME_TWO: if(input == TABLE_THREE) { retVal = state.TABLE_GAME_THREE; } else if (input == TABLE_ONE) { retVal = state.TABLE_GAME_ONE; } break; case TABLE_GAME_THREE: if(input == TABLE_TWO) { retVal = state.TABLE_GAME_FOUR; } else if (input == TABLE_ONE) { retVal = state.TABLE_GAME_ONE; } break; case TABLE_GAME_FOUR: if(input == TABLE_THREE) { retVal = state.TABLE_GAME_FIVE; } else if (input == TABLE_ONE) { retVal = state.TABLE_GAME_ONE; } break; case TABLE_GAME_FIVE: if(input == TABLE_ONE) { retVal = state.TABLE_GAME_SIX; } else if (input == TABLE_TWO) { retVal = state.TABLE_GAME_ONE; } break; case TABLE_GAME_SIX: if(input == TABLE_THREE) { retVal = state.TABLE_GAME_DONE; } else if (input == TABLE_TWO) { retVal = state.TABLE_GAME_ONE; } break; case TABLE_GAME_DONE: if(input == BLUE_BUTTON) { retVal = state.ROKET_STARTED; } break; case ROKET_STARTED: if(input == ROKET_INPUT) { retVal = state.ROKET_DONE; } } } return retVal; } private void scheduleTimer() { if(timer != null) timer.cancel(); timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { timertSecondsLast--; onTimerTick(); if(timertSecondsLast <= 0) { if(timer != null) timer.cancel(); } } }; timer.scheduleAtFixedRate(timerTask, 100, 100); } }