package net.demilich.metastone.gui.simulationmode; import java.io.IOException; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; import net.demilich.metastone.NotificationProxy; import org.apache.commons.lang3.time.DurationFormatUtils; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.BorderPane; import net.demilich.metastone.GameNotification; import net.demilich.metastone.game.cards.Card; import net.demilich.metastone.game.cards.CardCatalogue; import net.demilich.metastone.game.cards.CardType; import net.demilich.metastone.game.logic.GameLogic; import net.demilich.metastone.game.statistics.GameStatistics; import net.demilich.metastone.game.statistics.Statistic; public class SimulationResultView extends BorderPane { private static String getStatName(Statistic stat) { switch (stat) { case ARMOR_GAINED: return "Armor gained"; case CARDS_DRAWN: return "Cards drawn"; case CARDS_PLAYED: return "Cards played"; case DAMAGE_DEALT: return "Damage dealt"; case FATIGUE_DAMAGE: return "Fatigue damage"; case GAMES_LOST: return "Games Lost"; case GAMES_WON: return "Games won"; case HEALING_DONE: return "Healing done"; case HERO_POWER_USED: return "Hero power used"; case MANA_SPENT: return "Mana spent"; case MINIONS_PLAYED: return "Minions played"; case SPELLS_CAST: return "Spells cast"; case TURNS_TAKEN: return "Turns taken"; case WEAPONS_EQUIPPED: return "Weapons equipped"; case WIN_RATE: return "Win rate"; default: break; } return stat.toString(); } @FXML private BorderPane infoArea; @FXML private TableView<StatEntry> absoluteResultTable; @FXML private TableView<StatEntry> averageResultTable; @FXML private Button doneButton; @FXML private Label durationLabel; private PlayerInfoView player1InfoView; private PlayerInfoView player2InfoView; private final NumberFormat formatter = DecimalFormat.getInstance(); public SimulationResultView() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/SimulationResultView.fxml")); fxmlLoader.setRoot(this); fxmlLoader.setController(this); try { fxmlLoader.load(); } catch (IOException exception) { throw new RuntimeException(exception); } doneButton.setOnAction(event -> NotificationProxy.sendNotification(GameNotification.MAIN_MENU)); player1InfoView = new PlayerInfoView(); infoArea.setLeft(player1InfoView); player2InfoView = new PlayerInfoView(); infoArea.setRight(player2InfoView); formatter.setMinimumFractionDigits(0); formatter.setMaximumFractionDigits(2); } private String getAverageStatString(Statistic stat, GameStatistics playerStatistics, int numberOfGames) { if (playerStatistics.contains(stat)) { Object statValue = playerStatistics.get(stat); if (statValue instanceof Number) { double value = ((Number) statValue).doubleValue(); return formatter.format(value / numberOfGames); } } return "-"; } private String getFavouriteCardName(GameStatistics stats, CardType cardType) { List<Card> cards = new ArrayList<Card>(); for (String cardId : stats.getCardsPlayed().keySet()) { if (cardId.startsWith(GameLogic.TEMP_CARD_LABEL)) { continue; } Card card = CardCatalogue.getCardById(cardId); if (card == null) { System.out.println("Invalid card with id: " + cardId); } if (card.getCardType() == cardType) { cards.add(card); } } if (cards.isEmpty()) { return "-"; } Collections.sort(cards, (c1, c2) -> { int c1Count = stats.getCardsPlayedCount(c1.getCardId()); int c2Count = stats.getCardsPlayedCount(c2.getCardId()); // sort descending return Integer.compare(c2Count, c1Count); }); return cards.get(0).getName(); } private String getStatString(Statistic stat, GameStatistics playerStatistics) { if (playerStatistics.contains(stat)) { Object statValue = playerStatistics.get(stat); if (statValue instanceof Number) { return formatter.format(playerStatistics.get(stat)); } return statValue.toString(); } return "-"; } @SuppressWarnings({ "rawtypes", "unchecked" }) public void showSimulationResult(SimulationResult result) { player1InfoView.setInfo(result.getConfig().getPlayerConfig1()); player2InfoView.setInfo(result.getConfig().getPlayerConfig2()); durationLabel.setText("Simulation took " + DurationFormatUtils.formatDurationHMS(result.getDuration())); ObservableList<StatEntry> absoluteStatEntries = FXCollections.observableArrayList(); ObservableList<StatEntry> averageStatEntries = FXCollections.observableArrayList(); for (Statistic stat : Statistic.values()) { StatEntry absoluteStatEntry = new StatEntry(); absoluteStatEntry.setStatName(getStatName(stat)); absoluteStatEntry.setPlayer1Value(getStatString(stat, result.getPlayer1Stats())); absoluteStatEntry.setPlayer2Value(getStatString(stat, result.getPlayer2Stats())); absoluteStatEntries.add(absoluteStatEntry); StatEntry averageStatEntry = new StatEntry(); averageStatEntry.setStatName(getStatName(stat)); averageStatEntry.setPlayer1Value(getAverageStatString(stat, result.getPlayer1Stats(), result.getNumberOfGames())); averageStatEntry.setPlayer2Value(getAverageStatString(stat, result.getPlayer2Stats(), result.getNumberOfGames())); averageStatEntries.add(averageStatEntry); } StatEntry favouriteMinionCard = new StatEntry(); favouriteMinionCard.setStatName("Favourite minion card"); favouriteMinionCard.setPlayer1Value(getFavouriteCardName(result.getPlayer1Stats(), CardType.MINION)); favouriteMinionCard.setPlayer2Value(getFavouriteCardName(result.getPlayer2Stats(), CardType.MINION)); absoluteStatEntries.add(favouriteMinionCard); StatEntry favouriteSpellCard = new StatEntry(); favouriteSpellCard.setStatName("Favourite spell card"); favouriteSpellCard.setPlayer1Value(getFavouriteCardName(result.getPlayer1Stats(), CardType.SPELL)); favouriteSpellCard.setPlayer2Value(getFavouriteCardName(result.getPlayer2Stats(), CardType.SPELL)); absoluteStatEntries.add(favouriteSpellCard); StatEntry favouriteWeaponCard = new StatEntry(); favouriteWeaponCard.setStatName("Favourite weapon card"); favouriteWeaponCard.setPlayer1Value(getFavouriteCardName(result.getPlayer1Stats(), CardType.WEAPON)); favouriteWeaponCard.setPlayer2Value(getFavouriteCardName(result.getPlayer2Stats(), CardType.WEAPON)); absoluteStatEntries.add(favouriteWeaponCard); absoluteResultTable.setItems(absoluteStatEntries); absoluteResultTable.getColumns().get(0).setCellValueFactory(new PropertyValueFactory("statName")); absoluteResultTable.getColumns().get(1).setCellValueFactory(new PropertyValueFactory("player1Value")); absoluteResultTable.getColumns().get(2).setCellValueFactory(new PropertyValueFactory("player2Value")); averageResultTable.setItems(averageStatEntries); averageResultTable.getColumns().get(0).setCellValueFactory(new PropertyValueFactory("statName")); averageResultTable.getColumns().get(1).setCellValueFactory(new PropertyValueFactory("player1Value")); averageResultTable.getColumns().get(2).setCellValueFactory(new PropertyValueFactory("player2Value")); } }