rev |
line source |
darkhan@20
|
1 from State import * |
darkhan@20
|
2 |
Ilia@1
|
3 class Automata(object): |
darkhan@23
|
4 #field[][] - state symbol |
Ilia@1
|
5 #states[] |
darkhan@23
|
6 #symbols = {} - symbol: number_in_states |
darkhan@11
|
7 |
darkhan@35
|
8 def __init__(self, width=50, height=50, states=None): |
darkhan@11
|
9 self.width = width |
darkhan@11
|
10 self.height = height |
darkhan@20
|
11 if states == None: |
is_rusinov@68
|
12 self.states = [State("Dead", '-', "white", '1',[5]), |
is_rusinov@68
|
13 State("Alive", '+', "black", '2', [0, 1] + range(4, 9))] |
darkhan@20
|
14 else: |
darkhan@20
|
15 self.states = states |
darkhan@11
|
16 self.symbols = {} |
darkhan@62
|
17 self.st_sym = {} |
darkhan@11
|
18 for num, st in enumerate(self.states): |
darkhan@11
|
19 self.symbols[st.symbol] = num |
darkhan@62
|
20 self.st_sym[st.symbol] = st |
darkhan@11
|
21 self.field = [] |
darkhan@11
|
22 for row in range(height): |
darkhan@11
|
23 self.field.append([]) |
darkhan@11
|
24 for col in range(width): |
darkhan@25
|
25 self.field[row].append(self.states[0].symbol) |
darkhan@11
|
26 |
darkhan@17
|
27 def next_step(self): |
darkhan@42
|
28 changed = [] |
darkhan@62
|
29 for row in range(1, self.height - 1): |
darkhan@62
|
30 for col in range(1, self.width - 1): |
darkhan@28
|
31 symbol = self.field[row][col] |
darkhan@11
|
32 num = 0 |
darkhan@62
|
33 for vert in range(row - 1, row + 2): |
darkhan@62
|
34 for horiz in range(col - 1, col + 2): |
darkhan@11
|
35 if self.field[vert][horiz] == symbol: |
darkhan@11
|
36 num += 1 |
darkhan@62
|
37 if self.st_sym[symbol].next_state(num - 1): |
darkhan@49
|
38 changed.append((row, col)) |
darkhan@62
|
39 |
darkhan@62
|
40 for row in range(1, self.height - 1): |
darkhan@62
|
41 symbol1 = self.field[row][0] |
darkhan@62
|
42 symbol2 = self.field[row][self.width - 1] |
darkhan@62
|
43 num1 = 0 |
darkhan@62
|
44 num2 = 0 |
darkhan@62
|
45 for vert in range(row - 1, row + 2): |
darkhan@62
|
46 for horiz in [0, 1, self.width - 1]: |
darkhan@62
|
47 if self.field[vert][horiz] == symbol1: |
darkhan@62
|
48 num1 += 1 |
darkhan@62
|
49 for horiz in [self.width - 2, self.width - 1, 0]: |
darkhan@62
|
50 if self.field[vert][horiz] == symbol2: |
darkhan@62
|
51 num2 += 1 |
darkhan@62
|
52 if self.st_sym[symbol1].next_state(num1 - 1): |
darkhan@62
|
53 changed.append((row, 0)) |
darkhan@62
|
54 if self.st_sym[symbol2].next_state(num2 - 1): |
darkhan@62
|
55 changed.append((row, self.width - 1)) |
darkhan@62
|
56 |
darkhan@62
|
57 for col in range(1, self.width - 1): |
darkhan@62
|
58 symbol1 = self.field[0][col] |
darkhan@62
|
59 symbol2 = self.field[self.height - 1][col] |
darkhan@62
|
60 num1 = 0 |
darkhan@62
|
61 num2 = 0 |
darkhan@62
|
62 for horiz in range(col - 1, col + 2): |
darkhan@62
|
63 for vert in [0, 1, self.height - 1]: |
darkhan@62
|
64 if self.field[vert][horiz] == symbol1: |
darkhan@62
|
65 num1 += 1 |
darkhan@62
|
66 for vert in [self.height - 2, self.height - 1, 0]: |
darkhan@62
|
67 if self.field[vert][horiz] == symbol2: |
darkhan@62
|
68 num2 += 1 |
darkhan@62
|
69 if self.st_sym[symbol1].next_state(num1 - 1): |
darkhan@62
|
70 changed.append((0, col)) |
darkhan@62
|
71 if self.st_sym[symbol2].next_state(num2 - 1): |
darkhan@62
|
72 changed.append((self.height - 1, col)) |
darkhan@62
|
73 |
darkhan@62
|
74 for row, col in [(0, 0), (self.height - 1, self.width - 1), |
darkhan@62
|
75 (0, self.width - 1), (self.height - 1, 0)]: |
darkhan@62
|
76 symbol = self.field[row][col] |
darkhan@62
|
77 num = 0 |
darkhan@62
|
78 for vert_long in range(row + self.height - 1, |
darkhan@62
|
79 row + self.height + 2): |
darkhan@62
|
80 for horiz_long in range(col + self.width - 1, |
darkhan@62
|
81 col + self.width + 2): |
darkhan@62
|
82 vert = vert_long % self.height |
darkhan@62
|
83 horiz = horiz_long % self.width |
darkhan@62
|
84 if self.field[vert][horiz] == symbol: |
darkhan@62
|
85 num += 1 |
darkhan@62
|
86 if self.st_sym[symbol].next_state(num - 1): |
darkhan@62
|
87 changed.append((row, col)) |
darkhan@11
|
88 |
darkhan@49
|
89 for row, col in changed: |
darkhan@49
|
90 index = (self.symbols[self.field[row][col]] + |
darkhan@47
|
91 1) % len(self.states) |
darkhan@49
|
92 self.field[row][col] = self.states[index].symbol |
darkhan@42
|
93 return changed |
darkhan@11
|
94 |
darkhan@17
|
95 def change_size(self, value, side): |
darkhan@17
|
96 "0-up, 1-right, 2-down, 3-left" |
darkhan@17
|
97 new_field = [] |
darkhan@20
|
98 |
darkhan@17
|
99 if side == 0: |
darkhan@17
|
100 self.height += value |
darkhan@17
|
101 for row in range(value): |
darkhan@17
|
102 new_field.append([]) |
darkhan@17
|
103 for col in range(self.width): |
darkhan@17
|
104 new_field[row].append(states[0].symbol) |
darkhan@20
|
105 init = value |
darkhan@20
|
106 if value < 0: |
darkhan@20
|
107 init = 0 |
darkhan@20
|
108 for row in range(init, self.height): |
darkhan@17
|
109 new_field.append([]) |
darkhan@17
|
110 for col in range(self.width): |
darkhan@17
|
111 new_field[row].append(self.field[row - value][col]) |
darkhan@20
|
112 |
darkhan@17
|
113 if side == 2: |
darkhan@17
|
114 self.height += value |
darkhan@20
|
115 term = -value |
darkhan@20
|
116 if value > 0: |
darkhan@20
|
117 term = 0 |
darkhan@20
|
118 for row in range(self.height - term): |
darkhan@17
|
119 new_field.append([]) |
darkhan@17
|
120 for col in range(self.width): |
darkhan@17
|
121 new_field[row].append(self.field[row][col]) |
darkhan@17
|
122 for row in range(self.height, self.height + value): |
darkhan@17
|
123 new_field.append([]) |
darkhan@17
|
124 for col in range(self.width): |
darkhan@20
|
125 new_field[row].append(states[0].symbol) |
darkhan@20
|
126 |
darkhan@20
|
127 if side == 1: |
darkhan@20
|
128 self.width += value |
darkhan@20
|
129 term = -value |
darkhan@20
|
130 if value > 0: |
darkhan@20
|
131 term = 0 |
darkhan@20
|
132 for row in range(self.height): |
darkhan@20
|
133 new_field.append([]) |
darkhan@20
|
134 for col in range(self.width - term): |
darkhan@20
|
135 new_field[row].append(self.field[row][col]) |
darkhan@20
|
136 for row in range(self.height): |
darkhan@20
|
137 for col in range(self.width, self.width + value): |
darkhan@20
|
138 new_field[row].append(states[0].symbol) |
darkhan@20
|
139 |
darkhan@20
|
140 if side == 3: |
darkhan@20
|
141 self.width += value |
darkhan@20
|
142 for row in range(self.height): |
darkhan@20
|
143 new_field.append([]) |
darkhan@20
|
144 for col in range(value): |
darkhan@20
|
145 new_field[row].append(states[0].symbol) |
darkhan@20
|
146 init = value |
darkhan@20
|
147 if value < 0: |
darkhan@20
|
148 init = 0 |
darkhan@20
|
149 for row in range(self.height): |
darkhan@20
|
150 for col in range(init, self.width): |
darkhan@20
|
151 new_field[row].append(self.field[row][col - value]) |
darkhan@20
|
152 self.field = new_field |