Skip to content

Commit

Permalink
V0.14.0
Browse files Browse the repository at this point in the history
  • Loading branch information
domhnallmorr committed Jan 4, 2025
1 parent 27ca6cf commit 610d91b
Show file tree
Hide file tree
Showing 21 changed files with 184 additions and 80 deletions.
6 changes: 3 additions & 3 deletions src/pw_controller/race_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import threading
from typing import TYPE_CHECKING

from race_model import race_model
from race_model.race_model_enums import SessionNames
from race_weekend_model import race_weekend_model
from race_weekend_model.race_model_enums import SessionNames

if TYPE_CHECKING:
from pw_controller.pw_controller import Controller
Expand All @@ -15,7 +15,7 @@ def __init__(self, controller: Controller):
self.view = controller.view

if self.controller.model.season.current_track_model is not None: # None indicates the season is over, no more races this season
self.race_model = race_model.RaceModel("UI", self.controller.model, self.controller.model.season.current_track_model)
self.race_model = race_weekend_model.RaceWeekendModel("UI", self.controller.model, self.controller.model.season.current_track_model)


def simulate_session(self, session: SessionNames) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/pw_view/race_weekend/race_weekend_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import flet as ft

from pw_view.custom_widgets import custom_container, custom_buttons
from race_model.race_model_enums import SessionNames
from race_weekend_model.race_model_enums import SessionNames

if TYPE_CHECKING:
from pw_view.view import View
Expand Down
24 changes: 16 additions & 8 deletions src/pw_view/race_weekend/results_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pandas as pd
from flet.matplotlib_chart import MatplotlibChart

from race_model.race_model_enums import SessionNames
from race_weekend_model.race_model_enums import SessionNames
from pw_view import view
from pw_view.custom_widgets import custom_container, custom_buttons

Expand Down Expand Up @@ -90,7 +90,7 @@ def update_page(self, data: dict) -> None:
self.update_buttons_row(timed_session)
self.setup_classification_table(standings_df, current_session)

self.classification_list_view = ft.ListView(expand=True, spacing=10, padding=20, auto_scroll=True)
self.classification_list_view = ft.ListView(expand=True, spacing=10, padding=20, auto_scroll=False)
self.classification_list_view.controls.append(self.classification_container)

self.content_column = ft.Column(
Expand All @@ -104,7 +104,7 @@ def update_page(self, data: dict) -> None:
self.view.results_background_image,
self.content_column,
],
expand=False,
expand=True,
)

