diff options
author | Peter Ward <peteraward@gmail.com> | 2012-07-19 20:08:23 +1000 |
---|---|---|
committer | Peter Ward <peteraward@gmail.com> | 2012-07-19 20:08:23 +1000 |
commit | 93ba106c94b7a2d2109842432fed3dbe920c3558 (patch) | |
tree | 921f139e0db186f676cba9c3917489479c51ab88 /snake.py | |
parent | 7fb2789ea7b25a4825ff4b99a832758d3533ded5 (diff) |
Move everything into a package.
Diffstat (limited to 'snake.py')
-rw-r--r-- | snake.py | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/snake.py b/snake.py deleted file mode 100644 index 89e97da..0000000 --- a/snake.py +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env python - -from __future__ import division - -import sys -import time -import string -import random -from colour import hash_colour -from random import randint -from collections import deque -from copy import deepcopy -import traceback - -from common import * - -class SnakeEngine(object): - def __init__(self, rows, columns, n_apples, wrap=False, results=False, - *args, **kwargs): - super(SnakeEngine, self).__init__(*args, **kwargs) - - self.wrap = wrap - self.bots = {} - self.results = None - if results: - self.results = open('results.csv', 'a+') - - self.new_game(rows, columns, n_apples) - - def get_random_position(self): - x = randint(0, self.columns - 1) - y = randint(0, self.rows - 1) - return (x, y) - - def replace_random(self, old, new): - for i in xrange(self.rows * self.columns): - x, y = self.get_random_position() - if self.board[y][x] == old: - self.board[y][x] = new - return x, y - - def new_game(self, rows, columns, n_apples): - self.game_ticks = 0 - self.game_id = random.randint(0, sys.maxint) - - self.letters = list(string.lowercase) - self.letters.reverse() - - self.rows = rows - self.columns = columns - - # make board - self.board = [[Squares.EMPTY for x in xrange(columns)] for y in xrange(rows)] - for i in xrange(n_apples): - x, y = self.get_random_position() - self.board[y][x] = Squares.APPLE - - def add_bot(self, bot): - """ - A bot is a callable object, with this method signature: - def bot_callable( - board=[[cell for cell in row] for row in board], - position=(snake_x, snake_y) - ): - return random.choice('RULD') - """ - letter = self.letters.pop() - - name = bot.__name__ - colour = hash_colour(name) - - position = self.replace_random(Squares.EMPTY, letter.upper()) - if position is None: - raise KeyError, "Could not insert snake into the board." - - self.bots[letter] = [bot, colour, deque([position])] - return letter - - def remove_bot(self, letter): - letter = letter.lower() - - time_score = self.game_ticks - - for row in self.board: - for x, cell in enumerate(row): - if cell.lower() == letter: - row[x] = Squares.EMPTY - - bot = self.bots[letter] - del self.bots[letter] - - if not self.results: - return - - try: - name = bot[0].__name__ - except AttributeError: - pass - else: - apple_score = len(bot[2]) - self.results.write('%s,%s,%s,%s\n' % \ - (self.game_id, name, apple_score, time_score)) - self.results.flush() - - def update_snakes(self, directions_id=id(directions)): - assert id(directions) == directions_id, \ - "The common.directions dictionary has been modified since startup..." - - self.game_ticks += 1 - - for letter, (bot, colour, path) in self.bots.items(): - board = deepcopy(self.board) - try: - x, y = path[-1] - d = bot(board, (x, y)) - - # Sanity checking... - assert isinstance(d, basestring), \ - "Return value should be a string." - d = d.upper() - assert d in directions, "Return value should be 'U', 'D', 'L' or 'R'." - - # Get new position. - dx, dy = directions[d] - nx = x + dx - ny = y + dy - - if self.wrap: - ny %= self.rows - nx %= self.columns - else: - if ny < 0 or ny >= self.rows or nx < 0 or nx >= self.columns: - self.remove_bot(letter) - continue - - oldcell = self.board[ny][nx] - if oldcell in (Squares.EMPTY, Squares.APPLE): - # Move snake forward. - self.board[ny][nx] = letter.upper() - path.append((nx, ny)) - - # Make old head into body. - self.board[y][x] = letter.lower() - - if oldcell == Squares.APPLE: - # Add in an apple to compensate. - self.replace_random(Squares.EMPTY, Squares.APPLE) - else: - # Remove last part of snake. - ox, oy = path.popleft() - self.board[oy][ox] = Squares.EMPTY - else: - self.remove_bot(letter) - - except: - print "Exception in bot %s (%s):" % (letter.upper(), bot) - print '-'*60 - traceback.print_exc() - print '-'*60 - self.remove_bot(letter) - |