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

snake

view engine.py @ 139:cd7658cb90eb

Added rule.number to aid snake debugging.
author Daniil Alexeyevsky <me.dendik@gmail.com>
date Mon, 20 Dec 2010 17:49:57 +0300
parents b7d2bfd5860d
children 8b5bc7bda225
line source
1 import random as rnd
2 import Tkinter as tk
3 import snake
5 directions = [(0,1), (1,0), (0,-1), (-1,0)]
7 class Dict(dict):
8 pass
10 class Cell(object):
11 def __init__(self, x, y, canvas = None):
12 self.x = x
13 self.y = y
14 self.canvas = canvas
15 self.snake = None
16 self.type = 'empty'
17 return
18 def redraw(self, offset, c_size):
19 x0=offset[0] + self.x*c_size
20 y0=offset[1] + self.y*c_size
21 x1=offset[0] + (self.x+1)*c_size
22 y1=offset[1] + (self.y+1)*c_size
23 x2=offset[0] + (self.x+1/2.0)*c_size
24 if self.type == 'wall':
25 self.canvas.create_rectangle(x0, y0, x1, y1, fill="grey")
26 pass
27 elif self.type == 'empty':
28 self.canvas.create_rectangle(x0, y0, x1, y1, fill="black")
29 pass
30 elif self.type == 'body':
31 self.canvas.create_rectangle(x0, y0, x1, y1, fill=self.snake.color)
32 pass
33 elif self.type == 'head':
34 self.canvas.create_oval(x0, y0, x1, y1, fill=self.snake.color)
35 pass
36 elif self.type == 'tail':
37 self.canvas.create_polygon(x0, y0, x1, y0, x2, y1, fill=self.snake.color)
38 pass
39 return
40 def __eq__(self, pattern):
41 if pattern.type == 'any':
42 return True
43 if pattern.type != self.type:
44 return False
45 if pattern.snake_type == 'my' and pattern.snake != self.snake:
46 return False
47 elif pattern.snake_type == 'enemy' and pattern.snake == self.snake:
48 return False
49 return True
51 def __ne__(self, pattern):
52 return not self == pattern
54 def clear(self):
55 self.snake = None
56 self.type = 'empty'
57 return
60 class Engine(object):
61 def __init__(self, canvas):
62 self.canvas = canvas
63 self.w = min(canvas.winfo_height(), canvas.winfo_width())
64 self.h = min(canvas.winfo_height(), canvas.winfo_width())
65 self.snakes = [None, None, None, None]
66 self.init_field()
67 self.start_snake_length = 10
68 return
69 def init_field (self):
70 self.field = Dict()
71 self.field.w = 31
72 self.field.h = 31
73 f_w = self.field.w
74 f_h = self.field.h
75 for x in range(f_w):
76 for y in range(f_h):
77 self.field[x, y] = Cell(x, y, self.canvas)
78 for y in range(f_h):
79 self.field[0, y].type = 'wall'
80 self.field[f_w-1, y].type = 'wall'
81 for x in range(1,f_w-1):
82 self.field[x, 0].type = 'wall'
83 self.field[x, f_h-1].type = 'wall'
84 self.refill()
85 self.redraw()
86 return
87 def step(self):
88 for i, snake in enumerate(self.snakes):
89 if snake != None:
90 if len(snake.cells) == 0:
91 self.snakes[i] = None
92 continue
93 self.legal_moves(snake)
94 self.move_snake(snake)
95 self.refill()
96 self.redraw()
97 return
98 def move_snake(self, snake):
99 head = snake.cells[0]
100 for rule in snake.rules:
101 for direction in snake.legal_dir:
102 rule.rotate(direction)
103 if rule.applies(self.field, head.x, head.y) == True:
104 self.move_do(snake, direction)
105 return
106 if snake.legal_dir != []:
107 self.move_do(snake, snake.legal_dir[0])
108 pass
109 return
110 def move_do(self, snake, applied_dir):
111 head = snake.cells[0]
112 dir_cell = self.field[head.x + applied_dir[0], head.y + applied_dir[1]]
113 if dir_cell.type == 'empty':
114 snake.cells.insert(0,dir_cell)
115 del snake.cells[-1]
116 pass
117 elif (dir_cell.type == 'tail' and dir_cell.snake != snake):
118 snake.cells.insert(0,dir_cell)
119 del dir_cell.snake.cells[-1]
120 pass
122 def create_snake(self, snake_number):
123 cells_id = []
124 f_h = self.field.h
125 f_w = self.field.w
126 for y in range(self.start_snake_length):
127 cells_id.append(((f_w-1)/2, y+1))
128 for rot_num in range(snake_number - 1):
129 for i, cell in enumerate(cells_id):
130 cells_id[i] = (min(f_h, f_w)-1-cell[1],cell[0])
131 cells = []
132 for cell in cells_id:
133 cells.append(self.field[cell])
134 color_dic = {
135 1:'blue',
136 2:'green',
137 3:'yellow',
138 4:'red',}
139 self.snakes[snake_number-1] = snake.Snake(cells, color_dic[snake_number])
140 return self.snakes[snake_number-1]
141 def refill(self):
142 f_w = self.field.w
143 f_h = self.field.h
144 for x in range(1,f_w-1):
145 for y in range(1,f_h-1):
146 self.field[x, y].type = 'empty'
147 self.field[x, y].snake = None
148 pass
149 for snake in self.snakes:
150 if snake == None:
151 pass
152 else:
153 snake.fill()
154 pass
155 return
156 def redraw(self):
157 self.canvas.delete("all")
158 w = self.canvas.winfo_width()
159 h = self.canvas.winfo_height()
160 cw = w/float(self.field.w)
161 ch = h/float(self.field.h)
162 c = min(cw, ch)
163 field_geometry = (self.field.w*c,self.field.h*c)
164 offset = ((w - field_geometry[0])/2.0, (h - field_geometry[1])/2.0)
165 for cell_coord in self.field:
166 self.field[cell_coord].redraw(offset, c)
167 return
168 def legal_moves(self, snake):
169 snake.legal_dir = []
170 head = snake.cells[0]
171 for direction in directions:
172 dir_cell = self.field[head.x + direction[0], head.y + direction[1]]
173 if (dir_cell.type == 'empty' or (dir_cell.type == 'tail' and dir_cell.snake != snake)):
174 snake.legal_dir.append(direction)
175 rnd.shuffle(snake.legal_dir)
176 return