liars-dice/ui.py

108 lines
3.9 KiB
Python
Raw Normal View History

2022-08-03 15:39:53 +00:00
import time
from dataclasses import dataclass
from bot_ai import BotAi
from engine import EngineHandler, LiarsDiceEngine, Bid
@dataclass
class MyEngineHandler(EngineHandler):
state: LiarsDiceEngine | None
player_names: list[str]
bot_ai: BotAi
def is_current_player_numan(self):
return self.state.active_player_index == 0
def on_game_started(self, game_state: LiarsDiceEngine):
self.state = game_state
print(f"Ahoy, challenger! You're playing against {', '.join(self.player_names[1:])}.")
print()
def on_bid_placed(self, bid: Bid):
print(
f"{self.player_names[self.state.active_player_index]} "
f"bid{'s' if self.state.active_player_index != 0 else ''} "
f"{bid.num_dice}x{bid.die_face}{'s' if bid.num_dice > 1 else ''}!"
)
def on_challenge_bid(self):
bid_owner = (
self.player_names[self.state.active_player_index - 1] + "'s"
if self.is_current_player_numan()
else "your"
)
print(
f"\n{self.player_names[self.state.active_player_index]} "
f"challenge{'' if self.is_current_player_numan() else 's'} "
f"{bid_owner} bid... "
f"{'unsuccessfully' if self.state.is_current_bid_successful() else 'SUCCESSFULLY'}!"
)
print(f"Your dice: {', '.join(str(d) for d in sorted(self.state.dice[0].elements()))}")
for i in range(1, len(self.player_names)):
print(
f"{self.player_names[i]}'s dice: {', '.join(str(d) for d in sorted(self.state.dice[i].elements()))}"
)
time.sleep(2)
def on_new_round(self):
print(f"\n--- Round {self.state.round_number} ---\n")
print(f"Your dice: {', '.join(str(d) for d in sorted(self.state.dice[0].elements()))}")
for i in range(1, len(self.player_names)):
total = self.state.dice[i].total()
print(f"{self.player_names[i]}'s has {total} {'die' if total == 1 else 'dice'} left.")
print()
def on_player_eliminated(self, player_index: int) -> None:
human_player_eliminated = player_index == 0
print(
f"*** {self.player_names[player_index]} {'have' if human_player_eliminated else 'has'} been eliminated!\n"
)
self.player_names = [n for (i, n) in enumerate(self.player_names) if i != player_index]
if len(self.player_names) == 1:
print(
f"+++ {self.player_names[0]} {'is' if human_player_eliminated else 'are'} the winner!\n"
)
def get_players_turn(self) -> Bid | None:
if self.is_current_player_numan():
return self.get_human_turn_input()
else:
return self.bot_ai.ai_turn(self.state)
def get_human_turn_input(self):
include_challenge_option = bool(self.state.current_bid)
help_message = (
"Please use the input format of NX, whereby N is the number of dice and X is the die face of"
"the bid. Example: '43' means a bid of 3 dice with the 'four' face."
)
while True:
bid_text = input(
f"Your bid [{{NX}}{'/L' if include_challenge_option else ''}/?]: "
).lower()
if bid_text == "?":
print(f"\n{help_message}\n")
if include_challenge_option and bid_text == "l":
return None
if len(bid_text) == 2 and bid_text.isdigit():
num_dice = int(bid_text[0])
die_face = int(bid_text[1])
if die_face < 1 or die_face > 6:
print(
"\nProper pirates only use d6'es, please chose a dice face appropriately! (1-6)"
)
continue
return Bid(die_face=die_face, num_dice=num_dice)
print("\nInvalid bid!")
print(help_message)