Files
2026-05-26 08:47:46 +00:00

148 lines
4.9 KiB
Python

"""
Text-based adventure game powered by OpenAI GPT-3.5.
Usage:
python main.py
The game accepts player commands and uses the LLM to generate the next scene or dialogue.
Interrupt feature:
Type "pause" to pause the game. The current state will be displayed and you can resume by typing "resume".
Type "exit" to quit the game.
Make sure to set the environment variable OPENAI_API_KEY before running.
"""
import os
import json
import sys
from pathlib import Path
import openai
# Constants
SYSTEM_PROMPT = (
"You are a text-based adventure game narrator. "
"Respond to the player's commands with vivid descriptions, dialogue, and actions. "
"Maintain continuity and immerse the player in the story. "
)
STATE_FILE = Path("game_state.json")
class AdventureGame:
def __init__(self, model="gpt-3.5-turbo"):
self.model = model
self.history = [] # list of dicts with role and content
self.last_user_input = ""
self.load_state()
def load_state(self):
if STATE_FILE.exists():
try:
data = json.loads(STATE_FILE.read_text())
self.history = data.get("history", [])
self.last_user_input = data.get("last_user_input", "")
print("[Game] Loaded previous state. Type 'resume' to continue.")
except Exception as e:
print(f"[Game] Failed to load state: {e}")
def save_state(self):
data = {
"history": self.history,
"last_user_input": self.last_user_input,
}
STATE_FILE.write_text(json.dumps(data))
def clear_state(self):
if STATE_FILE.exists():
STATE_FILE.unlink()
def generate(self, user_input: str) -> str:
self.last_user_input = user_input
# Build messages for chat completion
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
] + self.history + [
{"role": "user", "content": user_input},
]
try:
response = openai.ChatCompletion.create(
model=self.model,
messages=messages,
temperature=0.7,
max_tokens=512,
)
content = response.choices[0].message.content.strip()
# Append to history
self.history.append({"role": "user", "content": user_input})
self.history.append({"role": "assistant", "content": content})
self.save_state()
return content
except Exception as e:
return f"[Error] Failed to generate response: {e}"
def show_state(self):
print("\n--- Current Game State ---")
if not self.history:
print("No history yet.")
else:
for msg in self.history:
role = msg["role"]
print(f"{role.capitalize()}: {msg['content']}\n")
print("--- End of State ---\n")
def run(self):
print("Welcome to the LLM Adventure Game! Type 'help' for commands.")
while True:
try:
user_input = input("> ").strip()
except (EOFError, KeyboardInterrupt):
print("\nExiting game.")
self.clear_state()
sys.exit(0)
if not user_input:
continue
if user_input.lower() in ("exit", "quit"):
print("Goodbye!")
self.clear_state()
break
if user_input.lower() == "help":
print("Commands: pause, resume, help, exit")
continue
if user_input.lower() == "pause":
print("Game paused. Type 'resume' to continue or 'exit' to quit.")
self.show_state()
while True:
try:
cmd = input("(paused)> ").strip().lower()
except (EOFError, KeyboardInterrupt):
print("\nExiting game.")
self.clear_state()
sys.exit(0)
if cmd == "resume":
print("Resuming game...")
break
if cmd == "exit":
print("Goodbye!")
self.clear_state()
sys.exit(0)
if cmd == "help":
print("Commands while paused: resume, exit, help")
continue
print("Unknown command while paused. Type 'resume' or 'exit'.")
continue
# Regular input
response = self.generate(user_input)
print(response)
if __name__ == "__main__":
if not os.getenv("OPENAI_API_KEY"):
print("Error: OPENAI_API_KEY environment variable not set.")
sys.exit(1)
openai.api_key = os.getenv("OPENAI_API_KEY")
game = AdventureGame()
game.run()