import gradio as gr import json from leaderboard_utils import ( get_mario_leaderboard, get_sokoban_leaderboard, get_2048_leaderboard, get_candy_leaderboard, get_tetris_leaderboard, get_tetris_planning_leaderboard, get_combined_leaderboard, GAME_ORDER ) from data_visualization import ( get_combined_leaderboard_with_group_bar, create_horizontal_bar_chart, get_combined_leaderboard_with_single_radar ) import pandas as pd # Define time points and their corresponding data files TIME_POINTS = { "03/25/2025": "rank_data_03_25_2025.json", # Add more time points here as they become available } # Load the initial JSON file with rank data with open(TIME_POINTS["03/25/2025"], "r") as f: rank_data = json.load(f) # Add leaderboard state at the top level leaderboard_state = { "current_game": None, "previous_overall": { "Super Mario Bros": True, "Sokoban": True, "2048": True, "Candy Crash": True, "Tetris (complete)": True, "Tetris (planning only)": True }, "previous_details": { "Super Mario Bros": False, "Sokoban": False, "2048": False, "Candy Crash": False, "Tetris (complete)": False, "Tetris (planning only)": False } } def load_rank_data(time_point): """Load rank data for a specific time point""" if time_point in TIME_POINTS: try: with open(TIME_POINTS[time_point], "r") as f: return json.load(f) except FileNotFoundError: return None return None def update_leaderboard(mario_overall, mario_details, sokoban_overall, sokoban_details, _2048_overall, _2048_details, candy_overall, candy_details, tetris_overall, tetris_details, tetris_plan_overall, tetris_plan_details): global leaderboard_state # Convert current checkbox states to dictionary for easier comparison current_overall = { "Super Mario Bros": mario_overall, "Sokoban": sokoban_overall, "2048": _2048_overall, "Candy Crash": candy_overall, "Tetris (complete)": tetris_overall, "Tetris (planning only)": tetris_plan_overall } current_details = { "Super Mario Bros": mario_details, "Sokoban": sokoban_details, "2048": _2048_details, "Candy Crash": candy_details, "Tetris (complete)": tetris_details, "Tetris (planning only)": tetris_plan_details } # Find which game's state changed changed_game = None for game in current_overall.keys(): if (current_overall[game] != leaderboard_state["previous_overall"][game] or current_details[game] != leaderboard_state["previous_details"][game]): changed_game = game break if changed_game: # If a game's details checkbox was checked if current_details[changed_game] and not leaderboard_state["previous_details"][changed_game]: # Reset all other games' states for game in current_overall.keys(): if game != changed_game: current_overall[game] = False current_details[game] = False leaderboard_state["previous_overall"][game] = False leaderboard_state["previous_details"][game] = False # Update state for the selected game leaderboard_state["current_game"] = changed_game leaderboard_state["previous_overall"][changed_game] = True leaderboard_state["previous_details"][changed_game] = True current_overall[changed_game] = True # If a game's overall checkbox was checked elif current_overall[changed_game] and not leaderboard_state["previous_overall"][changed_game]: # If we were in details view for another game, switch to overall view if leaderboard_state["current_game"] and leaderboard_state["previous_details"][leaderboard_state["current_game"]]: # Reset previous game's details leaderboard_state["previous_details"][leaderboard_state["current_game"]] = False current_details[leaderboard_state["current_game"]] = False leaderboard_state["current_game"] = None # Update state leaderboard_state["previous_overall"][changed_game] = True leaderboard_state["previous_details"][changed_game] = False # If a game's overall checkbox was unchecked elif not current_overall[changed_game] and leaderboard_state["previous_overall"][changed_game]: # If we're in details view, don't allow unchecking the overall checkbox if leaderboard_state["current_game"] == changed_game: current_overall[changed_game] = True else: leaderboard_state["previous_overall"][changed_game] = False if leaderboard_state["current_game"] == changed_game: leaderboard_state["current_game"] = None # If a game's details checkbox was unchecked elif not current_details[changed_game] and leaderboard_state["previous_details"][changed_game]: leaderboard_state["previous_details"][changed_game] = False if leaderboard_state["current_game"] == changed_game: leaderboard_state["current_game"] = None # When exiting details view, reset to show all games for game in current_overall.keys(): current_overall[game] = True current_details[game] = False leaderboard_state["previous_overall"][game] = True leaderboard_state["previous_details"][game] = False # Special case: If all games are selected and we're trying to view details all_games_selected = all(current_overall.values()) and not any(current_details.values()) if all_games_selected and changed_game and current_details[changed_game]: # Reset all other games' states for game in current_overall.keys(): if game != changed_game: current_overall[game] = False current_details[game] = False leaderboard_state["previous_overall"][game] = False leaderboard_state["previous_details"][game] = False # Update state for the selected game leaderboard_state["current_game"] = changed_game leaderboard_state["previous_overall"][changed_game] = True leaderboard_state["previous_details"][changed_game] = True current_overall[changed_game] = True # Build dictionary for selected games selected_games = { "Super Mario Bros": current_overall["Super Mario Bros"], "Sokoban": current_overall["Sokoban"], "2048": current_overall["2048"], "Candy Crash": current_overall["Candy Crash"], "Tetris (complete)": current_overall["Tetris (complete)"], "Tetris (planning only)": current_overall["Tetris (planning only)"] } # Get the appropriate DataFrame and charts based on current state if leaderboard_state["current_game"]: # For detailed view if leaderboard_state["current_game"] == "Super Mario Bros": df = get_mario_leaderboard(rank_data) elif leaderboard_state["current_game"] == "Sokoban": df = get_sokoban_leaderboard(rank_data) elif leaderboard_state["current_game"] == "2048": df = get_2048_leaderboard(rank_data) elif leaderboard_state["current_game"] == "Candy Crash": df = get_candy_leaderboard(rank_data) elif leaderboard_state["current_game"] == "Tetris (complete)": df = get_tetris_leaderboard(rank_data) else: # Tetris (planning only) df = get_tetris_planning_leaderboard(rank_data) # Always create a new chart for detailed view chart = create_horizontal_bar_chart(df, leaderboard_state["current_game"]) # For detailed view, we'll use the same chart for all visualizations radar_chart = chart group_bar_chart = chart else: # For overall view df, group_bar_chart = get_combined_leaderboard_with_group_bar(rank_data, selected_games) # Use the same selected_games for radar chart _, radar_chart = get_combined_leaderboard_with_single_radar(rank_data, selected_games) chart = group_bar_chart # Return exactly 16 values to match the expected outputs return (df, chart, radar_chart, group_bar_chart, current_overall["Super Mario Bros"], current_details["Super Mario Bros"], current_overall["Sokoban"], current_details["Sokoban"], current_overall["2048"], current_details["2048"], current_overall["Candy Crash"], current_details["Candy Crash"], current_overall["Tetris (complete)"], current_details["Tetris (complete)"], current_overall["Tetris (planning only)"], current_details["Tetris (planning only)"]) def update_leaderboard_with_time(time_point, mario_overall, mario_details, sokoban_overall, sokoban_details, _2048_overall, _2048_details, candy_overall, candy_details, tetris_overall, tetris_details, tetris_plan_overall, tetris_plan_details): # Load rank data for the selected time point global rank_data new_rank_data = load_rank_data(time_point) if new_rank_data is not None: rank_data = new_rank_data # Use the existing update_leaderboard function return update_leaderboard(mario_overall, mario_details, sokoban_overall, sokoban_details, _2048_overall, _2048_details, candy_overall, candy_details, tetris_overall, tetris_details, tetris_plan_overall, tetris_plan_details) def get_initial_state(): """Get the initial state for the leaderboard""" return { "current_game": None, "previous_overall": { "Super Mario Bros": True, "Sokoban": True, "2048": True, "Candy Crash": True, "Tetris (complete)": True, "Tetris (planning only)": True }, "previous_details": { "Super Mario Bros": False, "Sokoban": False, "2048": False, "Candy Crash": False, "Tetris (complete)": False, "Tetris (planning only)": False } } def clear_filters(): global leaderboard_state # Reset all checkboxes to default state selected_games = { "Super Mario Bros": True, "Sokoban": True, "2048": True, "Candy Crash": True, "Tetris (complete)": True, "Tetris (planning only)": True } # Get the combined leaderboard and group bar chart df, group_bar_chart = get_combined_leaderboard_with_group_bar(rank_data, selected_games) # Get the radar chart using the same selected games _, radar_chart = get_combined_leaderboard_with_single_radar(rank_data, selected_games) # Reset the leaderboard state to match the default checkbox states leaderboard_state = get_initial_state() # Return exactly 16 values to match the expected outputs return (df, group_bar_chart, radar_chart, group_bar_chart, True, False, # mario True, False, # sokoban True, False, # 2048 True, False, # candy True, False, # tetris True, False) # tetris plan def create_timeline_slider(): """Create a custom timeline slider component""" timeline_html = """