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

snake

view snake.py @ 96:3619305694ad

Actually fixed buttons resizing. Fixed code separation for buttons drawing.
author Danya Alexeyevsky <me.dendik@gmail.com>
date Mon, 20 Dec 2010 02:26:35 +0300
parents 2f56e186e75c
children c68b54a43501
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 for line in file:
35 magic, self.name = preprocess(line).split(' ', 1)
36 break
37 assert magic == "snake", "This is not snake file"
38 for line in file:
39 line = preprocess(line)
40 if line == 'end':
41 break
42 assert line == '', "Rules must be separated by empty lines"
43 self.rules.append(Rule(self).load(file))
45 def fill (self):
46 """Mark every cell in `self.cells` as belonging to self."""
47 for cell in self.cells:
48 cell.snake = self
49 self.cells[0].type = 'head'
50 for cell in self.cells[1:-1]:
51 cell.type = 'body'
52 self.cells[-1].type = 'tail'
53 return
55 class Rule(object):
56 """Rule defining possible behaviour of snake."""
58 codes = {
59 'h': 'head',
60 'b': 'body',
61 't': 'tail',
62 '#': 'wall',
63 ' ': 'any',
64 '-': 'empty',
65 }
67 def __init__ (self, snake):
68 self.snake = snake
69 self.direction = (0, -1)
70 self.pattern = {}
72 def load (self, file):
73 """Load rule definition from file.
75 Ignore any leading empty lines.
76 Return self.
77 """
78 y = 0
79 for line in file:
80 line = preprocess(line)
81 if y == 0 and line == '':
82 continue
83 assert len(line) == 8, "Rule lines must be exactly 7 chars long"
84 assert line[-1] == ';', "Rule lines must end with semicolon"
85 for x, char in enumerate(line[:7]):
86 self.parse_cell(x, y, char)
87 y += 1
88 if y == 7:
89 break
90 return self
92 def parse_cell(self, x, y, char):
93 """Parse definition of cell in rule file.
95 Cell is defined by one character.
96 """
97 is_my = char.islower()
98 char = char.lower()
99 assert char in self.codes, "Illegal symbol in rule: %s" % char
100 cell = engine.Cell(x, y, self.snake)
101 if char in 'htb':
102 if is_my:
103 cell.snake_type = 'my'
104 else:
105 cell.snake_type = 'enemy'
106 if char == 'h':
107 assert (x, y) == (3, 3), "Own head must in the center of rule"
108 if (x, y) == (3, 3):
109 assert char == 'h', "In the center of rule must be own head"
110 cell.type = self.codes[char]
111 self.pattern[x, y] = cell
113 def applies (self, field, x, y):
114 """True if the rule applies in the field at position (x,y)."""
115 for px, fx in zip(range(7), range(x - 3, x + 4)):
116 for py, fy in zip(range(7), range(y - 3, y + 4)):
117 if (fx, fy) in field:
118 if field[fx, fy] != self.pattern[px, py]:
119 return False
120 else:
121 if self.pattern[px, py].type != 'any':
122 return False
123 return True
125 def rotate (self, rot):
126 """Rotate rule pattern `rot` times counterclockwise."""
127 for i in range(((rot % 4) + 4) % 4):
128 self.rotate_ccw()
130 def rotate_ccw(self):
131 """Rotate rule pattern one time counterclockwise."""
132 pattern = {}
133 for x in range(7):
134 for y in range(7):
135 pattern[y, 6 - x] = self.pattern[x, y]
136 self.pattern = pattern
137 x, y = self.direction
138 self.direction = y, -x
140 # vim: set ts=4 sts=4 sw=4 et: