Skip to content

Instantly share code, notes, and snippets.

@jacobgardner
Last active December 16, 2015 02:09
Show Gist options
  • Save jacobgardner/5359985 to your computer and use it in GitHub Desktop.
Save jacobgardner/5359985 to your computer and use it in GitHub Desktop.
Snape Framework
'''
This module contains a class to represent a snape board. Snape is a game where you try to feed snape as many apples as you can without letting snape run into himeself. Every time your snape eats an apple, your snape grows in size.
'''
from __future__ import print_function
import random
from collections import namedtuple
import itertools
EMPTY = 0
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4
APPLE = 5
Point = namedtuple('Point', ['x', 'y'])
class Board(object):
def __init__(self, width, height, start=None, apple=None, tailgrowth=3):
'''
Represents where snape is, his head is and his feet are, along with
apples on the board.
:param width: Board width. Should be greater than 0
:type width: int
:param height: Board height: Should be greater than 0
:type height: int
:param start: (x, y) of your starting position. Defaults to random
:type start: 2-tuple containing ints
:param apple: (x, y) of your starting apple. Defaults to random
:type apple: 2-tuple containing ints
:param tailgrowth: Size snape grows when he eats an apple
:type tailgrowth: int
'''
self.width = width
self.height = height
self.growth = tailgrowth
self.points = 0
self.tail_size = 0
self.max_tail = tailgrowth
board = {}
for w in range(width):
board[w] = {}
for h in range(height):
board[w][h] = EMPTY
self.board = board
if start:
self.tail = self.head = Point(*start)
else:
self.tail = self.head = Point(
random.randint(0, width-1),
random.randint(0, height-1),
)
if apple:
self.apple = Point(*apple)
else:
self._eat()
self.points = 0
def _eat(self):
'''
Snape eats an apple
'''
available = []
for x, y in itertools.product(range(self.width), range(self.height)):
if self.board[x][y] == EMPTY and not (
x == self.head.x and y == self.head.y):
available += [Point(x, y)]
self.apple = random.sample(available, 1)[0]
self.max_tail += self.growth
self.points += 1
def move(self, dir):
'''
Direction to move snape
:param dir: Direction to move snape
:type dir: int (LEFT, RIGHT, UP, DOWN)
'''
self.board[self.head.x][self.head.y] = dir
if dir == LEFT:
assert self.head.x > 0
new_head = Point(self.head.x - 1, self.head.y)
elif dir == RIGHT:
assert self.head.x < self.width - 1
new_head = Point(self.head.x + 1, self.head.y)
elif dir == UP:
assert self.head.y < self.height - 1
new_head = Point(self.head.x, self.head.y + 1)
elif dir == DOWN:
assert self.head.y > 0
new_head = Point(self.head.x, self.head.y - 1)
assert self.board[new_head.x][new_head.y] == EMPTY
self.head = new_head
if self.tail_size < self.max_tail:
self.tail_size += 1
else:
d = self.board[self.tail.x][self.tail.y]
if d == LEFT:
new_tail = Point(self.tail.x - 1, self.tail.y)
elif d == RIGHT:
new_tail = Point(self.tail.x + 1, self.tail.y)
elif d == UP:
new_tail = Point(self.tail.x, self.tail.y + 1)
elif d == DOWN:
new_tail = Point(self.tail.x, self.tail.y - 1)
else:
assert 0
self.board[self.tail.x][self.tail.y] = EMPTY
self.tail = new_tail
if new_head.x == self.apple.x and new_head.y == self.apple.y:
self._eat()
def __str__(self):
b = ''
b += '----------------------------------\n'
b += 'Points: {0} Tail: {1}\n'.format(self.points, self.max_tail)
b += '----------------------------------\n'
b += '+' + '-' * self.width + '+\n'
board = self.board
for y in reversed(range(self.height)):
b += '|'
for x in range(self.width):
if board[x][y] == LEFT:
b += '<'
elif board[x][y] == RIGHT:
b += '>'
elif board[x][y] == UP:
b += '^'
elif board[x][y] == DOWN:
b += 'v'
elif x == self.apple.x and y == self.apple.y:
b += 'a'
elif x == self.head.x and y == self.head.y:
b += 'h'
else:
b += ' '
b += '|\n'
b += '+' + '-' * self.width + '+\n'
return b
if __name__ == '__main__':
SIZE = 19
b = Board(20, 20, (0, 0), (SIZE, SIZE))
moves = [RIGHT] * SIZE + [UP] * SIZE + [LEFT] * SIZE + [DOWN] * SIZE
moves += [RIGHT] * SIZE + [UP] * SIZE + [LEFT] * SIZE + [DOWN] * SIZE
for m in moves:
print(b)
b.move(m)
print(b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment