Skip to content

Instantly share code, notes, and snippets.

@kody-w
Created March 10, 2024 02:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kody-w/019b788107b359dc7cf10fe477bb17a4 to your computer and use it in GitHub Desktop.
Save kody-w/019b788107b359dc7cf10fe477bb17a4 to your computer and use it in GitHub Desktop.
import pygame
import sys
import random
from pygame.math import Vector2
class WormGame:
def __init__(self):
pygame.init()
self.screen_width = 600
self.screen_height = 400
self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
self.clock = pygame.time.Clock()
self.worm = Worm(self)
self.food = Food(self)
self.running = True
self.score = 0
self.consecutive_collisions = 0 # Track consecutive self-collisions
def run(self):
while self.running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
self.food.move_food(event)
self.food.update_food_position()
self.worm.move_worm()
self.check_collision()
self.check_fail()
self.screen.fill((175, 215, 70))
self.worm.draw_worm()
self.food.draw_food()
self.draw_score()
pygame.display.flip()
self.clock.tick(10)
def check_collision(self):
if self.worm.body[0] == self.food.pos:
self.food.randomize()
# Grow the worm by 2 blocks for each piece of food eaten
self.worm.add_block()
self.score += 1
def check_fail(self):
# Reset consecutive collisions if no collision this tick
self_collision = False
for block in self.worm.body[1:]:
if block == self.worm.body[0]:
self_collision = True
self.consecutive_collisions += 1
break
if not self_collision:
self.consecutive_collisions = 0
# Game ends after 2 consecutive collisions and worm size is significant
if self.consecutive_collisions >= 3:
print(f"Game Over. Your worm got caught in a knot! Final Score: {self.score}")
self.running = False
def draw_score(self):
font = pygame.font.Font(None, 36)
score_text = font.render(f"Score: {self.score}", True, (56, 74, 12))
self.screen.blit(score_text, (10, 10))
class Worm:
def __init__(self, game):
self.game = game
self.body = [Vector2(5, 10), Vector2(4, 10), Vector2(3, 10)]
self.direction = Vector2(1, 0)
self.new_block = False
self.cell_size = 20
self.move_counter = 0
self.move_frequency = 1
def move_worm(self):
self.move_counter += 1
if self.move_counter >= self.move_frequency:
self.update_direction()
if self.new_block:
body_copy = self.body[:]
body_copy.insert(0, body_copy[0] + self.direction)
self.body = body_copy[:]
self.new_block = False
else:
body_copy = self.body[:-1]
body_copy.insert(0, body_copy[0] + self.direction)
self.body = body_copy[:]
self.move_counter = 0
def update_direction(self):
# Generate potential directions
potential_directions = [Vector2(1, 0), Vector2(-1, 0), Vector2(0, 1), Vector2(0, -1)]
safe_directions = []
for dir in potential_directions:
new_head_position = self.body[0] + dir
if not self.is_collision(new_head_position):
safe_directions.append(dir)
if safe_directions:
self.direction = random.choice(safe_directions)
else:
self.direction = Vector2(0, 0) # No safe move available
def is_collision(self, position):
return position in self.body or position.x < 0 or position.y < 0 or position.x >= self.game.screen_width / self.cell_size or position.y >= self.game.screen_height / self.cell_size
def draw_worm(self):
for block in self.body:
x_pos = int(block.x * self.cell_size)
y_pos = int(block.y * self.cell_size)
block_rect = pygame.Rect(x_pos, y_pos, self.cell_size, self.cell_size)
pygame.draw.rect(self.game.screen, (183,111,122), block_rect)
def add_block(self):
self.new_block = True
class Food:
def __init__(self, game):
self.game = game
self.pos = Vector2(10, 10)
self.direction = Vector2(0, 0)
self.cell_size = 20
def update_food_position(self):
new_pos = self.pos + self.direction
if 0 <= new_pos.x < self.game.screen_width / self.cell_size and 0 <= new_pos.y < self.game.screen_height / self.cell_size:
self.pos = new_pos
def draw_food(self):
x_pos = int(self.pos.x * self.cell_size)
y_pos = int(self.pos.y * self.cell_size)
food_rect = pygame.Rect(x_pos, y_pos, self.cell_size, self.cell_size)
pygame.draw.rect(self.game.screen, (126,166,114), food_rect)
def move_food(self, event):
if event.key == pygame.K_UP:
self.direction = Vector2(0, -1)
elif event.key == pygame.K_DOWN:
self.direction = Vector2(0, 1)
elif event.key == pygame.K_LEFT:
self.direction = Vector2(-1, 0)
elif event.key == pygame.K_RIGHT:
self.direction = Vector2(1, 0)
def randomize(self):
self.pos = Vector2(random.randint(0, self.game.screen_width // self.cell_size - 1), random.randint(0, self.game.screen_height // self.cell_size - 1))
if __name__ == '__main__':
game = WormGame()
game.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment