logo


Tag: games

Snake AI in Pygame

In this article we will show you how to create basic game AI (Artificial Intelligence). This article will describe an AI for the game snake.


In this game (snake) both the computer and you play a snake, and the computer snake tries to catch you. In short: the opponent AI tries to determine and go to the destination point based on your location on the board.

You may like

Adding the computer player:
We extend the code with a new class called Computer which will be our computer player. This contains routines to draw and move the computer snake.

class Computer:
x = [0]
y = [0]
step = 44
direction = 0
length = 3

updateCountMax = 2
updateCount = 0

def __init__(self, length):
self.length = length
for i in range(0,2000):
self.x.append(-100)
self.y.append(-100)

# initial positions, no collision.
self.x[0] = 1*44
self.y[0] = 4*44

def update(self):

self.updateCount = self.updateCount + 1
if self.updateCount > self.updateCountMax:

# update previous positions
for i in range(self.length-1,0,-1):
self.x[i] = self.x[i-1]
self.y[i] = self.y[i-1]

# update position of head of snake
if self.direction == 0:
self.x[0] = self.x[0] + self.step
if self.direction == 1:
self.x[0] = self.x[0] - self.step
if self.direction == 2:
self.y[0] = self.y[0] - self.step
if self.direction == 3:
self.y[0] = self.y[0] + self.step

self.updateCount = 0


def moveRight(self):
self.direction = 0

def moveLeft(self):
self.direction = 1

def moveUp(self):
self.direction = 2

def moveDown(self):
self.direction = 3

def draw(self, surface, image):
for i in range(0,self.length):
surface.blit(image,(self.x[i],self.y[i]))

We then call the update and drawing method of the computer.

    def on_loop(self):
self.player.update()
self.computer.update()

....

def on_render(self):
self._display_surf.fill((0,0,0))
self.player.draw(self._display_surf, self._image_surf)
self.apple.draw(self._display_surf, self._apple_surf)
self.computer.draw(self._display_surf, self._image_surf)
pygame.display.flip()

This will make the computer snake move and be drawn on the screen. It has the same properties as the human player.

Adding the intelligence to the computer player
Because this is a simple game, we do not need to create a complete thinking machine inside the game. We simply need some basic intelligence exhibited by our computer player. Intelligence in games is often quite limited because most of the time more complexity is not neccesary or there simply is not the time available to implement clever algorithms.

The algorithm we will add will simply go to the destination. It will neglect any obstacles (the human player).

def target(self,dx,dy):
if self.x[0] > dx:
self.moveLeft()

if self.x[0] < dx:
self.moveRight()

if self.x[0] == dx:
if self.y[0] < dy:
self.moveDown()

if self.y[0] > dy:
self.moveUp()

Complete code
We end up with this complete code:

from pygame.locals import *
from random import randint
import pygame
import time

class Apple:
x = 0
y = 0
step = 44

def __init__(self,x,y):
self.x = x * self.step
self.y = y * self.step

def draw(self, surface, image):
surface.blit(image,(self.x, self.y))


class Player:
x = [0]
y = [0]
step = 44
direction = 0
length = 3

updateCountMax = 2
updateCount = 0

def __init__(self, length):
self.length = length
for i in range(0,2000):
self.x.append(-100)
self.y.append(-100)

# initial positions, no collision.
self.x[0] = 1*44
self.x[0] = 2*44

def update(self):

self.updateCount = self.updateCount + 1
if self.updateCount > self.updateCountMax:

# update previous positions
for i in range(self.length-1,0,-1):
self.x[i] = self.x[i-1]
self.y[i] = self.y[i-1]

# update position of head of snake
if self.direction == 0:
self.x[0] = self.x[0] + self.step
if self.direction == 1:
self.x[0] = self.x[0] - self.step
if self.direction == 2:
self.y[0] = self.y[0] - self.step
if self.direction == 3:
self.y[0] = self.y[0] + self.step

