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