game / app.py
sagar007's picture
Update app.py
3ddf78f verified
raw
history blame
8.1 kB
import gradio as gr
import random
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import os
class SnakeAndLadderGame:
def __init__(self):
# Board size
self.board_size = 10
self.total_cells = self.board_size * self.board_size
# Initialize snakes and ladders
self.snakes = {
16: 6,
47: 26,
49: 11,
56: 53,
62: 19,
64: 60,
87: 24,
93: 73,
95: 75,
98: 78
}
self.ladders = {
1: 38,
4: 14,
9: 31,
21: 42,
28: 84,
36: 44,
51: 67,
71: 91,
80: 100
}
# Player positions
self.player_positions = [0, 0] # Two players starting at position 0
self.current_player = 0
self.game_over = False
self.winner = None
self.last_move = ""
def roll_dice(self):
return random.randint(1, 6)
def move_player(self, player_idx, steps):
if self.game_over:
return f"Game over! Player {self.winner + 1} has won!"
old_position = self.player_positions[player_idx]
new_position = old_position + steps
# Check if the player won
if new_position >= 100:
self.player_positions[player_idx] = 100
self.game_over = True
self.winner = player_idx
return f"Player {player_idx + 1} has won the game!"
# Check if the player landed on a snake
elif new_position in self.snakes:
self.player_positions[player_idx] = self.snakes[new_position]
return f"Player {player_idx + 1} got bitten by a snake and moved from {new_position} to {self.snakes[new_position]}"
# Check if the player landed on a ladder
elif new_position in self.ladders:
self.player_positions[player_idx] = self.ladders[new_position]
return f"Player {player_idx + 1} climbed a ladder and moved from {new_position} to {self.ladders[new_position]}"
else:
self.player_positions[player_idx] = new_position
return f"Player {player_idx + 1} moved from {old_position} to {new_position}"
def play_turn(self):
if self.game_over:
return self.draw_board(), f"Game over! Player {self.winner + 1} has won!"
dice_roll = self.roll_dice()
move_message = self.move_player(self.current_player, dice_roll)
# Switch to the next player
self.current_player = (self.current_player + 1) % 2
status = f"Dice: {dice_roll}. {move_message}"
if not self.game_over:
status += f"\nPlayer {self.current_player + 1}'s turn next."
return self.draw_board(), status
def draw_board(self):
# Create a new image
cell_size = 60
board_width = self.board_size * cell_size
board_height = self.board_size * cell_size
padding = 20
img = Image.new('RGB', (board_width + 2*padding, board_height + 2*padding), color=(255, 255, 255))
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype("arial.ttf", 16)
except IOError:
font = ImageFont.load_default()
# Draw board grid
for row in range(self.board_size):
for col in range(self.board_size):
# Determine cell number based on row (0-9 from bottom to top)
if row % 2 == 0: # Even rows (0, 2, 4, 6, 8) go left to right
cell_num = (self.board_size - 1 - row) * self.board_size + col + 1
else: # Odd rows (1, 3, 5, 7, 9) go right to left
cell_num = (self.board_size - 1 - row) * self.board_size + (self.board_size - col)
# Cell position
x0 = col * cell_size + padding
y0 = (self.board_size - 1 - row) * cell_size + padding
x1 = x0 + cell_size
y1 = y0 + cell_size
# Alternate cell colors for better visualization
cell_color = (220, 220, 220) if (row + col) % 2 == 0 else (240, 240, 240)
# Highlight snake cells
if cell_num in self.snakes:
cell_color = (255, 200, 200) # Light red for snakes
# Highlight ladder cells
if cell_num in self.ladders:
cell_color = (200, 255, 200) # Light green for ladders
draw.rectangle([x0, y0, x1, y1], fill=cell_color, outline=(0, 0, 0))
# Draw cell number
draw.text((x0 + 5, y0 + 5), str(cell_num), fill=(0, 0, 0), font=font)
# Mark snakes
if cell_num in self.snakes:
draw.text((x0 + 5, y0 + 25), f"S→{self.snakes[cell_num]}", fill=(255, 0, 0), font=font)
# Mark ladders
if cell_num in self.ladders:
draw.text((x0 + 5, y0 + 25), f"L→{self.ladders[cell_num]}", fill=(0, 128, 0), font=font)
# Draw player positions
player_colors = [(0, 0, 255), (255, 0, 0)] # Blue for Player 1, Red for Player 2
for idx, pos in enumerate(self.player_positions):
if pos > 0:
# Find the cell position for the player
row = (self.board_size - 1) - ((pos - 1) // self.board_size)
if row % 2 == 0: # Even rows go left to right
col = (pos - 1) % self.board_size
else: # Odd rows go right to left
col = self.board_size - 1 - ((pos - 1) % self.board_size)
# Draw player token
player_x = col * cell_size + padding + (cell_size // 2) + (idx * 10 - 5)
player_y = (self.board_size - 1 - row) * cell_size + padding + (cell_size // 2) + 10
draw.ellipse([player_x - 10, player_y - 10, player_x + 10, player_y + 10],
fill=player_colors[idx], outline=(0, 0, 0))
draw.text((player_x - 4, player_y - 8), str(idx + 1), fill=(255, 255, 255), font=font)
return img
def reset_game():
global game
game = SnakeAndLadderGame()
return game.draw_board(), "Game reset. Player 1's turn to roll the dice."
def take_turn():
global game
return game.play_turn()
# Initialize game
game = SnakeAndLadderGame()
# Create Gradio interface
with gr.Blocks(title="Snake and Ladder Game") as demo:
gr.Markdown("# Snake and Ladder Game")
gr.Markdown("Roll the dice and make your way to 100 while avoiding snakes and climbing ladders!")
with gr.Row():
with gr.Column(scale=2):
board_display = gr.Image(game.draw_board(), label="Game Board")
with gr.Column(scale=1):
status_text = gr.Textbox(value="Welcome to Snake and Ladder Game! Player 1's turn to roll the dice.",
label="Game Status", lines=5)
roll_button = gr.Button("Roll Dice")
reset_button = gr.Button("Reset Game")
gr.Markdown("### Game Rules:")
gr.Markdown("""
1. Two players take turns rolling a dice.
2. Move your token according to the dice roll.
3. If you land on a snake's head, you'll slide down to its tail.
4. If you land on the bottom of a ladder, you'll climb up to the top.
5. The first player to reach or exceed position 100 wins!
""")
roll_button.click(take_turn, inputs=[], outputs=[board_display, status_text])
reset_button.click(reset_game, inputs=[], outputs=[board_display, status_text])
# Launch the app
if __name__ == "__main__":
demo.launch()