Spaces:
Sleeping
Sleeping
Create bacckup2.py
Browse files- bacckup2.py +187 -0
bacckup2.py
ADDED
@@ -0,0 +1,187 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import os
|
3 |
+
import random
|
4 |
+
import time
|
5 |
+
from PIL import Image
|
6 |
+
import json
|
7 |
+
from datetime import datetime
|
8 |
+
from pathlib import Path
|
9 |
+
import base64
|
10 |
+
from io import BytesIO
|
11 |
+
|
12 |
+
# Constants for game board
|
13 |
+
GRID_WIDTH = 16
|
14 |
+
GRID_HEIGHT = 9
|
15 |
+
REFRESH_RATE = 5 # seconds
|
16 |
+
|
17 |
+
# Fantasy name generator
|
18 |
+
def generate_fantasy_name():
|
19 |
+
prefixes = ['Aer', 'Bal', 'Cal', 'Dor', 'El', 'Fae', 'Gor', 'Hel', 'Il', 'Jor',
|
20 |
+
'Kal', 'Lyr', 'Mel', 'Nym', 'Oro', 'Pyr', 'Qar', 'Ryn', 'Syl', 'Tyr']
|
21 |
+
suffixes = ['ian', 'or', 'ion', 'us', 'ix', 'ar', 'en', 'yr', 'el', 'an',
|
22 |
+
'is', 'ax', 'on', 'ir', 'ex', 'az', 'er', 'eth', 'ys', 'ix']
|
23 |
+
return random.choice(prefixes) + random.choice(suffixes)
|
24 |
+
|
25 |
+
# Initialize session state
|
26 |
+
if 'initialized' not in st.session_state:
|
27 |
+
st.session_state.initialized = False
|
28 |
+
st.session_state.game_state = {
|
29 |
+
'players': {},
|
30 |
+
'chat_messages': [],
|
31 |
+
'last_sync': time.time()
|
32 |
+
}
|
33 |
+
st.session_state.player_name = None
|
34 |
+
st.session_state.character_stats = None
|
35 |
+
st.session_state.position = {
|
36 |
+
'x': random.randint(0, GRID_WIDTH - 1),
|
37 |
+
'y': random.randint(0, GRID_HEIGHT - 1)
|
38 |
+
}
|
39 |
+
st.session_state.last_move = time.time()
|
40 |
+
|
41 |
+
def roll_stats():
|
42 |
+
return {
|
43 |
+
'STR': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]),
|
44 |
+
'DEX': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]),
|
45 |
+
'CON': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]),
|
46 |
+
'INT': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]),
|
47 |
+
'WIS': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]),
|
48 |
+
'CHA': sum(sorted([random.randint(1, 6) for _ in range(4)])[1:]),
|
49 |
+
'HP': random.randint(1, 20) * 2 + random.randint(1, 20),
|
50 |
+
'MAX_HP': 40,
|
51 |
+
'score': 0,
|
52 |
+
'created_at': time.time()
|
53 |
+
}
|
54 |
+
|
55 |
+
def save_character_sheet(player_name, stats):
|
56 |
+
"""Save character sheet as markdown"""
|
57 |
+
filepath = f"characters/{player_name}.md"
|
58 |
+
os.makedirs('characters', exist_ok=True)
|
59 |
+
|
60 |
+
markdown = f"""# {player_name}'s Character Sheet
|
61 |
+
|
62 |
+
## Stats
|
63 |
+
- **STR**: {stats['STR']}
|
64 |
+
- **DEX**: {stats['DEX']}
|
65 |
+
- **CON**: {stats['CON']}
|
66 |
+
- **INT**: {stats['INT']}
|
67 |
+
- **WIS**: {stats['WIS']}
|
68 |
+
- **CHA**: {stats['CHA']}
|
69 |
+
|
70 |
+
## Health
|
71 |
+
HP: {stats['HP']}/{stats['MAX_HP']}
|
72 |
+
|
73 |
+
## Score
|
74 |
+
Current Score: {stats['score']}
|
75 |
+
|
76 |
+
## Position
|
77 |
+
X: {st.session_state.position['x']}, Y: {st.session_state.position['y']}
|
78 |
+
|
79 |
+
## Session Info
|
80 |
+
Created: {datetime.fromtimestamp(stats['created_at']).strftime('%Y-%m-%d %H:%M:%S')}
|
81 |
+
Last Updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
82 |
+
"""
|
83 |
+
|
84 |
+
with open(filepath, 'w') as f:
|
85 |
+
f.write(markdown)
|
86 |
+
|
87 |
+
def load_character_sheet(player_name):
|
88 |
+
"""Load character sheet if it exists"""
|
89 |
+
filepath = f"characters/{player_name}.md"
|
90 |
+
if os.path.exists(filepath):
|
91 |
+
with open(filepath, 'r') as f:
|
92 |
+
return f.read()
|
93 |
+
return None
|
94 |
+
|
95 |
+
def update_position(direction):
|
96 |
+
"""Update player position with wrapping"""
|
97 |
+
if direction == "up":
|
98 |
+
st.session_state.position['y'] = (st.session_state.position['y'] - 1) % GRID_HEIGHT
|
99 |
+
elif direction == "down":
|
100 |
+
st.session_state.position['y'] = (st.session_state.position['y'] + 1) % GRID_HEIGHT
|
101 |
+
elif direction == "left":
|
102 |
+
st.session_state.position['x'] = (st.session_state.position['x'] - 1) % GRID_WIDTH
|
103 |
+
elif direction == "right":
|
104 |
+
st.session_state.position['x'] = (st.session_state.position['x'] + 1) % GRID_WIDTH
|
105 |
+
|
106 |
+
st.session_state.last_move = time.time()
|
107 |
+
if st.session_state.character_stats:
|
108 |
+
save_character_sheet(st.session_state.player_name, st.session_state.character_stats)
|
109 |
+
|
110 |
+
def create_game_board():
|
111 |
+
"""Create and display the game board"""
|
112 |
+
# Create placeholder images for tiles
|
113 |
+
tile_image = Image.new('RGB', (50, 50), color='green')
|
114 |
+
player_image = Image.new('RGB', (50, 50), color='blue')
|
115 |
+
|
116 |
+
# Create columns for each row
|
117 |
+
for y in range(GRID_HEIGHT):
|
118 |
+
cols = st.columns(GRID_WIDTH)
|
119 |
+
for x in range(GRID_WIDTH):
|
120 |
+
# Display player or tile
|
121 |
+
if (x == st.session_state.position['x'] and
|
122 |
+
y == st.session_state.position['y']):
|
123 |
+
cols[x].image(player_image, use_column_width=True)
|
124 |
+
else:
|
125 |
+
cols[x].image(tile_image, use_column_width=True)
|
126 |
+
|
127 |
+
def main():
|
128 |
+
# Sidebar for player info and controls
|
129 |
+
st.sidebar.title("Player Info")
|
130 |
+
|
131 |
+
# Player name handling
|
132 |
+
if st.session_state.player_name is None:
|
133 |
+
default_name = generate_fantasy_name()
|
134 |
+
player_name = st.sidebar.text_input("Enter your name or use generated name:",
|
135 |
+
value=default_name)
|
136 |
+
if st.sidebar.button("Start Playing"):
|
137 |
+
st.session_state.player_name = player_name
|
138 |
+
if st.session_state.character_stats is None:
|
139 |
+
st.session_state.character_stats = roll_stats()
|
140 |
+
save_character_sheet(player_name, st.session_state.character_stats)
|
141 |
+
st.rerun()
|
142 |
+
else:
|
143 |
+
# Show current name and allow changes
|
144 |
+
new_name = st.sidebar.text_input("Your name:",
|
145 |
+
value=st.session_state.player_name)
|
146 |
+
if new_name != st.session_state.player_name:
|
147 |
+
old_name = st.session_state.player_name
|
148 |
+
st.session_state.player_name = new_name
|
149 |
+
os.rename(f"characters/{old_name}.md",
|
150 |
+
f"characters/{new_name}.md")
|
151 |
+
st.rerun()
|
152 |
+
|
153 |
+
# Display character sheet
|
154 |
+
character_sheet = load_character_sheet(st.session_state.player_name)
|
155 |
+
if character_sheet:
|
156 |
+
st.sidebar.markdown(character_sheet)
|
157 |
+
|
158 |
+
# Movement controls
|
159 |
+
st.sidebar.markdown("### Movement Controls")
|
160 |
+
move_cols = st.sidebar.columns(3)
|
161 |
+
if move_cols[1].button("⬆️", key="up"):
|
162 |
+
update_position("up")
|
163 |
+
st.rerun()
|
164 |
+
cols = st.sidebar.columns(3)
|
165 |
+
if cols[0].button("⬅️", key="left"):
|
166 |
+
update_position("left")
|
167 |
+
st.rerun()
|
168 |
+
if cols[1].button("⬇️", key="down"):
|
169 |
+
update_position("down")
|
170 |
+
st.rerun()
|
171 |
+
if cols[2].button("➡️", key="right"):
|
172 |
+
update_position("right")
|
173 |
+
st.rerun()
|
174 |
+
|
175 |
+
# Main game area
|
176 |
+
st.title("Multiplayer Tile Game")
|
177 |
+
|
178 |
+
# Display game board
|
179 |
+
create_game_board()
|
180 |
+
|
181 |
+
# Auto-refresh logic
|
182 |
+
if (time.time() - st.session_state.last_move) > REFRESH_RATE:
|
183 |
+
st.session_state.last_move = time.time()
|
184 |
+
st.rerun()
|
185 |
+
|
186 |
+
if __name__ == "__main__":
|
187 |
+
main()
|