rev |
line source |
darkhan@105
|
1 """Copyright 2010 Aydarkhanov Ruslan, Kurochkin Ilya, Rusinov Ivan |
darkhan@105
|
2 |
darkhan@105
|
3 This file is part of Foobar. |
darkhan@105
|
4 |
darkhan@105
|
5 Foobar is free software: you can redistribute it and/or modify it under |
darkhan@105
|
6 the terms of the GNU General Public License as published |
darkhan@105
|
7 by the Free Software Foundation, either version 2 of the License, |
darkhan@105
|
8 or (at your option) any later version. |
darkhan@105
|
9 |
darkhan@105
|
10 Foobar is distributed in the hope that it will be useful, |
darkhan@105
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty |
darkhan@105
|
12 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
darkhan@105
|
13 See the GNU General Public License for more details. |
darkhan@105
|
14 |
darkhan@105
|
15 You should have received a copy of the GNU General Public License |
darkhan@105
|
16 along with Foobar. If not, see http://www.gnu.org/licenses/. |
darkhan@105
|
17 """ |
darkhan@105
|
18 |
darkhan@88
|
19 from state import * |
darkhan@20
|
20 |
Ilia@1
|
21 class Automata(object): |
darkhan@80
|
22 def __init__(self, width=150, height=70, states=None): |
darkhan@11
|
23 self.width = width |
darkhan@11
|
24 self.height = height |
darkhan@20
|
25 if states == None: |
darkhan@81
|
26 self.states = [State("Dead", '-', "white", '0', [5]), |
darkhan@88
|
27 State("Alive", '+', "black", '1', [0, 1] + range(4, 9))] |
darkhan@20
|
28 else: |
darkhan@20
|
29 self.states = states |
darkhan@11
|
30 self.symbols = {} |
darkhan@62
|
31 self.st_sym = {} |
darkhan@11
|
32 for num, st in enumerate(self.states): |
darkhan@11
|
33 self.symbols[st.symbol] = num |
darkhan@62
|
34 self.st_sym[st.symbol] = st |
darkhan@11
|
35 self.field = [] |
darkhan@11
|
36 for row in range(height): |
darkhan@11
|
37 self.field.append([]) |
darkhan@11
|
38 for col in range(width): |
darkhan@25
|
39 self.field[row].append(self.states[0].symbol) |
darkhan@11
|
40 |
darkhan@17
|
41 def next_step(self): |
darkhan@42
|
42 changed = [] |
darkhan@62
|
43 for row in range(1, self.height - 1): |
darkhan@62
|
44 for col in range(1, self.width - 1): |
darkhan@28
|
45 symbol = self.field[row][col] |
darkhan@11
|
46 num = 0 |
darkhan@62
|
47 for vert in range(row - 1, row + 2): |
darkhan@62
|
48 for horiz in range(col - 1, col + 2): |
darkhan@11
|
49 if self.field[vert][horiz] == symbol: |
darkhan@11
|
50 num += 1 |
darkhan@62
|
51 if self.st_sym[symbol].next_state(num - 1): |
darkhan@49
|
52 changed.append((row, col)) |
darkhan@62
|
53 |
darkhan@62
|
54 for row in range(1, self.height - 1): |
darkhan@62
|
55 symbol1 = self.field[row][0] |
darkhan@62
|
56 symbol2 = self.field[row][self.width - 1] |
darkhan@62
|
57 num1 = 0 |
darkhan@62
|
58 num2 = 0 |
darkhan@62
|
59 for vert in range(row - 1, row + 2): |
darkhan@62
|
60 for horiz in [0, 1, self.width - 1]: |
darkhan@62
|
61 if self.field[vert][horiz] == symbol1: |
darkhan@62
|
62 num1 += 1 |
darkhan@62
|
63 for horiz in [self.width - 2, self.width - 1, 0]: |
darkhan@62
|
64 if self.field[vert][horiz] == symbol2: |
darkhan@62
|
65 num2 += 1 |
darkhan@62
|
66 if self.st_sym[symbol1].next_state(num1 - 1): |
darkhan@62
|
67 changed.append((row, 0)) |
darkhan@62
|
68 if self.st_sym[symbol2].next_state(num2 - 1): |
darkhan@62
|
69 changed.append((row, self.width - 1)) |
darkhan@62
|
70 |
darkhan@62
|
71 for col in range(1, self.width - 1): |
darkhan@62
|
72 symbol1 = self.field[0][col] |
darkhan@62
|
73 symbol2 = self.field[self.height - 1][col] |
darkhan@62
|
74 num1 = 0 |
darkhan@62
|
75 num2 = 0 |
darkhan@62
|
76 for horiz in range(col - 1, col + 2): |
darkhan@62
|
77 for vert in [0, 1, self.height - 1]: |
darkhan@62
|
78 if self.field[vert][horiz] == symbol1: |
darkhan@62
|
79 num1 += 1 |
darkhan@62
|
80 for vert in [self.height - 2, self.height - 1, 0]: |
darkhan@62
|
81 if self.field[vert][horiz] == symbol2: |
darkhan@62
|
82 num2 += 1 |
darkhan@62
|
83 if self.st_sym[symbol1].next_state(num1 - 1): |
darkhan@62
|
84 changed.append((0, col)) |
darkhan@62
|
85 if self.st_sym[symbol2].next_state(num2 - 1): |
darkhan@62
|
86 changed.append((self.height - 1, col)) |
darkhan@62
|
87 |
darkhan@62
|
88 for row, col in [(0, 0), (self.height - 1, self.width - 1), |
darkhan@62
|
89 (0, self.width - 1), (self.height - 1, 0)]: |
darkhan@62
|
90 symbol = self.field[row][col] |
darkhan@62
|
91 num = 0 |
darkhan@62
|
92 for vert_long in range(row + self.height - 1, |
darkhan@62
|
93 row + self.height + 2): |
darkhan@62
|
94 for horiz_long in range(col + self.width - 1, |
darkhan@62
|
95 col + self.width + 2): |
darkhan@62
|
96 vert = vert_long % self.height |
darkhan@62
|
97 horiz = horiz_long % self.width |
darkhan@62
|
98 if self.field[vert][horiz] == symbol: |
darkhan@62
|
99 num += 1 |
darkhan@62
|
100 if self.st_sym[symbol].next_state(num - 1): |
darkhan@62
|
101 changed.append((row, col)) |
darkhan@11
|
102 |
darkhan@49
|
103 for row, col in changed: |
darkhan@49
|
104 index = (self.symbols[self.field[row][col]] + |
darkhan@47
|
105 1) % len(self.states) |
darkhan@49
|
106 self.field[row][col] = self.states[index].symbol |
darkhan@42
|
107 return changed |
darkhan@11
|
108 |
darkhan@17
|
109 def change_size(self, value, side): |
darkhan@17
|
110 "0-up, 1-right, 2-down, 3-left" |
darkhan@17
|
111 new_field = [] |
darkhan@20
|
112 |
darkhan@17
|
113 if side == 0: |
darkhan@17
|
114 self.height += value |
darkhan@17
|
115 for row in range(value): |
darkhan@17
|
116 new_field.append([]) |
darkhan@17
|
117 for col in range(self.width): |
darkhan@83
|
118 new_field[row].append(self.states[0].symbol) |
darkhan@20
|
119 init = value |
darkhan@20
|
120 if value < 0: |
darkhan@20
|
121 init = 0 |
darkhan@20
|
122 for row in range(init, self.height): |
darkhan@17
|
123 new_field.append([]) |
darkhan@17
|
124 for col in range(self.width): |
darkhan@17
|
125 new_field[row].append(self.field[row - value][col]) |
darkhan@20
|
126 |
darkhan@17
|
127 if side == 2: |
darkhan@17
|
128 self.height += value |
darkhan@82
|
129 term = value |
darkhan@82
|
130 if value < 0: |
darkhan@20
|
131 term = 0 |
darkhan@20
|
132 for row in range(self.height - term): |
darkhan@17
|
133 new_field.append([]) |
darkhan@17
|
134 for col in range(self.width): |
darkhan@17
|
135 new_field[row].append(self.field[row][col]) |
darkhan@82
|
136 for row in range(self.height - term, self.height): |
darkhan@17
|
137 new_field.append([]) |
darkhan@17
|
138 for col in range(self.width): |
darkhan@83
|
139 new_field[row].append(self.states[0].symbol) |
darkhan@20
|
140 |
darkhan@20
|
141 if side == 1: |
darkhan@20
|
142 self.width += value |
darkhan@82
|
143 term = value |
darkhan@82
|
144 if value < 0: |
darkhan@20
|
145 term = 0 |
darkhan@20
|
146 for row in range(self.height): |
darkhan@20
|
147 new_field.append([]) |
darkhan@20
|
148 for col in range(self.width - term): |
darkhan@20
|
149 new_field[row].append(self.field[row][col]) |
darkhan@20
|
150 for row in range(self.height): |
darkhan@82
|
151 for col in range(self.width - term, self.width): |
darkhan@83
|
152 new_field[row].append(self.states[0].symbol) |
darkhan@20
|
153 |
darkhan@20
|
154 if side == 3: |
darkhan@20
|
155 self.width += value |
darkhan@20
|
156 for row in range(self.height): |
darkhan@20
|
157 new_field.append([]) |
darkhan@20
|
158 for col in range(value): |
darkhan@83
|
159 new_field[row].append(self.states[0].symbol) |
darkhan@20
|
160 init = value |
darkhan@20
|
161 if value < 0: |
darkhan@20
|
162 init = 0 |
darkhan@20
|
163 for row in range(self.height): |
darkhan@20
|
164 for col in range(init, self.width): |
darkhan@20
|
165 new_field[row].append(self.field[row][col - value]) |
darkhan@20
|
166 self.field = new_field |