self.updateCount = 0


def moveRight(self):
self.direction = 0

def moveLeft(self):
self.direction = 1

def moveUp(self):
self.direction = 2

def moveDown(self):
self.direction = 3

def draw(self, surface, image):
for i in range(0,self.length):
surface.blit(image,(self.x[i],self.y[i]))



class Computer:
x = [0]
y = [0]
step = 44
direction = 0
length = 3

updateCountMax = 2
updateCount = 0

def __init__(self, length):
self.length = length
for i in range(0,2000):
self.x.append(-100)
self.y.append(-100)

# initial positions, no collision.
self.x[0] = 1*44
self.y[0] = 4*44

def update(self):

self.updateCount = self.updateCount + 1
if self.updateCount > self.updateCountMax:

# update previous positions
for i in range(self.length-1,0,-1):
self.x[i] = self.x[i-1]
self.y[i] = self.y[i-1]

# update position of head of snake
if self.direction == 0:
self.x[0] = self.x[0] + self.step
if self.direction == 1:
self.x[0] = self.x[0] - self.step
if self.direction == 2:
self.y[0] = self.y[0] - self.step
if self.direction == 3:
self.y[0] = self.y[0] + self.step

self.updateCount = 0


def moveRight(self):
self.direction = 0

def moveLeft(self):
self.direction = 1

def moveUp(self):
self.direction = 2

def moveDown(self):
self.direction = 3


def target(self,dx,dy):
if self.x[0] > dx:
self.moveLeft()

if self.x[0] < dx:
self.moveRight()

if self.x[0] == dx:
if self.y[0] < dy:
self.moveDown()

if self.y[0] > dy:
self.moveUp()

def draw(self, surface, image):
for i in range(0,self.length):
surface.blit(image,(self.x[i],self.y[i]))


class Game:
def isCollision(self,x1,y1,x2,y2,bsize):
if x1 >= x2 and x1 <= x2 + bsize:
if y1 >= y2 and y1 <= y2 + bsize:
return True
return False

class App:

windowWidth = 800
windowHeight = 600
player = 0
apple = 0

def __init__(self):
self._running = True
self._display_surf = None
self._image_surf = None
self._apple_surf = None
self.game = Game()
self.player = Player(5)
self.apple = Apple(8,5)
self.computer = Computer(5)

def on_init(self):
pygame.init()
self._display_surf = pygame.display.set_mode((self.windowWidth,self.windowHeight), pygame.HWSURFACE)

pygame.display.set_caption('Pygame pythonspot.com example')
self._running = True
self._image_surf = pygame.image.load("pygame.png").convert()
self._apple_surf = pygame.image.load("apple.png").convert()

def on_event(self, event):
if event.type == QUIT:
self._running = False

def on_loop(self):
self.computer.target(self.apple.x, self.apple.y)
self.player.update()
self.computer.update()

# does snake eat apple?
for i in range(0,self.player.length):
if self.game.isCollision(self.apple.x,self.apple.y,self.player.x[i], self.player.y[i],44):
self.apple.x = randint(2,9) * 44
self.apple.y = randint(2,9) * 44
self.player.length = self.player.length + 1

# does computer eat apple?
for i in range(0,self.player.length):
if self.game.isCollision(self.apple.x,self.apple.y,self.computer.x[i], self.computer.y[i],44):
self.apple.x = randint(2,9) * 44
self.apple.y = randint(2,9) * 44
#self.computer.length = self.computer.length + 1


# does snake collide with itself?
for i in range(2,self.player.length):
if self.game.isCollision(self.player.x[0],self.player.y[0],self.player.x[i], self.player.y[i],40):
print "You lose! Collision: "
print "x[0] (" + str(self.player.x[0]) + "," + str(self.player.y[0]) + ")"
print "x[" + str(i) + "] (" + str(self.player.x[i]) + "," + str(self.player.y[i]) + ")"
exit(0)

