# Visual Basic > Games and Graphics Programming > Game Demos >  [Python] Snake

## kfcSmitty

I've been getting into Python, so I decided to make a Snake game leveraging Pygame. This is only the source code, but if you want to see how to set up the environment, you can check out instructions on getting Python/Pygame up and running in Eclipse here.

The Fruit Module:



```
'''
Created on 2013-11-08

@author: Smitty
A class to store the fruit information.
'''

class Fruit:

    def __init__(self):
        import random
        
        #assigns a random X and Y to the fruit that is divisible by 10 so it aligns with the snake
        self.x = random.randrange(0, 300, 10)
        self.y = random.randrange(0, 300, 10)
        self.colour = (255, 0, 0)
```

The Snake Module



```
'''
Created on 2013-11-07

@author: Smitty
The snake module holds an "enum" for the direction, and the snake-relevant functions
'''

#directions the snake can get. Python doesn't seem to have enums so I made a class
class Direction:
    LEFT = 1
    RIGHT = 2
    UP = 3
    DOWN = 4

#just a basic class to hold the X and Y coord for a block of the snake
class SnakeBlock:
    
    def __init__(self, x, y):   
        self.x = x
        self.y = y
         

class Snake:
    
    def Move(self):
        #loop through each block backwards and set its x and y coordinate to the previous
        #block in the sequence
        for i in range(len(self.blocks), 1, -1):
            self.blocks[i-1].x = self.blocks[i-2].x
            self.blocks[i-1].y = self.blocks[i-2].y
        
        if(self.direction == Direction.LEFT):
            self.blocks[0].x -= 10
            if(self.blocks[0].x < 0):
                self.Kill()
                
        elif(self.direction == Direction.RIGHT):            
            self.blocks[0].x += 10
            
            if(self.blocks[0].x >= self.maxx):
                self.Kill()
        elif(self.direction == Direction.UP):               
            self.blocks[0].y -= 10
            if(self.blocks[0].y < 0):
                self.Kill()
        elif(self.direction == Direction.DOWN):             
            self.blocks[0].y += 10
            if(self.blocks[0].y >= self.maxy):
                self.Kill()
                
        for i in range(1, len(self.blocks)):
            if(self.blocks[0].x == self.blocks[i].x and self.blocks[0].y == self.blocks[i].y):
                self.Kill()
                
    #it's game over, man!
    def Kill(self):
        self.alive = False
    
    def AddBlock(self):
        self.blocks.append(SnakeBlock(self.blocks[len(self.blocks) - 1].x, self.blocks[len(self.blocks) - 1].y))
        
        #300 x 300 screen means 900 blocks. If the user gets to 899 blocks, they've won
        if(len(self.blocks) >= 899):
            self.winner = True
            
    def __init__(self, maxx, maxy):
        self.direction = Direction.RIGHT
        self.blocks = [SnakeBlock(50, 50)]
        self.alive = True
        self.winner = False
        self.maxx = maxx
        self.maxy = maxy
```

The Main module



