From 18bcc1bce7ddabe519e516160e49123afbd3626d Mon Sep 17 00:00:00 2001 From: Khopa Date: Sat, 13 Jul 2019 14:08:44 +0200 Subject: [PATCH] Implemented stats view. --- game/db.py | 16 +++++- game/game.py | 8 +++ game/game_stats.py | 58 ++++++++++++++++++++++ qt_ui/widgets/QStatsWindow.py | 59 +++++++++++++++++++++++ qt_ui/widgets/QTopPanel.py | 4 +- qt_ui/windows/settings/QSettingsWindow.py | 15 ++---- 6 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 game/game_stats.py create mode 100644 qt_ui/widgets/QStatsWindow.py diff --git a/game/db.py b/game/db.py index 5e9209c6..f584c3ac 100644 --- a/game/db.py +++ b/game/db.py @@ -86,6 +86,10 @@ PRICES = { AH_64D: 15, OH_58D: 6, + # Bombers + B_52H: 25, + B_1B: 50, + # special IL_76MD: 13, An_26B: 13, @@ -183,8 +187,8 @@ UNIT_BY_TASK = { MiG_23MLD, Su_27, Su_33, - MiG_21Bis, MiG_19P, + MiG_21Bis, MiG_29A, MiG_29S, FA_18C_hornet, @@ -215,7 +219,9 @@ UNIT_BY_TASK = { Su_24MR, AH_64A, AH_64D, - OH_58D + OH_58D, + B_52H, + B_1B, ], Transport: [ IL_76MD, @@ -642,6 +648,8 @@ FACTIONS = { C_130, E_3A, + B_52H, + UH_1H, Armor.MBT_M60A3_Patton, @@ -669,6 +677,8 @@ FACTIONS = { A_10A, AV8BNA, + B_1B, + KC_135, S_3B_Tanker, C_130, @@ -707,6 +717,8 @@ FACTIONS = { A_10C, AV8BNA, + B_1B, + KC_135, S_3B_Tanker, C_130, diff --git a/game/game.py b/game/game.py index 1be1e3e8..7d0378cb 100644 --- a/game/game.py +++ b/game/game.py @@ -6,6 +6,7 @@ import math from dcs.task import * from dcs.vehicles import * +from game.game_stats import GameStats from gen.conflictgen import Conflict from userdata.debriefing import Debriefing from theater import * @@ -93,6 +94,7 @@ class Game: pending_transfers = None # type: typing.Dict[] ignored_cps = None # type: typing.Collection[ControlPoint] turn = 0 + game_stats: GameStats = None def __init__(self, player_name: str, enemy_name: str, theater: ConflictTheater, start_date: datetime): self.settings = Settings() @@ -104,6 +106,8 @@ class Game: self.enemy_country = db.FACTIONS[enemy_name]["country"] self.turn = 0 self.date = datetime(start_date.year, start_date.month, start_date.day) + self.game_stats = GameStats() + self.game_stats.update(self) def _roll(self, prob, mult): if self.settings.version == "dev": @@ -297,8 +301,12 @@ class Game: self.events = [] # type: typing.List[Event] self._generate_events() + #self._generate_globalinterceptions() + # Update statistics + self.game_stats.update(self) + @property def current_turn_daytime(self): return ["dawn", "day", "dusk", "night"][self.turn % 4] diff --git a/game/game_stats.py b/game/game_stats.py new file mode 100644 index 00000000..48f735ce --- /dev/null +++ b/game/game_stats.py @@ -0,0 +1,58 @@ +class FactionTurnMetadata: + """ + Store metadata about a faction + """ + + aircraft_count: int = 0 + vehicles_count: int = 0 + sam_count: int = 0 + + def __init__(self): + self.aircraft_count = 0 + self.vehicles_count = 0 + self.sam_count = 0 + + +class GameTurnMetadata: + """ + Store metadata about a game turn + """ + + allied_units:FactionTurnMetadata + enemy_units:FactionTurnMetadata + + def __init__(self): + self.allied_units = FactionTurnMetadata() + self.enemy_units = FactionTurnMetadata() + + +class GameStats: + """ + Store statistics for the current game + """ + + data_per_turn: [GameTurnMetadata] = [] + + def __init__(self): + self.data_per_turn = [] + + def update(self, game): + """ + Save data for current turn + :param game: Game we want to save the data about + """ + + turn_data = GameTurnMetadata() + + for cp in game.theater.controlpoints: + if cp.captured: + turn_data.allied_units.aircraft_count += sum(cp.base.aircraft.values()) + turn_data.allied_units.sam_count += sum(cp.base.aa.values()) + turn_data.allied_units.vehicles_count += sum(cp.base.armor.values()) + else: + turn_data.enemy_units.aircraft_count += sum(cp.base.aircraft.values()) + turn_data.enemy_units.sam_count += sum(cp.base.aa.values()) + turn_data.enemy_units.vehicles_count += sum(cp.base.armor.values()) + + self.data_per_turn.append(turn_data) + diff --git a/qt_ui/widgets/QStatsWindow.py b/qt_ui/widgets/QStatsWindow.py new file mode 100644 index 00000000..19d1254f --- /dev/null +++ b/qt_ui/widgets/QStatsWindow.py @@ -0,0 +1,59 @@ +from PySide2 import QtCharts +from PySide2.QtCore import QPoint, Qt +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import QDialog, QGridLayout +from PySide2.QtCharts import QtCharts + +import qt_ui.uiconstants as CONST +from game.game import Game + + +class QStatsWindow(QDialog): + + def __init__(self, game: Game): + super(QStatsWindow, self).__init__() + + self.game = game + + self.setModal(True) + self.setWindowTitle("Stats") + self.setWindowIcon(CONST.ICONS["Statistics"]) + self.setMinimumSize(600, 250) + + self.initUi() + + def initUi(self): + self.layout = QGridLayout() + self.generateUnitCharts() + self.setLayout(self.layout) + + def generateUnitCharts(self): + + self.alliedAircraft = [d.allied_units.aircraft_count for d in self.game.game_stats.data_per_turn] + self.enemyAircraft = [d.enemy_units.aircraft_count for d in self.game.game_stats.data_per_turn] + + self.alliedAircraftSerie = QtCharts.QLineSeries() + self.alliedAircraftSerie.setName("Allied aircraft count") + for a,i in enumerate(self.alliedAircraft): + self.alliedAircraftSerie.append(QPoint(a, i)) + + self.enemyAircraftSerie = QtCharts.QLineSeries() + self.enemyAircraftSerie.setColor(Qt.red) + self.enemyAircraftSerie.setName("Enemy aircraft count") + for a,i in enumerate(self.enemyAircraft): + self.enemyAircraftSerie.append(QPoint(a, i)) + + self.chart = QtCharts.QChart() + self.chart.addSeries(self.alliedAircraftSerie) + self.chart.addSeries(self.enemyAircraftSerie) + self.chart.setTitle("Aircraft forces over time") + + self.chart.createDefaultAxes() + self.chart.axisX().setRange(0, len(self.alliedAircraft)) + self.chart.axisY().setRange(0, max(max(self.alliedAircraft), max(self.enemyAircraft)) + 10) + + self.chartView = QtCharts.QChartView(self.chart) + self.chartView.setRenderHint(QPainter.Antialiasing) + + self.layout.addWidget(self.chartView, 0, 0) + diff --git a/qt_ui/widgets/QTopPanel.py b/qt_ui/widgets/QTopPanel.py index 6127d613..80480943 100644 --- a/qt_ui/widgets/QTopPanel.py +++ b/qt_ui/widgets/QTopPanel.py @@ -2,6 +2,7 @@ from PySide2.QtWidgets import QFrame, QHBoxLayout, QPushButton, QVBoxLayout, QMe from game import Game from qt_ui.widgets.QBudgetBox import QBudgetBox +from qt_ui.widgets.QStatsWindow import QStatsWindow from qt_ui.widgets.QTurnCounter import QTurnCounter import qt_ui.uiconstants as CONST @@ -60,7 +61,8 @@ class QTopPanel(QFrame): self.subwindow.show() def openStatisticsWindow(self): - QMessageBox.information(self, "Stats", "Todo open stats window") + self.subwindow = QStatsWindow(self.game) + self.subwindow.show() def passTurn(self): self.game.pass_turn() diff --git a/qt_ui/windows/settings/QSettingsWindow.py b/qt_ui/windows/settings/QSettingsWindow.py index 20c83592..97c2b591 100644 --- a/qt_ui/windows/settings/QSettingsWindow.py +++ b/qt_ui/windows/settings/QSettingsWindow.py @@ -1,16 +1,11 @@ -import os - -from PySide2 import QtCore -from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QModelIndex, QPoint -from PySide2.QtGui import QMovie, QStandardItemModel, QStandardItem -from PySide2.QtWidgets import QLabel, QDialog, QVBoxLayout, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \ +from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint +from PySide2.QtGui import QStandardItemModel, QStandardItem +from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \ QAbstractItemView, QPushButton, QGroupBox, QCheckBox -from game.game import Event, Game -from qt_ui.windows.GameUpdateSignal import GameUpdateSignal import qt_ui.uiconstants as CONST -from userdata.debriefing import wait_for_debriefing, Debriefing -from userdata.persistency import base_path +from game.game import Game +from qt_ui.windows.GameUpdateSignal import GameUpdateSignal class QSettingsWindow(QDialog):