pass

def on_render(self):
self._display_surf.fill((0,0,0))
self.player.draw(self._display_surf, self._image_surf)
self.apple.draw(self._display_surf, self._apple_surf)
self.computer.draw(self._display_surf, self._image_surf)
pygame.display.flip()

def on_cleanup(self):
pygame.quit()

def on_execute(self):
if self.on_init() == False:
self._running = False

while( self._running ):
pygame.event.pump()
keys = pygame.key.get_pressed()

if (keys[K_RIGHT]):
self.player.moveRight()

if (keys[K_LEFT]):
self.player.moveLeft()

if (keys[K_UP]):
self.player.moveUp()

if (keys[K_DOWN]):
self.player.moveDown()

if (keys[K_ESCAPE]):
self._running = False

self.on_loop()
self.on_render()

time.sleep (50.0 / 1000.0);
self.on_cleanup()

if __name__ == "__main__" :
theApp = App()
theApp.on_execute()

python snake python snake

Conclusion
You learned how to create a basic computer player using an very simple AI algorithm.

Next: Learn basic sidescroller logic

Game development with Pygame

Pygame Python Pygame Python

Welcome to the first tutorial of the series: Building games with Pygame. Games you create with Pygame can be run on any machine that supports Python, including Windows, Linux and Mac OS.

In this tutorial we will explain the fundamental of building a game with Pygame. We’ll start of with the basics and will teach you how to create the basic framework. In the next tutorials you will learn how to make certain types of games.

You may like
Python Game Development for Beginners

PyGame introduction
You’ll end up with a program similar to the one on the right:

A game always starts in an order similar to this (pseudo code):

initialize()
while running():
game_logic()
get_input()
update_screen()
deinitialize()

The game starts with initialization. All graphics are loaded, sounds are loaded, levels are loaded and any data that needs to be loaded. The game continues running until it receives a quit event. In this game loop we update the game, get input and update the screen. Depending on the game the implementation widely varies, but this fundamental structure is common in all games.

In Pygame we define this as:

import pygame
from pygame.locals import *

class App:

windowWidth = 640
windowHeight = 480
x = 10
y = 10

def __init__(self):
self._running = True
self._display_surf = None
self._image_surf = None

def on_init(self):
pygame.init()
self._display_surf = pygame.display.set_mode((self.windowWidth,self.windowHeight), pygame.HWSURFACE)
self._running = True
self._image_surf = pygame.image.load("pygame.png").convert()

def on_event(self, event):
if event.type == QUIT:
self._running = False

def on_loop(self):
pass

def on_render(self):
self._display_surf.blit(self._image_surf,(self.x,self.y))
pygame.display.flip()

def on_cleanup(self):
pygame.quit()

def on_execute(self):
if self.on_init() == False:
self._running = False

while( self._running ):
for event in pygame.event.get():
self.on_event(event)
self.on_loop()
self.on_render()
self.on_cleanup()

if __name__ == "__main__" :
theApp = App()
theApp.on_execute()

The Pygame program starts with the constructor init(). Once that is finished on_execute() is called. This method runs the game: it updates the events, updates the screen. Finally, the game is deinitialized using on_cleanup().

In the initialiasation phase we set the screen resolution and start the Pygame library:

def on_init(self):
pygame.init()
self._display_surf = pygame.display.set_mode((self.windowWidth,self.windowHeight), pygame.HWSURFACE)

We also load the image.

self._image_surf = pygame.image.load("pygame.png").convert()

This does not draw the image to the screen, that occurs in on_render().

def on_render(self):
self._display_surf.blit(self._image_surf,(self.x,self.y))
pygame.display.flip()

The blit method draws the image (image_surf) to the coordinate (x,y). In Pygame the coordinates start from (0,0) top left to (wind0wWidth, windowHeight). The method call pygame.display.flip() updates the screen.

Continue the next tutorial and learn how to add game logic and build games :-)