Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.fbb.msu.ru/hg/snake/annotate/e1cfe742dda8/snake.py
Дата изменения: Unknown
Дата индексирования: Fri Feb 28 20:48:43 2014
Кодировка:
snake: snake.py annotate

snake

annotate snake.py @ 50:e1cfe742dda8

Automated merge with ssh://kodomo/snake
author Daniil Alexeyevsky <me.dendik@gmail.com>
date Sun, 19 Dec 2010 23:31:56 +0300
parents acaa43cb15ad
children 995c5300f498
rev   line source
me@44 1 """Guts of snakes."""
me@44 2
me@34 3 import engine
me@34 4
me@34 5 def preprocess(line):
me@44 6 """Remove comments and junk spaces from line of snake definition file."""
me@34 7 if '//' in line:
me@34 8 line = line[:line.index('//')]
me@34 9 line = line.rstrip()
me@34 10 return line
martiran@30 11
martiran@30 12 class Snake(object):
me@44 13 """Snakes.
me@44 14
me@44 15 Attributes:
me@44 16
me@44 17 - `cells` -- list of cells belonging to the snake The first of these cells
me@44 18 becomes head, the last one becomes tail, the rest ar body. If snake has
me@44 19 only one cell, it is tail.
me@44 20 - `color` -- color of snake
me@44 21 - `rules` -- a list of Rule objects
me@44 22 """
me@44 23
martiran@32 24 def __init__ (self, cells, color):
martiran@32 25 self.cells = cells
martiran@32 26 self.color = color
martiran@32 27 self.rules = []
me@34 28
me@34 29 def load (self, file):
me@44 30 """Load snake description from file.
me@44 31
me@44 32 See program design docs for file syntax.
me@44 33 """
me@34 34 magic, name = preprocess(file.readline()).split(' ', 1)
me@34 35 assert magic == "snake", "This is not snake file"
me@34 36 while True:
me@34 37 line = preprocess(file.readline())
me@34 38 if line == 'end':
me@34 39 break
me@34 40 assert line == '', "Rules must be separated by empty lines"
me@34 41 self.rules.append(Rule().load(file))
me@34 42
martiran@30 43 def fill (self):
me@44 44 """Mark every cell in `self.cells` as belonging to self."""
martiran@32 45 for cell in self.cells:
martiran@32 46 cell.snake = self
martiran@31 47 snake.cells[0].type = 'head'
me@45 48 for cell in self.cells[1:-1]:
me@45 49 cell.type = 'body'
martiran@31 50 snake.cells[-1].type = 'tail'
martiran@31 51 return
me@34 52
martiran@30 53 class Rule(object):
me@44 54 """Rule defining possible behaviour of snake."""
me@34 55
me@34 56 codes = {
me@34 57 'h': 'head',
me@34 58 'b': 'body',
me@34 59 't': 'tail',
me@34 60 '#': 'wall',
me@34 61 ' ': 'any',
me@34 62 '-': 'empty',
me@34 63 }
me@34 64
martiran@32 65 def __init__ (self, snake):
martiran@32 66 self.snake = snake
me@34 67 self.direction = (1, 0)
me@34 68 self.pattern = {}
me@34 69
me@34 70 def load (self, file):
me@44 71 """Load rule definition from file. Ignore any leading empty lines."""
me@34 72 y = 0
me@34 73 for line in file:
me@34 74 line = preprocess(line)
me@34 75 if y == 0 and line == '':
me@34 76 continue
me@36 77 if y == 7:
me@36 78 break
me@41 79 assert len(line) == 8, "Rule lines must be exactly 7 chars long"
me@34 80 assert line[-1] == ';', "Rule lines must end with semicolon"
me@34 81 for x, char in enumerate(line[:8]):
me@34 82 self.parse_cell(x, y, char)
me@34 83 y += 1
me@34 84
me@34 85 def parse_cell(self, x, y, char):
me@44 86 """Parse definition of cell in rule file.
me@44 87
me@44 88 Cell is defined by one character.
me@44 89 """
me@34 90 assert char.lower() in self.codes, "Illegal symbol in rule: %s" % char
me@34 91 cell = engine.Cell(x, y, None)
me@34 92 if char in 'htb':
me@34 93 if char.islower():
me@34 94 cell.snake = 'my'
me@34 95 else:
me@34 96 cell.snake = 'enemy'
me@37 97 if char == 'h':
me@37 98 assert (x, y) == (3, 3), "Own head must in the center of rule"
me@37 99 if (x, y) == (3, 3):
me@37 100 assert char == 'h', "In the center of rule must be own head"
me@34 101 cell.type = self.codes[char.lower()]
me@34 102 self.pattern[x, y] = cell
me@34 103
martiran@32 104 def applies (self, field, x, y):
me@44 105 """True if the rule applies in the field at position (x,y)."""
me@38 106 for px, fx in zip(range(7), range(x - 3, x + 4)):
me@38 107 for py, fy in zip(range(7), range(y - 3, y + 4)):
me@49 108 if (fx, fy) in field:
me@43 109 if field[fx, fy] != self.pattern[px, py]:
me@43 110 return False
me@43 111 else:
me@43 112 if self.pattern[px, py].type != 'any':
me@43 113 return False
me@38 114 return True
me@34 115
martiran@32 116 def rotate (self, rot):
me@44 117 """Rotate rule pattern `rot` times counterclockwise."""
me@39 118 for i in range(((rot % 4) + 4) % 4):
me@39 119 self.rotate_ccw()
me@39 120
me@39 121 def rotate_ccw(self):
me@44 122 """Rotate rule pattern one time counterclockwise."""
me@39 123 pattern = {}
me@39 124 for x in range(7):
me@39 125 for y in range(7):
me@39 126 pattern[y, 6 - x] = self.pattern[x, y]
me@39 127 self.pattern = pattern
me@39 128 x, y = self.direction
me@39 129 self.direction = y, -x
me@34 130
me@34 131 # vim: set ts=4 sts=4 sw=4 et: