Review the completed game by filling in the missing pieces of the final integration.
# ── Full game integration ──
class Game:
def __init__(self):
self.snake = Snake(▢1, 7)
self.food = self._spawn_food()
self.score = ▢2
self.running = ▢3
def _spawn_food(self):
while True:
pos = (random.randint(0, GRID_COLS-1),
random.randint(0, ▢4-1))
if pos not in self.snake.body_set:
return ▢5
def update(self):
self.snake.▢6()
if not self.snake.is_alive():
self.running = ▢7
return
if self.snake.body[0] == self.food:
self.snake.grew = ▢8
self.score += 1
self.food = self.▢9()
def run(self):
clock = pygame.time.Clock()
while self.running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.KEYDOWN:
key_map = {pygame.K_UP:"UP", pygame.K_DOWN:"DOWN",
pygame.K_LEFT:"LEFT", pygame.K_RIGHT:"RIGHT"}
if event.key in key_map:
self.snake.▢10(key_map[event.key])
self.update()
self.▢11()
clock.tick(SNAKE_SPEED)
pygame.quit()
1__T___G________p__m___F____T______________t___d___The integrated Game class below has 3 bugs. Type the corrected line for each.
class Game:
def __init__(self):
self.snake = Snake(10, 7)
self.food = self._spawn_food()
self.running = True
def update(self):
self.snake.move()
if self.snake.body[0] == food: # Bug 1 – missing self.
self.snake.grew = True
if not self.snake.is_alive():
running = False # Bug 2 – missing self.
def draw(self, screen):
screen.fill(BG)
for i,(cx,cy) in enumerate(self.snake): # Bug 3 – wrong iterable
colour = (0,180,60) if i==0 else GREEN
pygame.draw.rect(screen, colour,
pygame.Rect(cx*CELL_SIZE,cy*CELL_SIZE,CELL_SIZE-2,CELL_SIZE-2), border_radius=4)
Bug 1
Buggy line:
Your fix:
Hint: `food` is an attribute of Game, not a standalone variable. Prefix with `self.` to access it.
Bug 2
Buggy line:
Your fix:
Hint: Without `self.`, this creates a new local variable that disappears after `update()` returns — the game never stops.
Bug 3
Buggy line:
Your fix:
Hint: `self.snake` is a Snake object; you need to iterate over `self.snake.body` (the list of positions).
Write **unit tests** for three functions: `Snake.turn()` (can't reverse), `Snake.is_alive()` (boundary), and `Game._spawn_food()` (not on snake). Use Python's `assert` statement.
# No pygame display needed for unit tests
import pygame
pygame.init()
pygame.display.set_mode((400,300)) # minimal surface
snake = Snake(10, 7)
# Test 1: Snake cannot reverse direction
snake.direction = "RIGHT"
snake.turn("LEFT") # should be blocked
assert snake.direction == {{"RIGHT"}}, "Reversal guard failed"
# Test 2: Snake.is_alive() returns False for out-of-bounds head
snake.body[0] = (-1, 7)
assert snake.is_alive() == {{False}}, "Boundary check failed"
# Test 3: Food does not spawn on the snake
game = Game()
for _ in range(50):
food = game._spawn_food()
assert food not in snake.body_set, "Food spawned on snake!"
print("All tests passed!")
**Final Challenge:** Add one meaningful extension to the complete game. Ideas: multi-food mode, speed ramp-up, obstacle walls, two-player mode, or a simple sprite for the head. Paste the code for your chosen feature and explain how it fits into the class structure.
Answer all 5 questions, then the Reflective Journal will unlock.
1. MVP in game development means:
2. Which is NOT a good first step when adding a new game feature?
3. 'Separation of concerns' in your game means:
4. A game state machine is useful for managing:
5. Which of these makes game code most maintainable for the long term?
Answer each prompt thoughtfully. There are no right or wrong answers — this is your own reflection.