DarshanScripts commited on
Commit
bedc00b
Β·
verified Β·
1 Parent(s): 296c7da

Upload stratego\web\components\board_display.py with huggingface_hub

Browse files
stratego//web//components//board_display.py ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Beautiful board display component with emojis and proper styling"""
2
+ import streamlit as st
3
+ from stratego.utils.parsing import extract_board_block_lines, extract_legal_moves
4
+
5
+
6
+ # Piece emoji mapping - makes board much more visual
7
+ PIECE_EMOJI = {
8
+ "fl": "🚩", # Flag
9
+ "bm": "πŸ’£", # Bomb
10
+ "ms": "πŸ‘‘", # Marshal (Crown)
11
+ "gn": "⭐", # General (Star)
12
+ "mn": "⛏️", # Miner
13
+ "sc": "πŸƒ", # Scout (Running person)
14
+ "sp": "πŸ•΅οΈ", # Spy
15
+ "sr": "πŸͺ–", # Sergeant (Helmet)
16
+ "lt": "πŸ“", # Lieutenant (Pin)
17
+ "cp": "πŸŽ–οΈ", # Captain (Medal)
18
+ "mx": "❓", # Unknown enemy
19
+ ".": " ", # Empty
20
+ "~": "πŸ’§", # Lake
21
+ }
22
+
23
+
24
+ def render_board(game_controller, background_color="auto"):
25
+ """Render a beautiful game board with emojis and great styling"""
26
+ if not game_controller:
27
+ st.error("Game not initialized")
28
+ return
29
+
30
+ board = game_controller.get_board_display()
31
+ lines = board.split("\n")
32
+
33
+ # Find where board starts
34
+ board_start = 0
35
+ for i, line in enumerate(lines):
36
+ if line.strip().startswith("0"):
37
+ board_start = i + 1
38
+ break
39
+
40
+ board_lines = lines[board_start:]
41
+
42
+ # Extract board data
43
+ size = game_controller.size
44
+ board_data = {}
45
+
46
+ for line in board_lines:
47
+ if not line.strip() or len(line) < 3:
48
+ continue
49
+ row_label = line[0] if line and line[0].isalpha() else None
50
+ if not row_label:
51
+ continue
52
+
53
+ rest = line[2:].strip()
54
+ pieces = rest.split()
55
+
56
+ if len(pieces) >= size:
57
+ for col, piece in enumerate(pieces[:size]):
58
+ board_data[(row_label, col)] = piece
59
+
60
+ # Create beautiful HTML board
61
+ html_board = create_beautiful_board_html(board_data, size)
62
+
63
+ st.markdown("## βš”οΈ Stratego Battle Board", help="Blue = Your Army | Red = Enemy Army")
64
+ st.markdown(html_board, unsafe_allow_html=True)
65
+
66
+ # Legend
67
+ legend_col1, legend_col2, legend_col3 = st.columns(3)
68
+ with legend_col1:
69
+ st.markdown("πŸ”΅ **Your Pieces** - Blue Background")
70
+ with legend_col2:
71
+ st.markdown("πŸ”΄ **Enemy Pieces** - Red with ❓")
72
+ with legend_col3:
73
+ st.markdown("πŸ’§ **Lakes** - Blocked Water")
74
+
75
+
76
+ def create_beautiful_board_html(board_data, size) -> str:
77
+ """Create a beautiful, professional-looking board"""
78
+
79
+ html = """
80
+ <style>
81
+ .board-wrapper {
82
+ background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
83
+ padding: 20px;
84
+ border-radius: 15px;
85
+ box-shadow: 0 10px 30px rgba(0,0,0,0.3);
86
+ display: inline-block;
87
+ margin: 20px 0;
88
+ }
89
+
90
+ .board-grid {
91
+ display: grid;
92
+ grid-template-columns: 40px repeat(""" + str(size) + """, 50px);
93
+ grid-template-rows: 40px repeat(""" + str(size) + """, 50px);
94
+ gap: 2px;
95
+ background-color: #1a1a2e;
96
+ padding: 10px;
97
+ border-radius: 10px;
98
+ }
99
+
100
+ .col-header {
101
+ background: linear-gradient(180deg, #3d5a80 0%, #2a5298 100%);
102
+ color: white;
103
+ display: flex;
104
+ align-items: center;
105
+ justify-content: center;
106
+ font-weight: bold;
107
+ font-size: 14px;
108
+ border-radius: 5px;
109
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.2);
110
+ }
111
+
112
+ .row-header {
113
+ background: linear-gradient(90deg, #3d5a80 0%, #2a5298 100%);
114
+ color: white;
115
+ display: flex;
116
+ align-items: center;
117
+ justify-content: center;
118
+ font-weight: bold;
119
+ font-size: 14px;
120
+ border-radius: 5px;
121
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.2);
122
+ }
123
+
124
+ .cell {
125
+ width: 50px;
126
+ height: 50px;
127
+ display: flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ font-size: 24px;
131
+ border-radius: 8px;
132
+ cursor: pointer;
133
+ transition: all 0.2s ease;
134
+ border: 1px solid rgba(255,255,255,0.1);
135
+ }
136
+
137
+ .cell:hover {
138
+ transform: scale(1.05);
139
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
140
+ }
141
+
142
+ .cell-empty {
143
+ background: linear-gradient(135deg, #34495e 0%, #2c3e50 100%);
144
+ color: #555;
145
+ }
146
+
147
+ .cell-your-piece {
148
+ background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
149
+ color: white;
150
+ box-shadow: 0 4px 15px rgba(52, 152, 219, 0.4);
151
+ font-weight: bold;
152
+ }
153
+
154
+ .cell-your-piece:hover {
155
+ background: linear-gradient(135deg, #5dade2 0%, #3498db 100%);
156
+ }
157
+
158
+ .cell-enemy-piece {
159
+ background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
160
+ color: white;
161
+ box-shadow: 0 4px 15px rgba(231, 76, 60, 0.4);
162
+ font-weight: bold;
163
+ }
164
+
165
+ .cell-enemy-piece:hover {
166
+ background: linear-gradient(135deg, #ec7063 0%, #e74c3c 100%);
167
+ }
168
+
169
+ .cell-lake {
170
+ background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
171
+ color: white;
172
+ box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3);
173
+ animation: wave 3s ease-in-out infinite;
174
+ }
175
+
176
+ @keyframes wave {
177
+ 0%, 100% { opacity: 0.7; }
178
+ 50% { opacity: 1; }
179
+ }
180
+
181
+ .turn-indicator {
182
+ text-align: center;
183
+ font-size: 18px;
184
+ font-weight: bold;
185
+ margin: 15px 0;
186
+ padding: 10px;
187
+ background: linear-gradient(90deg, #f39c12 0%, #e67e22 100%);
188
+ color: white;
189
+ border-radius: 8px;
190
+ box-shadow: 0 4px 10px rgba(0,0,0,0.2);
191
+ }
192
+ </style>
193
+
194
+ <div class="board-wrapper">
195
+ <div class="board-grid">
196
+ """
197
+
198
+ # Column headers
199
+ html += '<div class="col-header"></div>' # Corner placeholder
200
+ for col in range(size):
201
+ html += f'<div class="col-header">{col}</div>'
202
+
203
+ # Rows with pieces
204
+ rows = [chr(ord('A') + i) for i in range(size)]
205
+
206
+ for row in rows:
207
+ # Row header
208
+ html += f'<div class="row-header">{row}</div>'
209
+
210
+ # Cells
211
+ for col in range(size):
212
+ piece = board_data.get((row, col), ".")
213
+
214
+ if piece == "~":
215
+ cell_class = "cell cell-lake"
216
+ emoji = PIECE_EMOJI.get(piece, "πŸ’§")
217
+ elif piece == ".":
218
+ cell_class = "cell cell-empty"
219
+ emoji = ""
220
+ elif piece == "?":
221
+ cell_class = "cell cell-enemy-piece"
222
+ emoji = PIECE_EMOJI.get(piece, "❓")
223
+ else:
224
+ cell_class = "cell cell-your-piece"
225
+ emoji = PIECE_EMOJI.get(piece, "πŸŽ–οΈ")
226
+
227
+ html += f'<div class="{cell_class}">{emoji}</div>'
228
+
229
+ html += """
230
+ </div>
231
+ </div>
232
+ """
233
+
234
+ return html
235
+
236
+
237
+ def render_legal_moves(game_controller):
238
+ """Display available legal moves"""
239
+ if not game_controller:
240
+ return []
241
+
242
+ legal_moves = game_controller.get_legal_moves()
243
+ if legal_moves:
244
+ moves_str = " | ".join(legal_moves[:8])
245
+ st.caption(f"Available moves: {moves_str}")
246
+ return legal_moves