File size: 6,312 Bytes
416abcf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import pygame
import sys
import random
import time

# Init Pygame because we’re not living in the stone age
pygame.init()

# Constants that will never change except when they do
WIDTH, HEIGHT = 640, 480
# Block size: how many pixels per grid cell
BLOCK_SIZE = 20
# FPS: frames per second, aka how smooth the snake is
SPEED = 10
# Direction mapping: because string comparison is slower than integer comparison
DIRECTIONS = {'UP': (0, -1), 'DOWN': (0, 1), 'LEFT': (-1, 0), 'RIGHT': (1, 0)}

# Colors because RGB values are more readable than magic numbers
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
# Red for apple and also for “game over” messages
RED = (255, 0, 0)

class SnakeGame:
    def __init__(self):
        self.display = pygame.display.set_mode((WIDTH, HEIGHT))
        pygame.display.set_caption("Snake Game 2000 Edition")  # Title is kino
        self.clock = pygame.time.Clock()
        self.reset()

    def reset(self):
        # Reset the snake to the starting position
        self.snake = [(200, 200), (220, 200), (240, 200)]
        # Set initial direction to right because why the fuck not
        self.direction = 'RIGHT'
        # Generate an apple somewhere on the grid
        self.apple = self.generate_apple()
        # Keep track of score
        self.score = 0
        # Game over flag
        self.game_over = False

    def generate_apple(self):
        # Make sure the apple doesn't spawn where the snake already is
        while True:
            x = random.randint(0, WIDTH - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE
            y = random.randint(0, HEIGHT - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE
            apple = (x, y)
            if apple not in self.snake:
                return apple

    def update(self):
        if self.game_over:
            # If game is over, print final score like a based champion
            print(f"\nGame over anon! Final score: {self.score}")
            print("You died like a virgin. Press R to try again.")
            return

        # Get the head of the snake
        head = self.snake[-1]
        # Calculate new head position
        new_head = (head[0] + DIRECTIONS[self.direction][0] * BLOCK_SIZE,
                    head[1] + DIRECTIONS[self.direction][1] * BLOCK_SIZE)

        # Check for collisions with walls and self
        if ((new_head[0] < 0 or new_head[0] >= WIDTH or
             new_head[1] < 0 or new_head[1] >= HEIGHT) or
            new_head in self.snake):
            # If you hit a wall or yourself, game over
            self.game_over = True
            self.draw()  # Draw final frame
            pygame.time.delay(2000)  # Wait 2 seconds
            return

        # Move the snake
        self.snake.append(new_head)

        # Check if you ate the apple
        if self.apple == new_head:
            # Increase score and spawn new apple
            self.score += 1
            print(f"🍎 Munch! Score: {self.score}")  # Emoji for based feedback
            self.apple = self.generate_apple()
        else:
            # Otherwise, remove the tail
            self.snake.pop(0)

    def draw(self):
        # Fill screen with black like your soul
        self.display.fill(BLACK)

        # Draw snake
        for pos in self.snake:
            pygame.draw.rect(self.display, GREEN, pygame.Rect(pos[0], pos[1], BLOCK_SIZE, BLOCK_SIZE))

        # Draw apple
        pygame.draw.rect(self.display, RED, pygame.Rect(self.apple[0], self.apple[1], BLOCK_SIZE, BLOCK_SIZE))

        # Draw score
        font = pygame.font.Font(None, 36)
        text = font.render(f"Score: {self.score}", True, WHITE)
        self.display.blit(text, (10, 10))

        # Check if game over and draw “Game Over” text
        if self.game_over:
            text = font.render("Game Over. Press R to restart.", True, RED)
            self.display.blit(text, (10, 50))

        # Update display like a good boy
        pygame.display.flip()

    def handle_input(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                # Exit button pressed, clean up and quit
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                # Handle arrow key presses
                if event.key == pygame.K_UP and self.direction != 'DOWN':
                    self.direction = 'UP'
                elif event.key == pygame.K_DOWN and self.direction != 'UP':
                    self.direction = 'DOWN'
                elif event.key == pygame.K_LEFT and self.direction != 'RIGHT':
                    self.direction = 'LEFT'
                elif event.key == pygame.K_RIGHT and self.direction != 'LEFT':
                    self.direction = 'RIGHT'
                elif event.key == pygame.K_r:
                    # Reset game
                    self.reset()
                    self.game_over = False  # Clear game over state
                elif event.key == pygame.K_s:
                    # Change speed (because speedrunners will always exist)
                    try:
                        speed = int(input("Enter new speed: "))
                        if speed < 1:
                            print("Speed must be 1 or higher, you absolute mongoloid")
                        else:
                            SPEED = speed
                            print(f"Speed set to {speed}. Your grandma can handle this.")
                    except ValueError:
                        print("Invalid input. Default speed remains.")

                # Bonus feature: press S to show current speed
                elif event.key == pygame.K_c:
                    print(f"Current speed: {SPEED}")

    def run(self):
        # Game loop
        while True:
            self.handle_input()

            if self.game_over:
                self.draw()
                # Wait 2 seconds before restarting
                pygame.time.delay(2000)
                break

            self.update()
            self.draw()
            # Cap framerate at SPEED
            self.clock.tick(SPEED)

if __name__ == "__main__":
    game = SnakeGame()
    print("Welcome to Snake Game 2000 Edition!")
    print("Use arrow keys to move, R to restart, S to change speed")
    print(f"Current speed: {SPEED}")
    game.run()