snake
diff snake.py @ 47:14c3d41ce15d
Merge
author | Alex Martynov <martiran@kodomo.fbb.msu.ru> |
---|---|
date | Sun, 19 Dec 2010 23:26:16 +0300 |
parents | 2a7b76d66e78 |
children | acaa43cb15ad |
line diff
1.1 --- a/snake.py Sun Dec 19 23:25:25 2010 +0300 1.2 +++ b/snake.py Sun Dec 19 23:26:16 2010 +0300 1.3 @@ -1,18 +1,36 @@ 1.4 +"""Guts of snakes.""" 1.5 + 1.6 import engine 1.7 1.8 def preprocess(line): 1.9 + """Remove comments and junk spaces from line of snake definition file.""" 1.10 if '//' in line: 1.11 line = line[:line.index('//')] 1.12 line = line.rstrip() 1.13 return line 1.14 1.15 class Snake(object): 1.16 + """Snakes. 1.17 + 1.18 + Attributes: 1.19 + 1.20 + - `cells` -- list of cells belonging to the snake The first of these cells 1.21 + becomes head, the last one becomes tail, the rest ar body. If snake has 1.22 + only one cell, it is tail. 1.23 + - `color` -- color of snake 1.24 + - `rules` -- a list of Rule objects 1.25 + """ 1.26 + 1.27 def __init__ (self, cells, color): 1.28 self.cells = cells 1.29 self.color = color 1.30 self.rules = [] 1.31 1.32 def load (self, file): 1.33 + """Load snake description from file. 1.34 + 1.35 + See program design docs for file syntax. 1.36 + """ 1.37 magic, name = preprocess(file.readline()).split(' ', 1) 1.38 assert magic == "snake", "This is not snake file" 1.39 while True: 1.40 @@ -23,6 +41,7 @@ 1.41 self.rules.append(Rule().load(file)) 1.42 1.43 def fill (self): 1.44 + """Mark every cell in `self.cells` as belonging to self.""" 1.45 for cell in self.cells: 1.46 cell.snake = self 1.47 snake.cells[0].type = 'head' 1.48 @@ -31,6 +50,7 @@ 1.49 return 1.50 1.51 class Rule(object): 1.52 + """Rule defining possible behaviour of snake.""" 1.53 1.54 codes = { 1.55 'h': 'head', 1.56 @@ -47,6 +67,7 @@ 1.57 self.pattern = {} 1.58 1.59 def load (self, file): 1.60 + """Load rule definition from file. Ignore any leading empty lines.""" 1.61 y = 0 1.62 for line in file: 1.63 line = preprocess(line) 1.64 @@ -54,13 +75,17 @@ 1.65 continue 1.66 if y == 7: 1.67 break 1.68 + assert len(line) == 8, "Rule lines must be exactly 7 chars long" 1.69 assert line[-1] == ';', "Rule lines must end with semicolon" 1.70 - assert len(line) == 8, "Rule lines must be exactly 7 chars long" 1.71 for x, char in enumerate(line[:8]): 1.72 self.parse_cell(x, y, char) 1.73 y += 1 1.74 1.75 def parse_cell(self, x, y, char): 1.76 + """Parse definition of cell in rule file. 1.77 + 1.78 + Cell is defined by one character. 1.79 + """ 1.80 assert char.lower() in self.codes, "Illegal symbol in rule: %s" % char 1.81 cell = engine.Cell(x, y, None) 1.82 if char in 'htb': 1.83 @@ -76,25 +101,24 @@ 1.84 self.pattern[x, y] = cell 1.85 1.86 def applies (self, field, x, y): 1.87 + """True if the rule applies in the field at position (x,y).""" 1.88 for px, fx in zip(range(7), range(x - 3, x + 4)): 1.89 for py, fy in zip(range(7), range(y - 3, y + 4)): 1.90 - pcell = self.pattern[px, py] 1.91 - fcell = field.get(fx, fy) 1.92 - if pcell.type == 'any': 1.93 - continue 1.94 - if pcell.type != fcell.type: 1.95 - return False 1.96 - if pcell.snake == 'my' and fcell.snake != self.snake: 1.97 - return False 1.98 - elif pcell.snake == 'enemy' and fcell.snake == self.snake: 1.99 - return False 1.100 + if fx, fy in field: 1.101 + if field[fx, fy] != self.pattern[px, py]: 1.102 + return False 1.103 + else: 1.104 + if self.pattern[px, py].type != 'any': 1.105 + return False 1.106 return True 1.107 1.108 def rotate (self, rot): 1.109 + """Rotate rule pattern `rot` times counterclockwise.""" 1.110 for i in range(((rot % 4) + 4) % 4): 1.111 self.rotate_ccw() 1.112 1.113 def rotate_ccw(self): 1.114 + """Rotate rule pattern one time counterclockwise.""" 1.115 pattern = {} 1.116 for x in range(7): 1.117 for y in range(7):