package com.christophdietze.jack.shared.board; import com.christophdietze.jack.client.event.GameUpdatedEvent; import com.christophdietze.jack.client.util.GlobalEventBus; import com.google.inject.Inject; import com.google.inject.Singleton; /** * TODO Game is using the GlobalEventBus and is thus GWT dependent. The dependency itself might not be problematic, but * the singleton event bus could be dangerous on the server side. */ @Singleton public class Game { private GlobalEventBus eventBus; private MoveNode initialMoveNode; private MoveNode currentMoveNode; private GameMetaInfo metaInfo = new GameMetaInfo(); private GameResult gameResult; private boolean whiteAtBottom = true; @Inject public Game(GlobalEventBus eventBus) { this.eventBus = eventBus; clearAttributes(); Position initialPosition = Position.STARTING_POSITION; initialMoveNode = MoveNode.createInitialNode(initialPosition); currentMoveNode = initialMoveNode; initListeners(); } public boolean isWhiteAtBottom() { return whiteAtBottom; } public void setWhiteAtBottom(boolean whiteAtBottom) { this.whiteAtBottom = whiteAtBottom; } private void clearAttributes() { metaInfo.clear(); gameResult = GameResult.UNDECIDED; } public MoveNode getInitialMoveNode() { return initialMoveNode; } public MoveNode getCurrentMoveNode() { return currentMoveNode; } public Position getPosition() { return currentMoveNode.getPosition(); } public Position getInitialPosition() { return initialMoveNode.getPosition(); } public boolean hasPrevMove() { return currentMoveNode.hasPrev(); } public boolean hasNextMove() { return currentMoveNode.hasNext(); } public GameMetaInfo getMetaInfo() { return metaInfo; } public GameResult getGameResult() { assert gameResult != null; return gameResult; } public void clear() { clearAttributes(); clearPosition(); } public void makeMoveVerified(Move move) throws IllegalMoveException { MoveNode newNode = MoveNode.createNextNodeVerified(currentMoveNode, move); currentMoveNode = newNode; // TODO set GameResult when checkmate / stalemate occurs gameResult = GameResult.UNDECIDED; firePositionChanged(); } /** * This method is used to import moves.<br> * It does not verify the move, does not fire events. */ public void addMove(Move move) { MoveNode newNode; try { newNode = MoveNode.createNextNodeVerified(currentMoveNode, move); } catch (IllegalMoveException e) { throw new AssertionError(); } currentMoveNode = newNode; } /** * move must be a legal move */ // public void makeMove(Move move) { // currentMoveListNode = MoveListNode.createNext(position, move, // currentMoveListNode); // position.makeMove(move); // firePositionChanged(); // } public void setInitialPosition(Position initialPosition) { initialMoveNode = MoveNode.createInitialNode(initialPosition); currentMoveNode = initialMoveNode; gameResult = GameResult.UNDECIDED; firePositionChanged(); } // public void setCurrentAsInitialPosition() { // position.setFullmoveNumber(1); // this.initialPosition = position.copy(); // currentMoveListNode = MoveListNode.createRoot(position); // firePositionChanged(); // } public void setupStartingPosition() { clearAttributes(); setInitialPosition(Position.STARTING_POSITION); } public void clearPosition() { clearAttributes(); setInitialPosition(Position.EMPTY_POSITION); } public void gotoPrevMove() { assert hasPrevMove(); currentMoveNode = currentMoveNode.getPrev(); firePositionChanged(); } public void gotoNextMove() { assert hasNextMove(); currentMoveNode = currentMoveNode.getNext(); firePositionChanged(); } public void gotoFirstPosition() { currentMoveNode = initialMoveNode; firePositionChanged(); } /** * Goes to the last position of the current thread. */ public void gotoLastPosition() { while (currentMoveNode.hasNext()) { currentMoveNode = currentMoveNode.getNext(); } firePositionChanged(); } public void gotoPly(int ply) { if (ply < initialMoveNode.getPly()) { throw new RuntimeException("ply too low"); } while (ply < currentMoveNode.getPly()) { currentMoveNode = currentMoveNode.getPrev(); } while (ply > currentMoveNode.getPly()) { currentMoveNode = currentMoveNode.getNext(); } firePositionChanged(); } public void setGameResult(GameResult gameResult) { assert gameResult != null; this.gameResult = gameResult; firePositionChanged(); } // // public void addListener(GameListener listener) { // listeners.add(listener); // } private void initListeners() { metaInfo.addListener(new GameMetaInfoListener() { @Override public void onMetaInfoChanged() { firePositionChanged(); } }); } private void firePositionChanged() { eventBus.fireEvent(new GameUpdatedEvent()); // for (GameListener listener : listeners) { // listener.onPositionChanged(); // } } // private void fireMetaInfoChanged() { // for (GameListener listener : listeners) { // listener.onMetaInfoChanged(); // } // } // public HandlerRegistration addGameUpdatedEventHandler( // GameUpdatedEventHandler handler) { // return handlerManager.addHandler(GameUpdatedEvent.TYPE, handler); // } }