Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.fbb.msu.ru/hg/snake/file/2f62804e21fc/snake.py
Дата изменения: Unknown
Дата индексирования: Sun Feb 3 08:37:06 2013
Кодировка:
snake: 2f62804e21fc snake.py

snake

view snake.py @ 57:2f62804e21fc

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