import streamlit as st import os import random import time from PIL import Image import json from datetime import datetime from pathlib import Path import base64 from io import BytesIO import numpy as np GRID_WIDTH = 16 GRID_HEIGHT = 9 REFRESH_RATE = 10 INTERACTION_RADIUS = 2 POINTS_PER_INTERACTION = 1 @st.cache_resource def get_game_images(): return { 'tile': Image.new('RGB', (50, 50), color='green'), 'player': Image.new('RGB', (50, 50), color='blue'), 'other_player': Image.new('RGB', (50, 50), color='red') } @st.cache_data def get_name_components(): return { 'prefixes': ['Aer', 'Bal', 'Cal', 'Dor', 'El', 'Fae', 'Gor', 'Hel', 'Il', 'Jor', 'Kal', 'Lyr', 'Mel', 'Nym', 'Oro', 'Pyr', 'Qar', 'Ryn', 'Syl', 'Tyr'], 'suffixes': ['ian', 'or', 'ion', 'us', 'ix', 'ar', 'en', 'yr', 'el', 'an', 'is', 'ax', 'on', 'ir', 'ex', 'az', 'er', 'eth', 'ys', 'ix'] } @st.cache_data(ttl=2) def load_all_players(timestamp): players = {} if os.path.exists('players'): for filename in os.listdir('players'): if filename.endswith('.json'): with open(f"players/{filename}", 'r') as f: try: player_data = json.load(f) if time.time() - player_data['last_update'] < 60: players[player_data['name']] = player_data except json.JSONDecodeError: continue return {'players': players, 'last_update': time.time()} def create_sync_mechanism(): sync_js = """ """ st.components.v1.html(sync_js, height=0) def show_character_sheet(player_data): st.sidebar.markdown("### Character Sheet") st.sidebar.markdown(f""" **Name:** {player_data['name']} **Stats:** - HP: {player_data['stats']['HP']}/{player_data['stats']['MAX_HP']} - STR: {player_data['stats']['STR']} - DEX: {player_data['stats']['DEX']} - CON: {player_data['stats']['CON']} - INT: {player_data['stats']['INT']} - WIS: {player_data['stats']['WIS']} - CHA: {player_data['stats']['CHA']} **Score:** {player_data['stats']['score']} """) [Previous functions remain the same: generate_fantasy_name, load_game_state, save_game_state, calculate_distance, update_position, etc.] def main(): create_sync_mechanism() update_nearby_players() st.sidebar.title("Player Info") current_time = time.time() all_players = load_all_players(current_time)['players'] if st.session_state.player_name is None: default_name = generate_fantasy_name() player_name = st.sidebar.text_input("Enter your name or use generated name:", value=default_name) if st.sidebar.button("Start Playing"): st.session_state.player_name = player_name if st.session_state.character_stats is None: st.session_state.character_stats = { 'STR': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]), 'DEX': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]), 'CON': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]), 'INT': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]), 'WIS': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]), 'CHA': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]), 'HP': random.randint(1, 20) * 2 + random.randint(1, 20), 'MAX_HP': 40, 'score': 0, 'created_at': time.time() } save_player_state() st.rerun() else: show_character_sheet({'name': st.session_state.player_name, 'stats': st.session_state.character_stats}) st.sidebar.markdown("### Other Players") for player_name, player_data in all_players.items(): if player_name != st.session_state.player_name: show_character_sheet(player_data) st.sidebar.markdown("### Movement Controls") move_cols = st.sidebar.columns(3) if move_cols[1].button("⬆️", key="up"): update_position("up") st.rerun() cols = st.sidebar.columns(3) if cols[0].button("⬅️", key="left"): update_position("left") st.rerun() if cols[1].button("⬇️", key="down"): update_position("down") st.rerun() if cols[2].button("➡️", key="right"): update_position("right") st.rerun() if st.sidebar.button("Clear Game State"): st.query_params.clear() clear_caches() st.rerun() st.title("Multiplayer Tile Game") create_game_board() if (time.time() - st.session_state.last_move) > REFRESH_RATE: st.session_state.last_move = time.time() save_player_state() st.rerun() if __name__ == "__main__": main()