marvin-sw-text-adventure/marvin_sw_text_adventure/game.py
2023-05-18 08:38:50 -05:00

249 lines
8.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import atexit
from typing import List, Tuple
from marvin import ai_fn
import pydantic
from pydantic import Field
from rich.panel import Panel
from rich.prompt import Prompt
from rich.table import Table
from marvin_sw_text_adventure.console import console
from numpy import character
@ai_fn
def get_star_wars_character() -> str:
"return a brand new never before heard of star wars character"
@ai_fn
def create_backstory(name: str) -> str:
"create a backstory for a character"
class Game(pydantic.BaseModel):
name: str = Field(..., description="The name of the game")
id: str = Field(..., description="The id of the game")
class Mission(pydantic.BaseModel):
name: str = Field(
...,
description="The name of a brand new never before heard of star wars mission",
)
place: str = Field(..., description="The place of the mission")
leader: str = Field(..., description="The name of the leader of the mission")
year: int = Field(..., description="The year of the mission")
description: str = Field(
...,
description="The description of the brand new never before heard of star wars mission with important words surrounded by [b][/b]",
)
risk: int = Field(
..., description="The risk of the mission in health the character will loose"
)
reward: int = Field(
..., description="The reward of the mission in imperial credits"
)
image_prompt: str = Field(
..., description="An ai image generator prompt of the mission"
)
@property
def stats(self) -> Table:
table = Table(title=self.name, show_edge=False, show_header=False)
# table = Table(show_header=False)
table.add_row("place", self.place)
table.add_row("year", str(self.year))
table.add_row("risk", f"{self.risk} hp")
table.add_row("reward", f"{self.reward} credits")
table.add_row("leader", self.leader)
return table
@property
def describe(self) -> str:
table = Table(show_header=False)
table.add_row(self.stats, self.description)
return table
class MissionResult(pydantic.BaseModel):
success: bool = Field(..., description="The success of the mission")
imperial_credits_spent: int = Field(
..., description="The imperial credits spent on the mission"
)
imperial_credits_earned: int = Field(
..., description="The imperial credits earned on the mission"
)
health_lost: int = Field(..., description="The health lost on the mission")
health_gained: int = Field(..., description="The health gained on the mission")
story: str = Field(..., description="The story of the mission")
image_prompt: str = Field(
..., description="An ai image generator prompt of the mission"
)
fuel_used: int = Field(..., description="The fuel used on the mission")
class Ship(pydantic.BaseModel):
name: str = Field(..., description="The name of the ship")
description: str = Field(..., description="The description of the ship")
capacity: int = Field(..., description="The capacity of the ship")
ship_type: str = Field(..., description="The type of the ship")
year_built: int = Field(..., description="The year built of the ship")
capacity: int = Field(..., description="The capacity of the ship")
fuel_type: str = Field(..., description="The fuel type of the ship")
fuel_level: int = Field(..., description="The fuel level of the ship")
image_prompt: str = Field(
..., description="An ai image generator prompt of the mission"
)
@property
def stats(self) -> Table:
table = Table(title=self.name, show_edge=False, show_header=False)
table.add_row("year built", str(self.year_built))
table.add_row("capacity", str(self.capacity))
table.add_row("fuel level", str(self.fuel_level))
return table
@property
def describe(self):
table = Table(show_header=False, show_edge=False)
table.add_row(self.stats, self.description)
return table
class StarWarsCharacter(pydantic.BaseModel):
name: str = Field(
...,
description="The name of a brand new never before heard of star wars character",
)
imperial_credits: int = Field(
..., description="The imperial credits of the character"
)
health: int = Field(..., description="The health of the character")
home_planet: str = Field(
..., description="The name of the planet where the character was born"
)
age: int = Field(..., description="The age of the character")
birth_year_bby: int = Field(..., description="The birth year of the character")
backstory: str = Field(..., description="The backstory of the character")
ship: Ship = Field(
..., description="The name of the ship where the character operates"
)
side: str = Field(..., description="The side of the character")
city: str = Field(..., description="The name of the city where the character lives")
friends: List[str] = Field(
..., description="The names of the friends of the character"
)
team: str = Field(
..., description="The name of the team that the character belongs to"
)
enemies: List[str] = Field(
..., description="The names of the enemies of the character"
)
mission: Mission = Field(..., description="The current mission of the character")
role: str = Field(..., description="The role of the character")
image_prompt: str = Field(
..., description="An ai image generator prompt of the mission"
)
previous_missions: List[Tuple[Mission, MissionResult]] = Field(
[], description="The previous missions of the character"
)
@property
def stats(self) -> Table:
table = Table(title=self.name, show_edge=False, show_header=False)
# table = Table(show_header=False)
table.add_row("health", str(self.health))
table.add_row("imperial credits", str(self.imperial_credits))
table.add_row("fuel level", str(self.ship.fuel_level))
return table
@property
def describe(self):
table = Table(show_header=False, show_edge=False)
table.add_row(self.stats, self.backstory)
table.add_row()
table.add_row(self.ship.stats, self.ship.description)
table.add_row()
table.add_row(self.mission.stats, self.mission.description)
return Panel(
table,
title=f"{self.name}'s Mission Card",
title_align="left",
)
@ai_fn
def did_complete_mission(character: StarWarsCharacter, action: str) -> MissionResult:
"check if a character completed the mission or if they failed"
@ai_fn
def get_next_mission(
character: StarWarsCharacter, action: str, last_mission_success: bool
) -> Mission:
"""given a character, their action and the last mission success, return the next mission"""
@ai_fn
def create_game(character: StarWarsCharacter) -> Game:
"create a new game"
@ai_fn
def create_character() -> StarWarsCharacter:
"create a new character"
console.save_text(f"{game.name}-{character.name}-{game.id}.txt")
def game():
console.print("generating your character")
prompt = Prompt(console=console)
character = create_character()
game = create_game(character)
def save():
console.save_text(f"{game.name}-{character.name}-{game.id}.txt")
atexit.register(save)
while (
character.health > 0
and character.imperial_credits > 0
and character.ship.fuel_level > 0
):
console.print(character.describe)
action = prompt.ask("What do you do ")
result = did_complete_mission(character, action)
character.previous_missions.append((character.mission, result))
# keep only the last 5 missions
character.previous_missions = character.previous_missions[-5:]
character.imperial_credits -= result.imperial_credits_spent
character.imperial_credits += result.imperial_credits_earned
character.health -= result.health_lost
character.health += result.health_gained
character.ship.fuel_level -= result.fuel_used
console.print()
console.print("Your mission has been completed")
console.print(result.story)
console.print(f"You earned {result.imperial_credits_earned} imperial credits")
console.print(f"You spent {result.imperial_credits_spent} imperial credits")
console.print(f"You gained {result.health_gained} health")
console.print(f"You lost {result.health_lost} health")
character.mission = get_next_mission(character, action, result.success)
if character.health <= 0:
console.print("You are dead")
if character.imperial_credits <= 0:
console.print("You lost all your imperial credits")
if character.ship.fuel_level <= 0:
console.print("You lost all your fuel")
if __name__ == "__main__":
game()