contents = [
Expand Down Expand Up @@ -150,7 +150,8 @@ def setup_classification_table(self, standings_df: pd.DataFrame, current_session

columns = []
for col in standings_df.columns:
columns.append(ft.DataColumn(ft.Text(col)))
column_content = custom_container.HeaderContainer(self.view, col)
columns.append(ft.DataColumn(column_content))

data = standings_df.values.tolist()
rows = []
Expand All @@ -162,12 +163,16 @@ def setup_classification_table(self, standings_df: pd.DataFrame, current_session

rows.append(ft.DataRow(cells=cells))

self.results_table = ft.DataTable(columns=columns, rows=rows, data_row_max_height=30, data_row_min_height=30)
self.results_table = ft.DataTable(columns=columns, rows=rows, data_row_max_height=30, data_row_min_height=30, heading_row_color=ft.Colors.PRIMARY)

self.classification_container = custom_container.CustomContainer(self.view, self.results_table, expand=False)

def setup_pitstops_table(self, pit_stop_summary: dict) -> None:
columns = [ft.DataColumn(ft.Text("Driver")), ft.DataColumn(ft.Text("Stops")), ft.DataColumn(ft.Text("Laps"))]
columns = []
for col in ["Driver", "Stops", "Laps"]:
column_content = custom_container.HeaderContainer(self.view, col)
columns.append(ft.DataColumn(column_content))

rows = []

for driver in pit_stop_summary.keys():
Expand All @@ -181,9 +186,12 @@ def setup_pitstops_table(self, pit_stop_summary: dict) -> None:

rows.append(ft.DataRow(cells=cells))

self.pitstops_table = ft.DataTable(columns=columns, rows=rows, data_row_max_height=30, data_row_min_height=30)
self.pitstops_table = ft.DataTable(columns=columns, rows=rows, data_row_max_height=30, data_row_min_height=30, heading_row_color=ft.Colors.PRIMARY)

self.pitstops_container = custom_container.CustomContainer(self.view, self.pitstops_table, expand=False)

self.pitstops_list_view = ft.ListView(expand=True, spacing=10, padding=20, auto_scroll=False)
self.pitstops_list_view.controls.append(self.pitstops_container)

def setup_lap_chart(self) -> None:
px = 1/plt.rcParams['figure.dpi'] # pixel in inches
Expand Down Expand Up @@ -267,7 +275,7 @@ def display_pitstops(self, e: ft.ControlEvent) -> None:
self.reset_tab_buttons()
self.pitstops_btn.style = self.view.clicked_button_style

self.content_column.controls=[self.buttons_container, self.pitstops_container, self.continue_container]
self.content_column.controls=[self.buttons_container, self.pitstops_list_view, self.continue_container]
self.view.main_app.update()

def display_lap_chart(self, e: ft.ControlEvent) -> None:
Expand Down
6 changes: 5 additions & 1 deletion src/pw_view/staff_page/staff_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,11 @@ def setup_staff_value_progress_bars(self, data: dict) -> ft.Container:
row = ft.Row(
controls=[
ft.Text(f"{team_name} ({staff_value}):", width=100),
ft.ProgressBar(value=staff_value/max_staff, width=500, expand=True, bar_height=28)
ft.Container(
content=ft.ProgressBar(value=staff_value/max_staff, width=500, expand=True, bar_height=28),
height=28,
expand=True
)
],
expand=True,
)
Expand Down
6 changes: 3 additions & 3 deletions src/pw_view/standings_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def update_standings(self, drivers_standings_df: pd.DataFrame, constructors_stan
self.drivers_table = ft.DataTable(columns=columns, rows=rows, data_row_max_height=30, data_row_min_height=30,
heading_row_color=ft.Colors.PRIMARY)

self.scrollable_drivers_table = ft.ListView(expand=1, auto_scroll=True)
self.scrollable_drivers_table = ft.ListView(expand=True, auto_scroll=False)
self.scrollable_drivers_table.controls.append(custom_container.CustomContainer(self.view, self.drivers_table, expand=False))

# CONSTRUCTORS
Expand Down Expand Up @@ -142,13 +142,13 @@ def arrange_controls(self, mode: str) -> None:
assert mode in ["drivers", "constructors"]

if mode == "drivers":
container = custom_container.CustomContainer(self.view, self.scrollable_drivers_table, expand=False)
container = custom_container.CustomContainer(self.view, self.scrollable_drivers_table, expand=True)
elif mode == "constructors":
container = custom_container.CustomContainer(self.view, self.scrollable_constructors_table, expand=False)

column = ft.Column(
controls=[self.buttons_container, container],
expand=False,
expand=True,
spacing=20
)

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import random
from typing import Tuple

from race_model import session_model, commentary
from race_model.race_model_enums import SessionNames, SessionStatus
from race_weekend_model import session_model, commentary
from race_weekend_model.race_model_enums import SessionNames, SessionStatus, SessionMode

from pw_model.pw_base_model import Model
from race_model.particpant_model import ParticpantModel
from race_weekend_model.particpant_model import ParticpantModel
from race_weekend_model.session_model import SessionModel

class GrandPrixModel(session_model.SessionModel):
def __init__(self, model: Model):
Expand All @@ -24,22 +25,8 @@ def leader(self) -> str:
return str(self.standings_df.iloc[0]["Driver"])

def setup_grid_order(self) -> None:
qualy_results = self.race_model.results[SessionNames.QUALIFYING.value]["results"]
grid_order = qualy_results["Driver"]
self.standings_df = self.race_model.starting_grid.apply_grid_order_to_standings(self.standings_df)

self.standings_df.set_index('Driver', inplace=True, drop=False)
self.standings_df = self.standings_df.loc[grid_order]
self.refresh_standings_column()

for idx, row in self.standings_df.iterrows():
driver = row["Driver"]
participant = self.race_model.get_particpant_model_by_name(driver)

# update position in participant class
participant.starting_position = idx + 1
# update Grid column in dataframe
self.standings_df.loc[self.standings_df["Driver"] == driver, "Grid"] = idx + 1

def setup_participant_start_fuel_and_tyres(self) -> None:
for p in self.race_model.participants:
p.setup_start_fuel_and_tyres()
Expand All @@ -54,7 +41,7 @@ def setup_participant_start_fuel_and_tyres(self) -> None:
def advance(self, mode: str) -> None:
self.mode = mode
if self.status == SessionStatus.PRE_SESSION:
if self.mode != "simulate":
if self.mode != SessionMode.SIMULATE:
self.commentary_to_process.append(commentary.gen_race_start_message())
self.calculate_start()
self.status = SessionStatus.RUNNING
Expand All @@ -68,7 +55,7 @@ def advance(self, mode: str) -> None:
self.current_lap += 1

if self.current_lap > self.race_model.track_model.number_of_laps or self.current_lap == 999:
if self.mode != "simulate":
if self.mode != SessionMode.SIMULATE:
self.commentary_to_process.append(commentary.gen_race_over_message(self.leader))
self.status = SessionStatus.POST_SESSION
self.post_race_actions()
Expand Down Expand Up @@ -118,7 +105,7 @@ def calculate_run_to_turn1(self) -> list[Tuple[float, ParticpantModel]]:
[[12.761, <RaceEngineParticpantModel Mark Webber>], [13.124, <RaceEngineParticpantModel Sebastian Vettel>], [13.68, <RaceEngineParticpantModel Fernando Alonso>],]
'''

if self.mode != "simulate":
if self.mode != SessionMode.SIMULATE:
self.commentary_to_process.append(commentary.gen_lead_after_turn1_message(order_after_turn1[0][1].name))

return order_after_turn1
Expand Down Expand Up @@ -188,15 +175,15 @@ def calculate_lap(self) -> None:

# IF RETIRED THIS LAP
if participant.status == "retired":
if self.mode != "simulate":
if self.mode != SessionMode.SIMULATE:
self.commentary_to_process.append(commentary.gen_retirement_message(participant.name))
self.retirements.append(participant.name)
# self.log_event(f"{participant.name} retires")
laptime_ahead = None

else:
if participant.status == "pitting in":
if self.mode != "simulate":
if self.mode != SessionMode.SIMULATE:
self.commentary_to_process.append(commentary.gen_entering_pit_lane_message(participant.name))

# print(laptime_ahead)
Expand All @@ -206,12 +193,12 @@ def calculate_lap(self) -> None:

if gap_ahead + delta <= 500 and participant_ahead.status not in ["pitting in", "retired"]: # if car ahead is about to pit, don't handle for overtaking
# self.log_event(f"{driver} Attacking {participant_ahead.name}")
if self.mode != "simulate":
if self.mode != SessionMode.SIMULATE:
self.commentary_to_process.append(commentary.gen_attacking_message(driver, participant_ahead.name))

if random.randint(0, 100) < 25: # overtake successfull
# self.log_event(f"{participant.name} passes {participant_ahead.name}")
if self.mode != "simulate":
if self.mode != SessionMode.SIMULATE:
self.commentary_to_process.append(commentary.gen_overtake_message(participant.name, participant_ahead.name))

# add some random time to overtaking car, held up when passing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def setup_variables_for_session(self) -> None:
self.positions_by_lap: list[int] = [] # not zero indexed
self.tyre_wear_by_lap: list[int] = [] # not zero indexed
self.number_of_pitstops = 0
self.starting_position = None # not zero indexed
self.starting_position = None # not zero indexed, set in StartingGrid class

self.status = "in_pit"
self.attacking = False
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from __future__ import annotations
from typing import TYPE_CHECKING

from race_model import timed_session_model
from race_weekend_model import timed_session_model

if TYPE_CHECKING:
from race_model.race_model import RaceModel
from race_weekend_model.race_weekend_model import RaceWeekendModel

class QualyModel(timed_session_model.TimedSessionModel):
def __init__(self, model: RaceModel, session_time: int):
def __init__(self, model: RaceWeekendModel, session_time: int):
super().__init__(model, session_time)

self.generate_practice_runs()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ class SessionNames(Enum):
class SessionStatus(Enum):
PRE_SESSION = "Pre Session"
RUNNING = "Green"
POST_SESSION = "Post Session"
POST_SESSION = "Post Session"

class SessionMode(Enum):
SIMULATE = "simulate"

Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@

from pw_model import pw_base_model
from pw_model.track import track_model
from race_model import qualy_model, grand_prix_model
from race_model import particpant_model
from race_model.race_model_enums import SessionNames, SessionStatus
from race_weekend_model import qualy_model, grand_prix_model
from race_weekend_model import particpant_model
from race_weekend_model.starting_grid import StartingGrid
from race_weekend_model.race_model_enums import SessionNames, SessionStatus, SessionMode

class RaceModel:
class RaceWeekendModel:
def __init__(self, mode: str, model: pw_base_model.Model, track_model: track_model.TrackModel):
assert mode in ["UI", "headless"], f"Unsupported Mode {mode}" # headless is model only, UI means were using the GUI

Expand Down Expand Up @@ -49,7 +50,7 @@ def setup_practice(self, session_time: int, session_name: str) -> None:
self.setup_session()

def setup_qualifying(self,
session_time: None,# in seconds e.g. 60*60 for 1 hr
session_time: int,# in seconds e.g. 60*60 for 1 hr
session_type: Enum) -> None:
assert session_type == SessionNames.QUALIFYING # session is a variable for future development of Q1, Q2, Q3, for the 1998 1hr qualfy

Expand All @@ -58,6 +59,7 @@ def setup_qualifying(self,
self.setup_session()

def setup_race(self) -> None:
self.starting_grid = StartingGrid(self)
self.current_session_name = SessionNames.RACE.value
self.current_session = grand_prix_model.GrandPrixModel(self)
self.setup_session()
Expand All @@ -72,5 +74,5 @@ def update_player_drivers_strategy(self, driver1_data, driver2_data) -> None:

def simulate_session(self) -> None:
while self.current_session.status != SessionStatus.POST_SESSION:
self.current_session.advance("simulate")
self.current_session.advance(SessionMode.SIMULATE)

Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
from typing import Optional, TYPE_CHECKING
import pandas as pd

from race_model.race_model_enums import SessionStatus
from race_weekend_model.race_model_enums import SessionStatus

if TYPE_CHECKING:
from race_model.race_model import RaceModel
from race_weekend_model.race_weekend_model import RaceWeekendModel

class SessionModel:
def __init__(self, race_model: RaceModel):
def __init__(self, race_model: RaceWeekendModel):
self.race_model = race_model
self.setup_standings()

Expand Down
48 changes: 48 additions & 0 deletions src/race_weekend_model/starting_grid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'''
A specific class to holds the starting grid positions for each driver.
It updates each participant model's starting_position variable
It is also responsible for applying the grid order to the GrandPrixModel's standings dataframe
'''
from __future__ import annotations
from typing import TYPE_CHECKING

import pandas as pd

from race_weekend_model.race_model_enums import SessionNames
if TYPE_CHECKING:
from race_weekend_model.race_weekend_model import RaceWeekendModel

class StartingGrid:
def __init__(self, race_weekend_model: RaceWeekendModel):
self.race_weekend_model = race_weekend_model

self.setup_grid_order()
self.update_participants()

def setup_grid_order(self) -> None:
qualy_results = self.race_weekend_model.results[SessionNames.QUALIFYING.value]["results"]
self.grid_order = qualy_results["Driver"]

def update_participants(self) -> None:
'''
Update starting position variable in eeach participant
'''
for idx, driver in enumerate(self.grid_order):
participant = self.race_weekend_model.get_particpant_model_by_name(driver)

# update position in participant class
participant.starting_position = idx + 1

def apply_grid_order_to_standings(self, standings_df: pd.DataFrame) -> pd.DataFrame:
standings_df.set_index('Driver', inplace=True, drop=False)
standings_df = standings_df.loc[self.grid_order]

standings_df.reset_index(drop=True, inplace=True)
standings_df["Position"] = standings_df.index + 1

for idx, row in standings_df.iterrows():
driver = row["Driver"]
standings_df.loc[standings_df["Driver"] == driver, "Grid"] = idx + 1

return standings_df

Loading

0 comments on commit 610d91b

Please sign in to comment.