Spaces:
Runtime error
Runtime error
# Rich CLI interface for the Wiki Run game | |
from rich.console import Console | |
from rich.panel import Panel | |
from rich.markdown import Markdown | |
from rich.prompt import Prompt | |
from rich.table import Table | |
from engine import WikiRunEnvironment | |
from BFS_solver import WikiSolver | |
console = Console() | |
class WikiRunCLI: | |
def __init__(self, wiki_data_path): | |
"""Initialize the CLI interface""" | |
self.env = WikiRunEnvironment(wiki_data_path) | |
self.console = Console() | |
def _display_article(self, state): | |
"""Display the current article with highlighted links""" | |
title = state['current_article'] | |
text = state['article_text'] | |
links = state['available_links'] | |
# Create a panel with article title | |
console.print(Panel(f"[bold cyan]{title}[/bold cyan]", | |
expand=False, | |
border_style="cyan")) | |
# Display article text with highlighted links | |
# In a real implementation, we'd need to properly format | |
# the links within the text, but for MVP this is simpler | |
md = Markdown(text) | |
console.print(md) | |
# Display available links | |
console.print("\n[bold green]Available Links:[/bold green]") | |
# Create a table for links (3 columns) | |
table = Table(show_header=False, box=None) | |
table.add_column("Link 1", style="green") | |
table.add_column("Link 2", style="green") | |
table.add_column("Link 3", style="green") | |
# Add links to table (3 per row) | |
row = [] | |
for i, link in enumerate(links): | |
# Check if link is available in the current article | |
is_available = self.env.article_exists(link) | |
color = "green" if is_available else "red" | |
row.append(f"[{color}]{i+1}. {link}[/{color}]") | |
if len(row) == 3: | |
table.add_row(*row) | |
row = [] | |
# Add any remaining links | |
if row: | |
table.add_row(*row + [''] * (3 - len(row))) | |
console.print(table) | |
def _display_game_info(self, state): | |
"""Display game information""" | |
console.print("\n[bold yellow]Game Info:[/bold yellow]") | |
console.print(f"Target Article: [bold red]{state['target_article']}[/bold red]") | |
console.print(f"Steps Taken: [bold]{state['steps_taken']}[/bold]") | |
console.print(f"Path: [italic]{' β '.join(state['path_taken'])}[/italic]") | |
def play(self): | |
"""Main game loop""" | |
console.clear() | |
console.print("[bold]Welcome to Wiki Run![/bold]") | |
console.print("Navigate from one Wikipedia article to another using only links.\n") | |
# Let user choose between random articles, specific ones, or solver mode | |
choice = Prompt.ask("Choose mode: [bold]r[/bold]andom articles, [bold]s[/bold]pecific ones, or [bold]p[/bold]ath solver?", | |
choices=["r", "s", "p"], | |
default="r") | |
if choice == "p": | |
# Solver mode | |
available_articles = self.env.db.get_all_article_titles() | |
console.print(f"Available articles: {len(available_articles)}") | |
# Show a sample of available articles | |
import random | |
sample = random.sample(available_articles, min(10, len(available_articles))) | |
console.print("Sample articles:") | |
for article in sample: | |
console.print(f"- {article}") | |
start = Prompt.ask("Start article") | |
target = Prompt.ask("Target article") | |
# Initialize solver and find path | |
solver = WikiSolver(self.env) | |
path, error = solver.find_path(start, target) | |
if error: | |
console.print(f"[red]{error}[/red]") | |
else: | |
solver.display_solution(path, start, target) | |
play_again = Prompt.ask("Try another path? (y/n)", choices=["y", "n"], default="y") | |
if play_again == "y": | |
self.play() | |
return | |
if choice == "r": | |
state = self.env.reset() | |
else: | |
# Get start and target articles | |
available_articles = self.env.db.get_all_article_titles() | |
console.print(f"Available articles: {len(available_articles)}") | |
# Show a sample of available articles | |
import random | |
sample = random.sample(available_articles, min(10, len(available_articles))) | |
console.print("Sample articles:") | |
for article in sample: | |
console.print(f"- {article}") | |
start = Prompt.ask("Start article") | |
target = Prompt.ask("Target article") | |
state = self.env.reset(start, target) | |
# Main game loop | |
while not state['is_complete']: | |
console.clear() | |
self._display_article(state) | |
self._display_game_info(state) | |
# Get user input | |
choice = Prompt.ask("\nChoose a link (number) or type part of a link name", | |
default="") | |
# Process input | |
links = state['available_links'] | |
next_article = None | |
try: | |
# Check if input is a number | |
idx = int(choice) - 1 | |
if 0 <= idx < len(links): | |
next_article = links[idx] | |
except ValueError: | |
# Input is text, find closest match | |
matches = [link for link in links if choice.lower() in link.lower()] | |
if len(matches) == 1: | |
next_article = matches[0] | |
elif len(matches) > 1: | |
console.print("[yellow]Multiple matches found:[/yellow]") | |
for i, match in enumerate(matches): | |
console.print(f"{i+1}. {match}") | |
sub_choice = Prompt.ask("Choose a match (number)", default="1") | |
try: | |
idx = int(sub_choice) - 1 | |
if 0 <= idx < len(matches): | |
next_article = matches[idx] | |
except ValueError: | |
pass | |
if next_article: | |
state, message = self.env.step(next_article) | |
if message: | |
console.print(f"[bold]{message}[/bold]") | |
if state['is_complete']: | |
break | |
else: | |
console.print("[red]Invalid choice. Try again.[/red]") | |
console.input("\nPress Enter to continue...") | |
# Game complete | |
console.clear() | |
console.print("[bold green]Congratulations! You've reached the target article![/bold green]") | |
console.print(f"You took [bold]{state['steps_taken']}[/bold] steps.") | |
console.print(f"Your path: [italic]{' β '.join(state['path_taken'])}[/italic]") | |
play_again = Prompt.ask("Play again? (y/n)", choices=["y", "n"], default="y") | |
if play_again == "y": | |
self.play() | |
if __name__ == "__main__": | |
import sys | |
if len(sys.argv) < 2: | |
console.print("[red]Please provide the path to Wikipedia data[/red]") | |
console.print("Usage: python cli.py <wiki_data_path>") | |
sys.exit(1) | |
wiki_data_path = sys.argv[1] | |
game = WikiRunCLI(wiki_data_path) | |
game.play() | |