Last active
December 16, 2015 02:09
-
-
Save jacobgardner/5359985 to your computer and use it in GitHub Desktop.
Snape Framework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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