sagar007 commited on
Commit
3ddf78f
·
verified ·
1 Parent(s): fec93e3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +185 -328
app.py CHANGED
@@ -1,353 +1,210 @@
1
  import gradio as gr
2
- import numpy as np
3
  import random
 
4
  from PIL import Image, ImageDraw, ImageFont
5
- import io
6
- import base64
7
 
8
- class LudoGame:
9
  def __init__(self):
10
- # Player colors
11
- self.colors = ["red", "green", "yellow", "blue"]
12
- self.color_codes = {
13
- "red": "#FF5555",
14
- "green": "#55FF55",
15
- "yellow": "#FFFF55",
16
- "blue": "#5555FF",
17
- "white": "#FFFFFF",
18
- "black": "#000000"
 
 
 
 
 
 
 
19
  }
20
 
21
- # Game state
22
- self.reset_game()
23
-
24
- def reset_game(self):
25
- # Initialize game state
 
 
 
 
 
 
 
 
 
26
  self.current_player = 0
27
- self.dice_value = 1
28
- self.dice_rolled = False
29
  self.winner = None
 
30
 
31
- # Initialize tokens (4 tokens per player)
32
- self.tokens = {}
33
- for i, color in enumerate(self.colors):
34
- self.tokens[color] = [-1, -1, -1, -1] # -1 means in home
35
-
36
- # Track if player can play after rolling
37
- self.can_play = False
38
-
39
- # Game messages
40
- self.message = f"Game started! {self.colors[self.current_player].capitalize()}'s turn to roll."
41
-
42
  def roll_dice(self):
43
- """Roll the dice and return the value"""
44
- if self.winner:
45
- return self.render_board()
46
-
47
- if self.dice_rolled:
48
- self.message = f"You already rolled a {self.dice_value}. Please move a token or pass."
49
- return self.render_board()
50
-
51
- self.dice_value = random.randint(1, 6)
52
- self.dice_rolled = True
53
-
54
- # Check if player can move any token
55
- self.can_play = self._can_play()
56
-
57
- if not self.can_play:
58
- # If player rolled 6, give them another turn
59
- if self.dice_value == 6:
60
- self.message = f"{self.colors[self.current_player].capitalize()} rolled a 6 but can't move. Roll again!"
61
- self.dice_rolled = False
62
- else:
63
- self.message = f"{self.colors[self.current_player].capitalize()} rolled {self.dice_value} but can't move. Next player's turn."
64
- self._next_player()
65
- else:
66
- self.message = f"{self.colors[self.current_player].capitalize()} rolled {self.dice_value}. Choose a token to move."
67
-
68
- return self.render_board()
69
-
70
- def _can_play(self):
71
- """Check if current player can move any token"""
72
- current_color = self.colors[self.current_player]
73
- tokens = self.tokens[current_color]
74
-
75
- for i, position in enumerate(tokens):
76
- if position == -1 and self.dice_value == 6:
77
- # Can move out of home
78
- return True
79
- elif position >= 0:
80
- # Token is already on the board
81
- return True
82
-
83
- return False
84
 
85
- def move_token(self, token_idx):
86
- """Move the selected token for the current player"""
87
- if self.winner:
88
- return self.render_board()
89
 
90
- if not self.dice_rolled:
91
- self.message = "Please roll the dice first."
92
- return self.render_board()
93
 
94
- if not self.can_play:
95
- self.message = "You can't move any token. Please pass your turn."
96
- return self.render_board()
 
 
 
97
 
98
- current_color = self.colors[self.current_player]
99
- current_pos = self.tokens[current_color][token_idx]
 
 
100
 
101
- # Token still in home and not rolled a 6
102
- if current_pos == -1 and self.dice_value != 6:
103
- self.message = "Need to roll a 6 to move a token out of home."
104
- return self.render_board()
105
 
