Py.Cafe

jackparmer/

snake-game

Interactive Snake Game Demo with Streamlit

DocsPricing
  • app.py
  • requirements.txt
app.py
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
135
import streamlit as st
import numpy as np
import time
from PIL import Image, ImageDraw

# Initialize the game state
if 'snake' not in st.session_state:
    st.session_state.snake = [(10, 10)]
    st.session_state.direction = 'RIGHT'
    st.session_state.food = (15, 15)
    st.session_state.score = 0
    st.session_state.game_over = False

# Game constants
CELL_SIZE = 20
GRID_SIZE = 30

def draw_grid(snake, food):
    grid = Image.new('RGB', (GRID_SIZE * CELL_SIZE, GRID_SIZE * CELL_SIZE), (0, 0, 0))
    draw = ImageDraw.Draw(grid)
    
    # Draw the snake
    for segment in snake:
        draw.rectangle([segment[0] * CELL_SIZE, segment[1] * CELL_SIZE,
                        (segment[0] + 1) * CELL_SIZE, (segment[1] + 1) * CELL_SIZE], fill=(0, 255, 0))
    
    # Draw the food
    draw.rectangle([food[0] * CELL_SIZE, food[1] * CELL_SIZE,
                    (food[0] + 1) * CELL_SIZE, (food[1] + 1) * CELL_SIZE], fill=(255, 0, 0))
    
    return grid

def move_snake(snake, direction):
    head = snake[0]
    if direction == 'UP':
        new_head = (head[0], head[1] - 1)
    elif direction == 'DOWN':
        new_head = (head[0], head[1] + 1)
    elif direction == 'LEFT':
        new_head = (head[0] - 1, head[1])
    elif direction == 'RIGHT':
        new_head = (head[0] + 1, head[1])
    
    return [new_head] + snake[:-1]

def check_collision(snake):
    head = snake[0]
    # Check wall collision
    if head[0] < 0 or head[0] >= GRID_SIZE or head[1] < 0 or head[1] >= GRID_SIZE:
        return True
    # Check self collision
    if head in snake[1:]:
        return True
    return False

def check_food_collision(snake, food):
    if snake[0] == food:
        return True
    return False

def grow_snake(snake):
    snake.append(snake[-1])
    return snake

def generate_food(snake):
    while True:
        new_food = (np.random.randint(0, GRID_SIZE), np.random.randint(0, GRID_SIZE))
        if new_food not in snake:
            return new_food

st.title('Snake Game')

# Control the snake's direction
col1, col2, col3 = st.columns(3)
with col1:
    st.write('')
with col2:
    if st.button('⬆️'):
        if st.session_state.direction != 'DOWN':
            st.session_state.direction = 'UP'
with col3:
    st.write('')

col1, col2, col3 = st.columns(3)
with col1:
    if st.button('⬅️'):
        if st.session_state.direction != 'RIGHT':
            st.session_state.direction = 'LEFT'
with col2:
    st.write('')
with col3:
    if st.button('➡️'):
        if st.session_state.direction != 'LEFT':
            st.session_state.direction = 'RIGHT'

col1, col2, col3 = st.columns(3)
with col1:
    st.write('')
with col2:
    if st.button('⬇️'):
        if st.session_state.direction != 'UP':
            st.session_state.direction = 'DOWN'
with col3:
    st.write('')

# Move the snake automatically
if not st.session_state.game_over:
    st.session_state.snake = move_snake(st.session_state.snake, st.session_state.direction)
    
    # Check for collisions
    if check_collision(st.session_state.snake):
        st.session_state.game_over = True
        st.write("Game Over! Your score is:", st.session_state.score)
    else:
        # Check if food is eaten
        if check_food_collision(st.session_state.snake, st.session_state.food):
            st.session_state.snake = grow_snake(st.session_state.snake)
            st.session_state.food = generate_food(st.session_state.snake)
            st.session_state.score += 1
        
        # Draw the grid
        grid = draw_grid(st.session_state.snake, st.session_state.food)
        st.image(grid, caption='Snake Game')
    
    time.sleep(0.1)
    st.experimental_rerun()
else:
    if st.button('Restart'):
        st.session_state.snake = [(10, 10)]
        st.session_state.direction = 'RIGHT'
        st.session_state.food = (15, 15)
        st.session_state.score = 0
        st.session_state.game_over = False
        st.experimental_rerun()