/** * 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.ai.nn; import org.jskat.control.JSkatThread; import org.jskat.control.SkatGame; import org.jskat.data.GameAnnouncement; import org.jskat.data.GameAnnouncement.GameAnnouncementFactory; import org.jskat.data.SkatGameData.GameState; import org.jskat.gui.NullView; import org.jskat.util.CardDeck; import org.jskat.util.CardList; import org.jskat.util.GameType; import org.jskat.util.GameVariant; import org.jskat.util.Player; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.helpers.NOPLogger; /** * Helper class for simulating games */ class GameSimulationThread extends JSkatThread { private static Logger log = LoggerFactory.getLogger(GameSimulationThread.class); private final GameType gameType; private final Player position; private final CardList cards; private final CardList skat; private Long maxEpisodes; private Long maxTimestamp; private long simulatedGames; private long wonGames; private final AIPlayerNN nnPlayer1; private final AIPlayerNN nnPlayer2; private final AIPlayerNN nnPlayer3; GameSimulationThread(final GameType pGameType, final Player playerPosition, final CardList playerHandCards, final CardList skatCards) { setName(pGameType.name()); gameType = pGameType; position = playerPosition; cards = new CardList(playerHandCards); skat = new CardList(skatCards); nnPlayer1 = new AIPlayerNN(); nnPlayer1.setIsLearning(false); nnPlayer1.setLogger(NOPLogger.NOP_LOGGER); nnPlayer2 = new AIPlayerNN(); nnPlayer2.setIsLearning(false); nnPlayer2.setLogger(NOPLogger.NOP_LOGGER); nnPlayer3 = new AIPlayerNN(); nnPlayer3.setIsLearning(false); nnPlayer3.setLogger(NOPLogger.NOP_LOGGER); } void startSimulationWithMaxEpidodes(final Long episodes) { maxEpisodes = episodes; start(); } void startSimulationWithTimestamp(final Long timestamp) { maxTimestamp = timestamp; start(); } @Override public void run() { simulateGames(); } private void simulateGames() { simulatedGames = 0; wonGames = 0; while (!isAllSimulationsDone()) { if (simulateGame()) { wonGames++; } simulatedGames++; } } private boolean isAllSimulationsDone() { if (maxEpisodes != null) { if (simulatedGames < maxEpisodes.longValue()) { return false; } } else if (maxTimestamp != null) { if (System.currentTimeMillis() < maxTimestamp.longValue()) { return false; } } log.warn(simulatedGames + " episodes simulated for game type " + gameType + ": won rate " + getWonRate() + "."); return true; } private boolean simulateGame() { SkatGame game = new SkatGame("SIM" + gameType.name(), GameVariant.STANDARD, nnPlayer1, nnPlayer2, nnPlayer3); game.setView(new NullView()); game.setLogger(NOPLogger.NOP_LOGGER); CardDeck deck = CardDeckSimulator.simulateUnknownCards(position, cards, skat); log.debug("Card deck: " + deck); //$NON-NLS-1$ game.setCardDeck(deck); game.dealCards(); game.setDeclarer(position); GameAnnouncementFactory factory = GameAnnouncement.getFactory(); factory.setGameType(gameType); game.setGameAnnouncement(factory.getAnnouncement()); game.setGameState(GameState.TRICK_PLAYING); game.start(); try { game.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // FIXME (jansch 28.06.2011) have to call getGameResult() for result // calculation game.getGameResult(); return game.isGameWon(); } long getEpisodes() { return simulatedGames; } double getWonRate() { double wonDouble = wonGames; double gameCountDouble = simulatedGames; return wonDouble / gameCountDouble; } GameType getGameType() { return gameType; } }