group-b/group_b/player.py

121 lines
4.0 KiB
Python

from .action_deck import ActionDeck, ActionCard
from .stage_deck import StageDeck, StageDeckEmpty, StraightCard
class PlayerState():
START_HAND = 4
NOTE_LOOKAHEAD = 3
MAX_HAND_SIZE = 5
def __init__(self):
self._action_deck = ActionDeck()
self._action_deck.shuffle()
self._stage = StageDeck()
self._resources = PlayerResources()
self._hand = [self._action_deck.draw() for _ in range(PlayerState.START_HAND)]
self._pace_note_queue = [self._stage.draw() for _ in range(PlayerState.NOTE_LOOKAHEAD)]
def hand(self):
return self._hand
def resources(self):
return self._resources
def draw(self):
assert(len(self._hand) <= self.MAX_HAND_SIZE)
new_action = self._action_deck.draw()
self._hand.append(new_action)
return new_action
def perform_action(self, action: ActionCard):
# no cheating!
assert(action in self.hand())
current_stage_note = self._pace_note_queue.pop(0)
self.apply_road_friction()
for modifier, value in action.modifiers.items():
if type(current_stage_note) == StraightCard:
# TKTKTK partial value or the ability to play two cards
# on long straight? hard to balance 70 meter straight in
# to heavy zone
if modifier != "focus":
value = current_stage_note.modifier * value
value += value * self._resources.momentum
self.maybe_modify_resource(modifier, value)
if not current_stage_note.can_pass_with(self, action):
# maybe lol
damage = int(self._resources.momentum + self._resources.speed)
print(f"{self._resources.speed} is too fast for a {current_stage_note}! you've taken {damage*5} car and {damage} tire damage")
self._resources.car_health -= damage * 5
self._resources.tire_health -= damage
current_stage_note.discard()
action.discard()
self.hand().remove(action)
try:
self._pace_note_queue.append(self._stage.draw())
except StageDeckEmpty:
pass
def check_damage(self):
if self._resources.car_health <= 0:
raise Exception("you've crashed")
def apply_road_friction(self):
rf = self._resources.road_friction
self._resources.speed -= self._resources.momentum * rf
self._resources.momentum -= self._resources.momentum * rf
# TKTKTK this will spend resources until one cannot be spent , need to check all before spendign any
def maybe_modify_resource(self, modifier, value):
if modifier == "focus" and self._resources[modifier] + value <= 0:
print(f"{modifier} {value} {self._resources[modifier]}")
raise Exception("you've lost focus and crashed!")
if modifier == "speed" and self._resources[modifier] + value >= self._resources.top_speed:
self._resources.speed = self._resources.top_speed
elif self._resources[modifier] + value >= 0:
self._resources[modifier] += value
else:
self._resources[modifier] = 0
from dataclasses import dataclass
class DictyDataClass():
def __getitem__(self, item):
return getattr(self, item)
def __setitem__(self, item, val):
return setattr(self, item, val)
@dataclass
class PlayerResources(DictyDataClass):
speed: int = 0
focus: int = 10
momentum: int = 0
car_health: int = 100
tire_health: int = 100
# only relevant in meta-progression
soft_tires: int = 4
hard_tires: int = 4
# hidden values attached to the car, stage, etc
tire_wear: int = 1
road_friction: float = 0.1
top_speed: int = 15
def __str__(self):
return "".join([
"speed: ", str(self.speed), "\n",
"focus: ", str(self.focus), "\n",
"momentum: ", str(self.momentum), "\n",
"car: ", str(self.car_health), "\n",
"tire: ", str(self.tire_health), "\n",
])