/** * 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.apache.commons.math3.stat.descriptive.SynchronizedDescriptiveStatistics; 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.data.SkatGameResult; import org.jskat.gui.NullView; import org.jskat.player.JSkatPlayer; 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; class GameSimulation { private final static Logger LOG = LoggerFactory.getLogger(GameSimulation.class); private final GameType gameType; private final Player playerPosition; private final CardList playerCards; private final CardList skatCards; private final Statistics statistics = new Statistics(); private final JSkatPlayer player1; private final JSkatPlayer player2; private final JSkatPlayer player3; GameSimulation(GameType gameType, Player playerPosition, CardList playerCards) { this(gameType, playerPosition, playerCards, new CardList()); } GameSimulation(GameType gameType, Player playerPosition, CardList playerCards, CardList skatCards) { this.gameType = gameType; this.playerPosition = playerPosition; this.playerCards = new CardList(playerCards); this.skatCards = new CardList(skatCards); player1 = new AIPlayerNN(NOPLogger.NOP_LOGGER); player2 = new AIPlayerNN(NOPLogger.NOP_LOGGER); player3 = new AIPlayerNN(NOPLogger.NOP_LOGGER); } SkatGameResult simulateGame(String tableName) { SkatGame game = new SkatGame(tableName, GameVariant.STANDARD, player1, player2, player3); game.setView(new NullView()); game.setLogger(NOPLogger.NOP_LOGGER); CardDeck deck = CardDeckSimulator.simulateUnknownCards(playerPosition, playerCards, skatCards); LOG.debug("Simulated card deck: " + deck); //$NON-NLS-1$ game.setCardDeck(deck); game.dealCards(); game.setDeclarer(playerPosition); 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 SkatGameResult gameResult = game.getGameResult(); statistics.adjust(gameResult); return gameResult; } long getEpisodes() { return statistics.getEpisodes(); } long getWonGames() { return statistics.getWonGames(); } double getWonRate() { return statistics.getWonRate(); } long getWonGamesWithSchneider() { return statistics.getWonGamesWithSchneider(); } double getWonRateWithSchneider() { return statistics.getWonRateWithSchneider(); } long getWonGamesWithSchwarz() { return statistics.getWonGamesWithSchwarz(); } double getWonRateWithSchwarz() { return statistics.getWonRateWithSchwarz(); } double getDeclarerPointsMedian() { return statistics.getDeclarerPointsMedian(); } public GameType getGameType() { return gameType; } public CardList getSkatCards() { return new CardList(skatCards); } @Override public String toString() { return "Game simulation " + gameType + " " + statistics.getEpisodes() + " episodes"; } class Statistics { private long episodes; private long wonGames; private double wonRate; private long wonGamesWithSchneider; private double wonRateWithSchneider; private long wonGamesWithSchwarz; private double wonRateWithSchwarz; private final SynchronizedDescriptiveStatistics declarerPointsStats = new SynchronizedDescriptiveStatistics(); void adjust(SkatGameResult gameResult) { episodes++; if (gameResult.isWon()) { wonGames++; if (gameResult.isSchneider()) { wonGamesWithSchneider++; } if (gameResult.isSchwarz()) { wonGamesWithSchwarz++; } } wonRate = ((double) wonGames) / ((double) episodes); wonRateWithSchneider = ((double) wonGamesWithSchneider) / ((double) episodes); wonRateWithSchwarz = ((double) wonGamesWithSchwarz) / ((double) episodes); declarerPointsStats.addValue(gameResult.getFinalDeclarerPoints()); } long getEpisodes() { return episodes; } long getWonGames() { return wonGames; } double getWonRate() { return wonRate; } long getWonGamesWithSchneider() { return wonGamesWithSchneider; } double getWonRateWithSchneider() { return wonRateWithSchneider; } long getWonGamesWithSchwarz() { return wonGamesWithSchwarz; } double getWonRateWithSchwarz() { return wonRateWithSchwarz; } double getDeclarerPointsMedian() { return declarerPointsStats.getPercentile(50); } } }