File size: 5,068 Bytes
2fb15db
 
 
 
 
b0a6ae6
2fb15db
 
 
 
 
 
b0a6ae6
 
2fb15db
 
 
 
 
 
b0a6ae6
 
2fb15db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b0a6ae6
2fb15db
 
b0a6ae6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2fb15db
b0a6ae6
 
2fb15db
 
b0a6ae6
 
 
 
 
 
 
 
 
2fb15db
 
 
 
b0a6ae6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2fb15db
 
 
 
 
b0a6ae6
 
 
2fb15db
 
 
 
 
 
 
 
 
 
 
 
b0a6ae6
 
 
 
2fb15db
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import streamlit as st
import json
import random
import time
import os
from streamlit_javascript import st_javascript

# Constants
GRID_SIZE = 10
MAX_PLAYERS = 10
UPDATE_INTERVAL = 3
GAME_STATE_FILE = "game_state.json"
CELL_SIZE = 50
PLAYER_SIZE = 40

# Initialize session state
if "player_name" not in st.session_state:
    st.session_state.player_name = f"Player_{random.randint(1000, 9999)}"
if "selected_player" not in st.session_state:
    st.session_state.selected_player = None
if "player_color" not in st.session_state:
    st.session_state.player_color = f"#{random.randint(0, 0xFFFFFF):06x}"

# Function to load game state
def load_game_state():
    if os.path.exists(GAME_STATE_FILE):
        with open(GAME_STATE_FILE, "r") as f:
            return json.load(f)
    return {"players": {}}

# Function to save game state
def save_game_state(state):
    with open(GAME_STATE_FILE, "w") as f:
        json.dump(state, f)

# Function to update player position
def update_player_position(player_name, x, y):
    state = load_game_state()
    if player_name in state["players"]:
        state["players"][player_name]["x"] = x
        state["players"][player_name]["y"] = y
    else:
        if len(state["players"]) < MAX_PLAYERS:
            state["players"][player_name] = {"x": x, "y": y, "color": st.session_state.player_color}
    save_game_state(state)

# Function to generate SVG for the game board
def generate_svg(game_state):
    svg = f'<svg width="{GRID_SIZE * CELL_SIZE}" height="{GRID_SIZE * CELL_SIZE}" xmlns="http://www.w3.org/2000/svg">'
    
    # Draw grid
    for i in range(GRID_SIZE):
        for j in range(GRID_SIZE):
            svg += f'<rect x="{i * CELL_SIZE}" y="{j * CELL_SIZE}" width="{CELL_SIZE}" height="{CELL_SIZE}" fill="white" stroke="gray" />'
    
    # Draw players
    for player, data in game_state["players"].items():
        x, y = data["x"] * CELL_SIZE + CELL_SIZE // 2, data["y"] * CELL_SIZE + CELL_SIZE // 2
        color = data.get("color", "#000000")
        svg += f'<circle cx="{x}" cy="{y}" r="{PLAYER_SIZE // 2}" fill="{color}">'
        svg += f'<animate attributeName="cx" from="{x}" to="{x}" dur="0.5s" repeatCount="1" />'
        svg += f'<animate attributeName="cy" from="{y}" to="{y}" dur="0.5s" repeatCount="1" />'
        svg += '</circle>'
        svg += f'<text x="{x}" y="{y + 5}" text-anchor="middle" fill="white" font-size="12">{player[0].upper()}</text>'
    
    svg += '</svg>'
    return svg

# Streamlit app
st.set_page_config(layout="wide")
st.title("Enhanced Multiplayer Grid Game")

# Display player name and allow updates
col1, col2 = st.columns([3, 1])
with col1:
    player_name = st.text_input("Your name", value=st.session_state.player_name)
    if player_name != st.session_state.player_name:
        st.session_state.player_name = player_name
        update_player_position(player_name, GRID_SIZE // 2, GRID_SIZE // 2)

with col2:
    st.color_picker("Choose your color", value=st.session_state.player_color, key="player_color")

# Create grid
grid = st.empty()

# JavaScript for smooth movement
js_code = """
function movePlayer(playerId, fromX, fromY, toX, toY) {
    const player = document.getElementById(playerId);
    if (player) {
        const animateX = player.getElementsByTagName('animate')[0];
        const animateY = player.getElementsByTagName('animate')[1];
        animateX.setAttribute('from', fromX);
        animateX.setAttribute('to', toX);
        animateY.setAttribute('from', fromY);
        animateY.setAttribute('to', toY);
        animateX.beginElement();
        animateY.beginElement();
    }
}
"""

st.components.v1.html(f"<script>{js_code}</script>", height=0)

# Main game loop
while True:
    # Load current game state
    game_state = load_game_state()
    
    # Generate and display SVG
    svg = generate_svg(game_state)
    grid.markdown(svg, unsafe_allow_html=True)
    
    # Handle player movement
    col1, col2 = st.columns(2)
    with col1:
        if st.button("Select Your Character"):
            st.session_state.selected_player = st.session_state.player_name
    
    with col2:
        if st.session_state.selected_player:
            target_x = st.number_input("Target X", min_value=0, max_value=GRID_SIZE-1, value=GRID_SIZE//2)
            target_y = st.number_input("Target Y", min_value=0, max_value=GRID_SIZE-1, value=GRID_SIZE//2)
            if st.button("Move"):
                current_pos = game_state["players"].get(st.session_state.player_name, {"x": GRID_SIZE // 2, "y": GRID_SIZE // 2})
                from_x, from_y = current_pos["x"] * CELL_SIZE + CELL_SIZE // 2, current_pos["y"] * CELL_SIZE + CELL_SIZE // 2
                to_x, to_y = target_x * CELL_SIZE + CELL_SIZE // 2, target_y * CELL_SIZE + CELL_SIZE // 2
                st_javascript(f"movePlayer('{st.session_state.player_name}', {from_x}, {from_y}, {to_x}, {to_y})")
                update_player_position(st.session_state.player_name, target_x, target_y)
    
    # Wait for update interval
    time.sleep(UPDATE_INTERVAL)
    st.experimental_rerun()