mirror of
https://github.com/rr-/pq-cli.git
synced 2026-09-29 14:54:00 -06:00
116 lines
2.9 KiB
Python
116 lines
2.9 KiB
Python
import argparse
|
|
import datetime
|
|
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
from signal import SIG_DFL, SIGPIPE, signal
|
|
|
|
from pqcli import random
|
|
from pqcli.config import CLASSES, RACES
|
|
from pqcli.mechanic import (
|
|
Player,
|
|
Simulation,
|
|
StatsBuilder,
|
|
act_name,
|
|
create_player,
|
|
generate_name,
|
|
)
|
|
from pqcli.roster import Roster
|
|
|
|
signal(SIGPIPE, SIG_DFL)
|
|
logging.basicConfig(
|
|
stream=sys.stdout, level=logging.DEBUG, format="%(message)s"
|
|
)
|
|
|
|
|
|
# make things predictable
|
|
SEED_A = 1_664_525
|
|
SEED_B = 2141
|
|
SEED_C = 1_013_904_223
|
|
|
|
|
|
def custom_random(num: int) -> int:
|
|
global SEED_A, SEED_B, SEED_C
|
|
SEED_B = (SEED_A * SEED_B + SEED_C) % 0x100000000
|
|
return SEED_B % num
|
|
|
|
|
|
random.below = custom_random
|
|
|
|
|
|
def character_sheet(player: Player) -> None:
|
|
print(f"{player.name} the {player.race.name}")
|
|
print(f"Level {player.level} {player.class_.name}")
|
|
print(f"Plot stage: {act_name(player.quest_book.act)}")
|
|
print(f"Quest: {player.quest_book.current_quest}")
|
|
print()
|
|
print("Stats:")
|
|
for stat, value in player.stats:
|
|
print(f" {stat.value}: {value}")
|
|
print()
|
|
print(f"Equipment (best: {player.equipment.best}):")
|
|
for equipment, item_name in player.equipment:
|
|
print(f" {equipment.value}: {item_name}")
|
|
print()
|
|
print("Spell Book:")
|
|
for spell in player.spell_book:
|
|
print(f" {spell.name}: {spell.level}")
|
|
print()
|
|
print("Inventory:")
|
|
print(f" Gold: {player.inventory.gold}")
|
|
for item in player.inventory:
|
|
print(f" {item.name}: {item.quantity}")
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("-r", "--roster", type=Path)
|
|
parser.add_argument("-l", "--max-level", type=int, default=5)
|
|
return parser.parse_args()
|
|
|
|
|
|
def random_player() -> Player:
|
|
return create_player(
|
|
stats=StatsBuilder().roll(),
|
|
name=generate_name(),
|
|
race=random.choice(RACES),
|
|
class_=random.choice(CLASSES),
|
|
)
|
|
|
|
|
|
def main() -> None:
|
|
args = parse_args()
|
|
|
|
if args.roster:
|
|
roster = Roster.load(args.roster)
|
|
if not roster.players:
|
|
roster.players.append(random_player())
|
|
roster.save()
|
|
player = roster.players[0]
|
|
else:
|
|
roster = None
|
|
player = random_player()
|
|
|
|
start = datetime.datetime.now()
|
|
elapsed = 0
|
|
last_level = 0
|
|
simulation = Simulation(player)
|
|
try:
|
|
while True:
|
|
if player.level != last_level:
|
|
last_level = player.level
|
|
character_sheet(player)
|
|
if player.level >= args.max_level:
|
|
break
|
|
simulation.tick()
|
|
elapsed += 100
|
|
finally:
|
|
print("real time: ", (datetime.datetime.now() - start))
|
|
print("virtual time: ", datetime.timedelta(milliseconds=elapsed))
|
|
if roster:
|
|
roster.save()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|