/** * Copyright (C) 2017 Jan Schäfer (jansch@users.sourceforge.net) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jskat.control; import java.util.ArrayList; import java.util.List; import org.jskat.control.command.table.ShowCardsCommand; import org.jskat.control.event.skatgame.BidEvent; import org.jskat.control.event.skatgame.GameAnnouncementEvent; import org.jskat.control.event.skatgame.GameFinishEvent; import org.jskat.control.event.skatgame.GameStartEvent; import org.jskat.control.event.skatgame.SkatGameEvent; import org.jskat.control.event.skatgame.TrickCardPlayedEvent; import org.jskat.control.event.table.TableGameMoveEvent; import org.jskat.control.event.table.TrickCompletedEvent; import org.jskat.data.SkatGameData; import org.jskat.data.SkatGameData.GameState; import org.jskat.gui.JSkatView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class is used for replaying skat games */ public class SkatGameReplayer { private final static Logger LOG = LoggerFactory .getLogger(SkatGameReplayer.class); private final JSkatView view; private final String tableName; private SkatGameData data; private final List<SkatGameEvent> gameMoves = new ArrayList<>(); private int currentMove = 0; public SkatGameReplayer(JSkatView view, String tableName, List<SkatGameEvent> gameMoves) throws InterruptedException { this.view = view; this.tableName = tableName; this.gameMoves.addAll(gameMoves); resetReplay(); } public void toStart() { resetReplay(); } public void oneMoveBackward() { if (currentMove > 1) { currentMove--; gameMoves.get(currentMove).processBackward(data); } } public void oneMoveForward() { if (hasMoreMoves()) { oneStepForward(); } } public void toEnd() { while (hasMoreMoves()) { oneStepForward(); } } private void resetReplay() { currentMove = 0; data = new SkatGameData(); // game start oneStepForward(); // dealing oneStepForward(); } private boolean hasMoreMoves() { return currentMove < gameMoves.size(); } private void setGameState(SkatGameEvent event) { if (event instanceof GameStartEvent) { view.setGameState(tableName, GameState.BIDDING); } else if (event instanceof BidEvent) { view.setGameState(tableName, GameState.BIDDING); } else if (event instanceof GameAnnouncementEvent) { view.setGameState(tableName, GameState.DECLARING); } else if (event instanceof TrickCardPlayedEvent) { view.setGameState(tableName, GameState.TRICK_PLAYING); } else if (event instanceof GameFinishEvent) { view.setGameState(tableName, GameState.GAME_OVER); } } private void oneStepForward() { SkatGameEvent event = gameMoves.get(currentMove); setGameState(event); // TODO: code duplication with SkatGame.playCard() if (event instanceof TrickCardPlayedEvent && data.getCurrentTrick() != null && data.getCurrentTrick().getFirstCard() == null) { JSkatEventBus.TABLE_EVENT_BUSSES.get(tableName).post( new TrickCompletedEvent(data.getLastCompletedTrick())); } else if (event instanceof GameFinishEvent) { JSkatEventBus.INSTANCE.post(new ShowCardsCommand(tableName, data .getCardsAfterDiscard())); } event.processForward(data); JSkatEventBus.INSTANCE.post(new TableGameMoveEvent(tableName, event)); currentMove++; } }