```
'''
Created on 2013-11-07

@author: Smitty
'''
import pygame
from snake import Snake
from snake import Direction
from fruit import *

from pygame.locals import QUIT
from pygame.locals import KEYDOWN
from pygame.locals import K_LEFT
from pygame.locals import K_RIGHT
from pygame.locals import K_UP
from pygame.locals import K_DOWN
from pygame.locals import K_ESCAPE
from pygame.locals import K_RETURN
from pygame.locals import K_KP_ENTER    
    
class Game:
    
    #initialize the game.
    #Load pygame and set up the game screen
    def Initialize(self):
        pygame.init()
        self.screen = pygame.display.set_mode((300, 300))
        pygame.display.set_caption('Smitty-Snake')
        pygame.mouse.set_visible(0)
        self.Blackout()
    
    #fills the entire screen with a black background
    def Blackout(self):
        background = pygame.Surface(self.screen.get_size())
        background = background.convert()
        background.fill((0, 0, 0))
        self.screen.blit(background, (0, 0))
    
    def DrawSnake(self, snake):
        pygame.time.delay(100) #the speed of the snake

        #draw each block of the snake to the screen
        for i in range(0, len(snake.blocks)):
            pygame.draw.rect(self.screen, (255, 255, 255), (snake.blocks[i].x, snake.blocks[i].y, 9, 9), 0)
            pygame.draw.rect(self.screen, (50, 50, 50), (snake.blocks[i].x, snake.blocks[i].y, 10, 10), 1)
    
    def DrawFruit(self, fruit):
        pygame.draw.rect(self.screen, fruit.colour, (fruit.x, fruit.y, 9, 9), 0)
        pygame.draw.rect(self.screen, (50, 50, 50), (fruit.x, fruit.y, 10, 10), 1)
        
    def Run(self):
        #the bounds for the game. If the snake exceeds them, game over!
        snake = Snake(300, 300)
        
        fruit = Fruit()
        
        while snake.alive and not snake.winner:
            #required to draw to the screen.
            #Update after everything has been blitted!
            pygame.display.update()
            
            for event in pygame.event.get():
                if event.type == QUIT:
                    return
                elif event.type == KEYDOWN and event.key == K_LEFT and snake.direction != Direction.RIGHT:
                    snake.direction = Direction.LEFT
                elif event.type == KEYDOWN and event.key == K_RIGHT and snake.direction != Direction.LEFT:
                    snake.direction = Direction.RIGHT
                elif event.type == KEYDOWN and event.key == K_UP and snake.direction != Direction.DOWN:
                    snake.direction = Direction.UP
                elif event.type == KEYDOWN and event.key == K_DOWN and snake.direction != Direction.UP:
                    snake.direction = Direction.DOWN
            
            #grab the position of the last block before we move it
            removeX = snake.blocks[len(snake.blocks)-1].x
            removeY = snake.blocks[len(snake.blocks)-1].y
            
            snake.Move()
            
            #draw black over the last block so the snake doesn't just keep extending
            pygame.draw.rect(self.screen, (0, 0, 0), (removeX, removeY, 10, 10), 0)
            self.DrawFruit(fruit)
            self.DrawSnake(snake)
            
            #hey, we got a fruit!
            if(snake.blocks[0].x == fruit.x and snake.blocks[0].y == fruit.y):
                snake.AddBlock()
                fruit = Fruit()
        
        #once the game ends, display the final screen
        snakeGame.Menu(len(snake.blocks), snake.winner)
            
    def Menu(self, score, winner):
        self.Blackout()
        
        gameoverFont = pygame.font.SysFont("arial", 24)
        continueFont = pygame.font.SysFont("arial", 15)
        
        if(winner):
            gameoverLabel = gameoverFont.render("You Win!", 1, (255,255,255))
            self.screen.blit(gameoverLabel, (95, 90))
        else:
            gameoverLabel = gameoverFont.render("Game Over!", 1, (255,255,255))
            self.screen.blit(gameoverLabel, (95, 90))
        
        scoreLabel = gameoverFont.render("Score: " + str(score), 1, (34, 139, 34))
        self.screen.blit(scoreLabel, (105, 120))
        
        continueLabel = continueFont.render("Press enter to play again or escape to exit.", 1 , (255,255,255))
        self.screen.blit(continueLabel, (35, 150))
        
        #again, update the screen because we're done drawing
        pygame.display.update()
        
        while 1:
            for event in pygame.event.get():
                if event.type == QUIT:
                    return
                elif event.type == KEYDOWN and event.key == K_ESCAPE:
                    return
                elif event.type == KEYDOWN and (event.key == K_RETURN or event.key == K_KP_ENTER):
                    self.Blackout()
                    snakeGame.Run()
                    return
          
snakeGame = Game()
snakeGame.Initialize() 
snakeGame.Run()
```

----------

