d-day-game / app.py
Bc-AI's picture
Update app.py
85c584c verified
raw
history blame
6.64 kB
import random
import time
import gradio as gr
class SavingPrivateRyanDefinitive:
def __init__(self):
# Game State
self.mode = "Stable"
self.current_mission = 1
self.total_missions = 5
self.distance = 0
self.game_over = False
self.ryan_found = False
self.miller_wounded = False
# Plot-Specific Locations
self.missions = {
1: {"name": "Omaha Beach", "goal": 300, "desc": "Dog One Sector. The Atlantic Wall."},
2: {"name": "Neuville Village", "goal": 400, "desc": "Searching for Ryan. Sniper territory."},
3: {"name": "Radar Station", "goal": 500, "desc": "The hills of Normandy. German MG nest ahead."},
4: {"name": "Battle of Ramelle", "goal": 600, "desc": "Hold the bridge at all costs."},
5: {"name": "Normandy Cemetery", "goal": 100, "desc": "Present Day. Colleville-sur-Mer."}
}
# The Actual 2nd Ranger Squad
# Format: status, death_mission, death_distance, final_words
self.squad = {
"Capt. Miller": {"status": "Alive", "death": (4, 590), "words": "James... earn this. Earn it."},
"Sgt. Horvath": {"status": "Alive", "death": (4, 550), "words": "I moved the rock..."},
"Pvt. Reiben": {"status": "Alive", "death": (9, 999), "words": "I'm going home."},
"Pvt. Jackson": {"status": "Alive", "death": (4, 450), "words": "Be not far from me, for trouble is near."},
"Pvt. Mellish": {"status": "Alive", "death": (4, 500), "words": "Give 'em hell!"},
"Pvt. Caparzo": {"status": "Alive", "death": (2, 200), "words": "It's for the kid's father."},
"Medic Wade": {"status": "Alive", "death": (3, 250), "words": "I want to go home... Mama..."},
"Cpl. Upham": {"status": "Alive", "death": (9, 999), "words": "FUBAR."}
}
def get_beta_visuals(self):
"""Generates the Graphical UI elements for Beta Mode"""
if self.mode == "Stable": return ""
progress = int((self.distance / self.missions[self.current_mission]["goal"]) * 15)
bar = "β–ˆ" * progress + "β–‘" * (15 - progress)
status_icons = "".join([f"[{n[5:8]}:{'πŸ’š' if s['status']=='Alive' else 'πŸ’€'}]" for n, s in self.squad.items()])
visual = f"\n{'='*50}\n"
visual += f"πŸ“ SECTOR: {self.missions[self.current_mission]['name'].upper()}\n"
visual += f"πŸ—ΊοΈ MAP PROGRESS: |{bar}| {self.distance}m\n"
visual += f"πŸ‘₯ SQUAD VITALS: {status_icons}\n"
visual += f"{'='*50}\n"
return visual
def get_chatter(self):
living = [n for n, s in self.squad.items() if s["status"] == "Alive" and n != "Capt. Miller"]
if not living: return "Miller: 'Keep moving!'"
speaker = random.choice(living)
quotes = [
"What's the pool up to? I've got 300 on the Captain.",
"FUBAR. Everything is FUBAR.",
"You think Ryan's worth all this?",
"Keep five yards! Don't bunch up!",
"I haven't had a decent meal since Portsmouth."
]
return f"{speaker}: '{random.choice(quotes)}'"
def handle_plot(self):
plot_log = ""
# Check for scripted deaths
for name, info in self.squad.items():
m_death, d_death = info["death"]
if self.current_mission == m_death and self.distance >= d_death and info["status"] == "Alive":
info["status"] = "Dead"
plot_log += f"\n🚨 CINEMATIC EVENT: {name} has been hit! {info['words']}\n"
if name == "Capt. Miller":
self.miller_wounded = True
# Plot Beats
if self.current_mission == 3 and self.distance > 300:
plot_log += "\nπŸ“– STORY: Miller stops the squad's infighting. 'I'm a schoolteacher from Pennsylvania.' The squad goes silent.\n"
if self.current_mission == 4 and self.distance > 100 and not self.ryan_found:
self.ryan_found = True
plot_log += "\n✨ STORY: Private James Francis Ryan found. He won't leave his post. Miller: 'Rally on the bridge!'\n"
return plot_log
def play(self, action, mode):
self.mode = mode
if self.game_over: return "The mission is over. James Ryan is home.", "End of File"
# Movement and Narrative
advance = random.randint(45, 85)
self.distance += advance
# Build Output
output = self.get_beta_visuals()
output += f"\nπŸ“’ {self.get_chatter()}\n"
output += self.handle_plot()
# Check Mission Completion
if self.distance >= self.missions[self.current_mission]["goal"]:
if self.current_mission < self.total_missions:
self.current_mission += 1
self.distance = 0
output += f"\nβœ… MISSION COMPLETE. Transitioning to {self.missions[self.current_mission]['name']}...\n"
else:
self.game_over = True
output += "\nπŸ•ŠοΈ FINAL SCENE: 'Tell me I'm a good man.' Ryan salutes the grave. Fade to black.\n"
# Special Death Logic for Miller
if self.miller_wounded:
output += "\n🎬 [BETA]: P-51 Mustangs scream overhead. The Tiger tank is destroyed. Miller looks at Ryan... 'Earn this.'\n"
self.current_mission = 5 # Skip to Cemetery
self.distance = 0
self.miller_wounded = False
status_str = f"Mission {self.current_mission}: {self.missions[self.current_mission]['name']}"
return output, status_str
# UI Assembly
def run_app():
game_engine = SavingPrivateRyanDefinitive()
with gr.Blocks(theme=gr.themes.Monochrome(), title="Saving Private Ryan") as demo:
gr.Markdown("# πŸŽ–οΈ SAVING PRIVATE RYAN: THE DEFINITIVE CAMPAIGN")
gr.Markdown("Experience the full journey from Omaha Beach to the final sacrifice.")
with gr.Row():
mode_select = gr.Radio(["Stable", "Beta"], label="Interface", value="Beta")
action_btn = gr.Button("ADVANCE SQUAD", variant="primary")
with gr.Row():
text_output = gr.TextArea(label="Battlefield Journal", lines=22)
meta_status = gr.Textbox(label="Current Objective")
action_btn.click(
game_engine.play,
inputs=[gr.State("move"), mode_select],
outputs=[text_output, meta_status]
)
demo.launch()
if __name__ == "__main__":
run_app()