106
- # Token in home and rolled a 6
107
- if current_pos == -1 and self.dice_value == 6:
108
- # Put token on the board at starting position (different for each player)
109
- self.tokens[current_color][token_idx] = self.current_player * 13
110
- self.message = f"{current_color.capitalize()} token {token_idx+1} is now on the board."
111
- self.dice_rolled = False
112
- return self.render_board()
113
-
114
- # Token already on board
115
- new_pos = (current_pos + self.dice_value) % 52
116
-
117
- # Check for token captures (simplistic implementation)
118
- for color in self.colors:
119
- if color != current_color:
120
- for i, pos in enumerate(self.tokens[color]):
121
- if pos == new_pos:
122
- # Capture token
123
- self.tokens[color][i] = -1
124
- self.message = f"{current_color.capitalize()} captured {color}'s token!"
125
-
126
- # Move token
127
- self.tokens[current_color][token_idx] = new_pos
128
-
129
- # Check if the player has won (simplistic - all tokens completed a full circle)
130
- if self._check_winner():
131
- self.winner = self.current_player
132
- self.message = f"{current_color.capitalize()} wins the game!"
133
  else:
134
- self.message = f"{current_color.capitalize()} moved token {token_idx+1} to position {new_pos}."
135
-
136
- # If player rolled 6, give them another turn
137
- if self.dice_value == 6:
138
- self.message += " Roll again!"
139
- else:
140
- self._next_player()
141
-
142
- self.dice_rolled = False
143
- return self.render_board()
144
-
145
- def _check_winner(self):
146
- """Very simple win check - if all tokens made a complete circuit"""
147
- current_color = self.colors[self.current_player]
148
- starting_pos = self.current_player * 13
149
-
150
- for pos in self.tokens[current_color]:
151
- if pos < starting_pos: # Simplified win condition
152
- return False
153
-
154
- return True
155
-
156
- def _next_player(self):
157
- """Move to the next player's turn"""
158
- self.current_player = (self.current_player + 1) % 4
159
- self.dice_rolled = False
160
- self.message += f" {self.colors[self.current_player].capitalize()}'s turn to roll."
161
-
162
- def pass_turn(self):
163
- """Pass the current player's turn"""
164
- if self.winner:
165
- return self.render_board()
166
-
167
- if not self.dice_rolled:
168
- self.message = "Please roll the dice first."
169
- return self.render_board()
170
-
171
- if self.can_play:
172
- self.message = "You have valid moves available. Please move a token."
173
- return self.render_board()
174
-
175
- self._next_player()
176
- return self.render_board()
177
-
178
- def render_board(self):
179
- """Render the Ludo board as an image"""
180
- # Create a new image with white background
181
- width, height = 600, 600
182
- board = Image.new('RGB', (width, height), color='white')
183
- draw = ImageDraw.Draw(board)
184
-
185
- # Draw the game board (simplified version)
186
- # Draw the outer square
187
- draw.rectangle([(50, 50), (550, 550)], outline='black', width=2)
188
-
189
- # Draw the home squares for each player
190
- home_squares = [
191
- (50, 50, 250, 250), # Red (top-left)
192
- (350, 50, 550, 250), # Green (top-right)
193
- (50, 350, 250, 550), # Yellow (bottom-left)
194
- (350, 350, 550, 550) # Blue (bottom-right)
195
- ]
196
-
197
- for i, color in enumerate(self.colors):
198
- draw.rectangle(home_squares[i], fill=self.color_codes[color], outline='black', width=2)
199
-
200
- # Draw the center square
201
- draw.rectangle([(250, 250), (350, 350)], fill='white', outline='black', width=2)
202
-
203
- # Draw the path (simplified)
204
- # Horizontal paths
205
- draw.rectangle([(250, 50), (350, 250)], fill='white', outline='black', width=1) # Top
206
- draw.rectangle([(250, 350), (350, 550)], fill='white', outline='black', width=1) # Bottom
207
- draw.rectangle([(50, 250), (250, 350)], fill='white', outline='black', width=1) # Left
208
- draw.rectangle([(350, 250), (550, 350)], fill='white', outline='black', width=1) # Right
209
-
210
- # Draw the tokens
211
- for color_idx, color in enumerate(self.colors):
212
- for token_idx, position in enumerate(self.tokens[color]):
213
- if position == -1:
214
- # Token in home - draw in home area
215
- home_x = home_squares[color_idx][0] + 50 + (token_idx % 2) * 100
216
- home_y = home_squares[color_idx][1] + 50 + (token_idx // 2) * 100
217
- draw.ellipse([(home_x-20, home_y-20), (home_x+20, home_y+20)],
218
- fill=self.color_codes[color], outline='black', width=2)
219
- else:
220
- # Token on board - simplified position calculation
221
- # This is a very basic mapping for illustration
222
- board_positions = [
223
- # Top row (left to right)
224
- (100, 300), (150, 300), (200, 300), (250, 300), (300, 300), (350, 300), (400, 300), (450, 300), (500, 300),
225
- # Right column (top to bottom)
226
- (500, 350), (500, 400), (500, 450), (500, 500),
227
- # Bottom row (right to left)
228
- (450, 500), (400, 500), (350, 500), (300, 500), (250, 500), (200, 500), (150, 500), (100, 500),
229
- # Left column (bottom to top)
230
- (100, 450), (100, 400), (100, 350), (100, 300),
231
- # Inner track (simplified approximation)
232
- # Repeat the pattern for simplicity
233
- (100, 300), (150, 300), (200, 300), (250, 300), (300, 300), (350, 300), (400, 300), (450, 300), (500, 300),
234
- (500, 350), (500, 400), (500, 450), (500, 500),
235
- (450, 500), (400, 500), (350, 500), (300, 500), (250, 500), (200, 500), (150, 500), (100, 500),
236
- (100, 450), (100, 400), (100, 350), (100, 300),
237
- ]
238
-
239
- if position < len(board_positions):
240
- token_x, token_y = board_positions[position]
241
- draw.ellipse([(token_x-15, token_y-15), (token_x+15, token_y+15)],
242
- fill=self.color_codes[color], outline='black', width=2)
243
- # Draw token number
244
- draw.text((token_x-5, token_y-5), str(token_idx+1), fill='black')
245
-
246
- # Draw the dice
247
- dice_x, dice_y = 300, 300
248
- draw.rectangle([(dice_x-25, dice_y-25), (dice_x+25, dice_y+25)], fill='white', outline='black', width=2)
249
-
250
- # Draw dice pips based on value
251
- if self.dice_value == 1:
252
- draw.ellipse([(dice_x-5, dice_y-5), (dice_x+5, dice_y+5)], fill='black')
253
- elif self.dice_value == 2:
254
- draw.ellipse([(dice_x-15, dice_y-15), (dice_x-5, dice_y-5)], fill='black')
255
- draw.ellipse([(dice_x+5, dice_y+5), (dice_x+15, dice_y+15)], fill='black')
256
- elif self.dice_value == 3:
257
- draw.ellipse([(dice_x-15, dice_y-15), (dice_x-5, dice_y-5)], fill='black')
258
- draw.ellipse([(dice_x-5, dice_y-5), (dice_x+5, dice_y+5)], fill='black')
259
- draw.ellipse([(dice_x+5, dice_y+5), (dice_x+15, dice_y+15)], fill='black')
260
- elif self.dice_value == 4:
261
- draw.ellipse([(dice_x-15, dice_y-15), (dice_x-5, dice_y-5)], fill='black')
262
- draw.ellipse([(dice_x+5, dice_y-15), (dice_x+15, dice_y-5)], fill='black')
263
- draw.ellipse([(dice_x-15, dice_y+5), (dice_x-5, dice_y+15)], fill='black')
264
- draw.ellipse([(dice_x+5, dice_y+5), (dice_x+15, dice_y+15)], fill='black')
265
- elif self.dice_value == 5:
266
- draw.ellipse([(dice_x-15, dice_y-15), (dice_x-5, dice_y-5)], fill='black')
267
- draw.ellipse([(dice_x+5, dice_y-15), (dice_x+15, dice_y-5)], fill='black')
268
- draw.ellipse([(dice_x-5, dice_y-5), (dice_x+5, dice_y+5)], fill='black')
269
- draw.ellipse([(dice_x-15, dice_y+5), (dice_x-5, dice_y+15)], fill='black')
270
- draw.ellipse([(dice_x+5, dice_y+5), (dice_x+15, dice_y+15)], fill='black')
271
- elif self.dice_value == 6:
272
- draw.ellipse([(dice_x-15, dice_y-15), (dice_x-5, dice_y-5)], fill='black')
273
- draw.ellipse([(dice_x+5, dice_y-15), (dice_x+15, dice_y-5)], fill='black')
274
- draw.ellipse([(dice_x-15, dice_y-5), (dice_x-5, dice_y+5)], fill='black')
275
- draw.ellipse([(dice_x+5, dice_y-5), (dice_x+15, dice_y+5)], fill='black')
276
- draw.ellipse([(dice_x-15, dice_y+5), (dice_x-5, dice_y+15)], fill='black')
277
- draw.ellipse([(dice_x+5, dice_y+5), (dice_x+15, dice_y+15)], fill='black')
278
-
279
- # Draw the current player indicator
280
- current_color = self.colors[self.current_player]
281
- draw.rectangle([(20, 20), (40, 40)], fill=self.color_codes[current_color], outline='black', width=2)
282
-
283
- # Draw game message
284
- draw.text((50, 20), self.message, fill='black')
285
-
286
- # Return the PIL Image directly - Gradio can handle PIL images
287
- return board
288
-
289
- # Create the Gradio interface
290
- def create_ludo_game():
291
- game = LudoGame()
292
-
293
- def roll():
294
- return game.roll_dice()
295
-
296
- def move_token_0():
297
- return game.move_token(0)
298
-
299
- def move_token_1():
300
- return game.move_token(1)
301
-
302
- def move_token_2():
303
- return game.move_token(2)
304
-
305
- def move_token_3():
306
- return game.move_token(3)
307
-
308
- def pass_turn():
309
- return game.pass_turn()
310
-
311
- def reset():
312
- game.reset_game()
313
- return game.render_board()
314
-
315
- with gr.Blocks() as ludo_app:
316
- gr.Markdown("# Ludo Game")
317
- gr.Markdown("### A classic 4-player board game")
318
-
319
- with gr.Row():
320
- with gr.Column():
321
- image_output = gr.Image(type="pil", label="Ludo Board")
322
 
323
- with gr.Row():
324
- roll_button = gr.Button("Roll Dice")
 
 
 
325
 
326
- with gr.Row():
327
- token1_button = gr.Button("Move Token 1")
328
- token2_button = gr.Button("Move Token 2")
329
- token3_button = gr.Button("Move Token 3")
330
- token4_button = gr.Button("Move Token 4")
331
 
332
- with gr.Row():
333
- pass_button = gr.Button("Pass Turn")
334
- reset_button = gr.Button("Reset Game")
335
-
336
- # Set up button click events
337
- roll_button.click(roll, inputs=[], outputs=[image_output])
338
- token1_button.click(move_token_0, inputs=[], outputs=[image_output])
339
- token2_button.click(move_token_1, inputs=[], outputs=[image_output])
340
- token3_button.click(move_token_2, inputs=[], outputs=[image_output])
341
- token4_button.click(move_token_3, inputs=[], outputs=[image_output])
342
- pass_button.click(pass_turn, inputs=[], outputs=[image_output])
343
- reset_button.click(reset, inputs=[], outputs=[image_output])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
 
345
- # Initialize the board on load
346
- ludo_app.load(fn=game.render_board, inputs=None, outputs=image_output)
347
-
348
- return ludo_app
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
 
350
  # Launch the app
351
  if __name__ == "__main__":
352
- app = create_ludo_game()
353
- app.launch(share=True)
 
1
  import gradio as gr
 
2
  import random
3
+ import numpy as np
4
  from PIL import Image, ImageDraw, ImageFont
5
+ import os
 
6
 
7
+ class SnakeAndLadderGame:
8
  def __init__(self):
9
+ # Board size
10
+ self.board_size = 10
11
+ self.total_cells = self.board_size * self.board_size
12
+
13
+ # Initialize snakes and ladders
14
+ self.snakes = {
15
+ 16: 6,
16
+ 47: 26,
17
+ 49: 11,
18
+ 56: 53,
19
+ 62: 19,
20
+ 64: 60,
21
+ 87: 24,
22
+ 93: 73,
23
+ 95: 75,
24
+ 98: 78
25
  }
26
 
27
+ self.ladders = {
28
+ 1: 38,
29
+ 4: 14,
30
+ 9: 31,
31
+ 21: 42,
32
+ 28: 84,
33
+ 36: 44,
34
+ 51: 67,
35
+ 71: 91,
36
+ 80: 100
37
+ }
38
+
39
+ # Player positions
40
+ self.player_positions = [0, 0] # Two players starting at position 0
41
  self.current_player = 0
42
+ self.game_over = False
 
43
  self.winner = None
44
+ self.last_move = ""
45
 
 
 
 
 
 
 
 
 
 
 
 
46
  def roll_dice(self):
47
+ return random.randint(1, 6)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
+ def move_player(self, player_idx, steps):
50
+ if self.game_over:
51
+ return f"Game over! Player {self.winner + 1} has won!"
 
52
 
53
+ old_position = self.player_positions[player_idx]
54
+ new_position = old_position + steps
 
55
 
56
+ # Check if the player won
57
+ if new_position >= 100:
58
+ self.player_positions[player_idx] = 100
59
+ self.game_over = True
60
+ self.winner = player_idx
61
+ return f"Player {player_idx + 1} has won the game!"
62
 
63
+ # Check if the player landed on a snake
64
+ elif new_position in self.snakes:
65
+ self.player_positions[player_idx] = self.snakes[new_position]
66
+ return f"Player {player_idx + 1} got bitten by a snake and moved from {new_position} to {self.snakes[new_position]}"
67
 
68
+ # Check if the player landed on a ladder
69
+ elif new_position in self.ladders:
70
+ self.player_positions[player_idx] = self.ladders[new_position]
71
+ return f"Player {player_idx + 1} climbed a ladder and moved from {new_position} to {self.ladders[new_position]}"
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  else:
74
+ self.player_positions[player_idx] = new_position
75
+ return f"Player {player_idx + 1} moved from {old_position} to {new_position}"
76
+
77
+ def play_turn(self):
78
+ if self.game_over:
79
+ return self.draw_board(), f"Game over! Player {self.winner + 1} has won!"
80
+
81
+ dice_roll = self.roll_dice()
82
+ move_message = self.move_player(self.current_player, dice_roll)
83
+
84
+ # Switch to the next player
85
+ self.current_player = (self.current_player + 1) % 2
86
+
87
+ status = f"Dice: {dice_roll}. {move_message}"
88
+ if not self.game_over:
89
+ status += f"\nPlayer {self.current_player + 1}'s turn next."
90
+
91
+ return self.draw_board(), status
92
+
93
+ def draw_board(self):
94
+ # Create a new image
95
+ cell_size = 60
96
+ board_width = self.board_size * cell_size
97
+ board_height = self.board_size * cell_size
98
+ padding = 20
99
+
100
+ img = Image.new('RGB', (board_width + 2*padding, board_height + 2*padding), color=(255, 255, 255))
101
+ draw = ImageDraw.Draw(img)
102
+
103
+ try:
104
+ font = ImageFont.truetype("arial.ttf", 16)
105
+ except IOError:
106
+ font = ImageFont.load_default()
107
+
108
+ # Draw board grid
109
+ for row in range(self.board_size):
110
+ for col in range(self.board_size):
111
+ # Determine cell number based on row (0-9 from bottom to top)
112
+ if row % 2 == 0: # Even rows (0, 2, 4, 6, 8) go left to right
113
+ cell_num = (self.board_size - 1 - row) * self.board_size + col + 1
114
+ else: # Odd rows (1, 3, 5, 7, 9) go right to left
115
+ cell_num = (self.board_size - 1 - row) * self.board_size + (self.board_size - col)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
+ # Cell position
118
+ x0 = col * cell_size + padding
119
+ y0 = (self.board_size - 1 - row) * cell_size + padding
120
+ x1 = x0 + cell_size
121
+ y1 = y0 + cell_size
122
 
123
+ # Alternate cell colors for better visualization
124
+ cell_color = (220, 220, 220) if (row + col) % 2 == 0 else (240, 240, 240)
 
 
 
125
 
126
+ # Highlight snake cells
127
+ if cell_num in self.snakes:
128
+ cell_color = (255, 200, 200) # Light red for snakes
129
+
130
+ # Highlight ladder cells
131
+ if cell_num in self.ladders:
132
+ cell_color = (200, 255, 200) # Light green for ladders
133
+
134
+ draw.rectangle([x0, y0, x1, y1], fill=cell_color, outline=(0, 0, 0))
135
+
136
+ # Draw cell number
137
+ draw.text((x0 + 5, y0 + 5), str(cell_num), fill=(0, 0, 0), font=font)
138
+
139
+ # Mark snakes
140
+ if cell_num in self.snakes:
141
+ draw.text((x0 + 5, y0 + 25), f"S→{self.snakes[cell_num]}", fill=(255, 0, 0), font=font)
142
+
143
+ # Mark ladders
144
+ if cell_num in self.ladders:
145
+ draw.text((x0 + 5, y0 + 25), f"L→{self.ladders[cell_num]}", fill=(0, 128, 0), font=font)
146
+
147
+ # Draw player positions
148
+ player_colors = [(0, 0, 255), (255, 0, 0)] # Blue for Player 1, Red for Player 2
149
+ for idx, pos in enumerate(self.player_positions):
150
+ if pos > 0:
151
+ # Find the cell position for the player
152
+ row = (self.board_size - 1) - ((pos - 1) // self.board_size)
153
+ if row % 2 == 0: # Even rows go left to right
154
+ col = (pos - 1) % self.board_size
155
+ else: # Odd rows go right to left
156
+ col = self.board_size - 1 - ((pos - 1) % self.board_size)
157
+
158
+ # Draw player token
159
+ player_x = col * cell_size + padding + (cell_size // 2) + (idx * 10 - 5)
160
+ player_y = (self.board_size - 1 - row) * cell_size + padding + (cell_size // 2) + 10
161
+
162
+ draw.ellipse([player_x - 10, player_y - 10, player_x + 10, player_y + 10],
163
+ fill=player_colors[idx], outline=(0, 0, 0))
164
+ draw.text((player_x - 4, player_y - 8), str(idx + 1), fill=(255, 255, 255), font=font)
165
 
166
+ return img
167
+
168
+ def reset_game():
169
+ global game
170
+ game = SnakeAndLadderGame()
171
+ return game.draw_board(), "Game reset. Player 1's turn to roll the dice."
172
+
173
+ def take_turn():
174
+ global game
175
+ return game.play_turn()
176
+
177
+ # Initialize game
178
+ game = SnakeAndLadderGame()
179
+
180
+ # Create Gradio interface
181
+ with gr.Blocks(title="Snake and Ladder Game") as demo:
182
+ gr.Markdown("# Snake and Ladder Game")
183
+ gr.Markdown("Roll the dice and make your way to 100 while avoiding snakes and climbing ladders!")
184
+
185
+ with gr.Row():
186
+ with gr.Column(scale=2):
187
+ board_display = gr.Image(game.draw_board(), label="Game Board")
188
+
189
+ with gr.Column(scale=1):
190
+ status_text = gr.Textbox(value="Welcome to Snake and Ladder Game! Player 1's turn to roll the dice.",
191
+ label="Game Status", lines=5)
192
+
193
+ roll_button = gr.Button("Roll Dice")
194
+ reset_button = gr.Button("Reset Game")
195
+
196
+ gr.Markdown("### Game Rules:")
197
+ gr.Markdown("""
198
+ 1. Two players take turns rolling a dice.
199
+ 2. Move your token according to the dice roll.
200
+ 3. If you land on a snake's head, you'll slide down to its tail.
201
+ 4. If you land on the bottom of a ladder, you'll climb up to the top.
202
+ 5. The first player to reach or exceed position 100 wins!
203
+ """)
204
+
205
+ roll_button.click(take_turn, inputs=[], outputs=[board_display, status_text])
206
+ reset_button.click(reset_game, inputs=[], outputs=[board_display, status_text])
207
 
208
  # Launch the app
209
  if __name__ == "__main__":
210
+ demo.launch()