Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.fbb.msu.ru/hg/cca/raw-annotate/1ff4d543476f/automata.py
Дата изменения: Unknown
Дата индексирования: Fri Feb 11 14:46:50 2011
Кодировка:

darkhan@105: """Copyright 2010 Aydarkhanov Ruslan, Kurochkin Ilya, Rusinov Ivan
darkhan@105:
darkhan@105: This file is part of Foobar.
darkhan@105:
darkhan@105: Foobar is free software: you can redistribute it and/or modify it under
darkhan@105: the terms of the GNU General Public License as published
darkhan@105: by the Free Software Foundation, either version 2 of the License,
darkhan@105: or (at your option) any later version.
darkhan@105:
darkhan@105: Foobar is distributed in the hope that it will be useful,
darkhan@105: but WITHOUT ANY WARRANTY; without even the implied warranty
darkhan@105: of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
darkhan@105: See the GNU General Public License for more details.
darkhan@105:
darkhan@105: You should have received a copy of the GNU General Public License
darkhan@105: along with Foobar. If not, see http://www.gnu.org/licenses/.
darkhan@105: """
darkhan@105:
darkhan@88: from state import *
darkhan@20:
Ilia@1: class Automata(object):
darkhan@80: def __init__(self, width=150, height=70, states=None):
darkhan@11: self.width = width
darkhan@11: self.height = height
darkhan@20: if states == None:
darkhan@81: self.states = [State("Dead", '-', "white", '0', [5]),
darkhan@88: State("Alive", '+', "black", '1', [0, 1] + range(4, 9))]
darkhan@20: else:
darkhan@20: self.states = states
darkhan@11: self.symbols = {}
darkhan@62: self.st_sym = {}
darkhan@11: for num, st in enumerate(self.states):
darkhan@11: self.symbols[st.symbol] = num
darkhan@62: self.st_sym[st.symbol] = st
darkhan@11: self.field = []
darkhan@11: for row in range(height):
darkhan@11: self.field.append([])
darkhan@11: for col in range(width):
darkhan@25: self.field[row].append(self.states[0].symbol)
darkhan@11:
darkhan@17: def next_step(self):
darkhan@42: changed = []
darkhan@62: for row in range(1, self.height - 1):
darkhan@62: for col in range(1, self.width - 1):
darkhan@28: symbol = self.field[row][col]
darkhan@11: num = 0
darkhan@62: for vert in range(row - 1, row + 2):
darkhan@62: for horiz in range(col - 1, col + 2):
darkhan@11: if self.field[vert][horiz] == symbol:
darkhan@11: num += 1
darkhan@62: if self.st_sym[symbol].next_state(num - 1):
darkhan@49: changed.append((row, col))
darkhan@62:
darkhan@62: for row in range(1, self.height - 1):
darkhan@62: symbol1 = self.field[row][0]
darkhan@62: symbol2 = self.field[row][self.width - 1]
darkhan@62: num1 = 0
darkhan@62: num2 = 0
darkhan@62: for vert in range(row - 1, row + 2):
darkhan@62: for horiz in [0, 1, self.width - 1]:
darkhan@62: if self.field[vert][horiz] == symbol1:
darkhan@62: num1 += 1
darkhan@62: for horiz in [self.width - 2, self.width - 1, 0]:
darkhan@62: if self.field[vert][horiz] == symbol2:
darkhan@62: num2 += 1
darkhan@62: if self.st_sym[symbol1].next_state(num1 - 1):
darkhan@62: changed.append((row, 0))
darkhan@62: if self.st_sym[symbol2].next_state(num2 - 1):
darkhan@62: changed.append((row, self.width - 1))
darkhan@62:
darkhan@62: for col in range(1, self.width - 1):
darkhan@62: symbol1 = self.field[0][col]
darkhan@62: symbol2 = self.field[self.height - 1][col]
darkhan@62: num1 = 0
darkhan@62: num2 = 0
darkhan@62: for horiz in range(col - 1, col + 2):
darkhan@62: for vert in [0, 1, self.height - 1]:
darkhan@62: if self.field[vert][horiz] == symbol1:
darkhan@62: num1 += 1
darkhan@62: for vert in [self.height - 2, self.height - 1, 0]:
darkhan@62: if self.field[vert][horiz] == symbol2:
darkhan@62: num2 += 1
darkhan@62: if self.st_sym[symbol1].next_state(num1 - 1):
darkhan@62: changed.append((0, col))
darkhan@62: if self.st_sym[symbol2].next_state(num2 - 1):
darkhan@62: changed.append((self.height - 1, col))
darkhan@62:
darkhan@62: for row, col in [(0, 0), (self.height - 1, self.width - 1),
darkhan@62: (0, self.width - 1), (self.height - 1, 0)]:
darkhan@62: symbol = self.field[row][col]
darkhan@62: num = 0
darkhan@62: for vert_long in range(row + self.height - 1,
darkhan@62: row + self.height + 2):
darkhan@62: for horiz_long in range(col + self.width - 1,
darkhan@62: col + self.width + 2):
darkhan@62: vert = vert_long % self.height
darkhan@62: horiz = horiz_long % self.width
darkhan@62: if self.field[vert][horiz] == symbol:
darkhan@62: num += 1
darkhan@62: if self.st_sym[symbol].next_state(num - 1):
darkhan@62: changed.append((row, col))
darkhan@11:
darkhan@49: for row, col in changed:
darkhan@49: index = (self.symbols[self.field[row][col]] +
darkhan@47: 1) % len(self.states)
darkhan@49: self.field[row][col] = self.states[index].symbol
darkhan@42: return changed
darkhan@11:
darkhan@17: def change_size(self, value, side):
darkhan@17: "0-up, 1-right, 2-down, 3-left"
darkhan@17: new_field = []
darkhan@20:
darkhan@17: if side == 0:
darkhan@17: self.height += value
darkhan@17: for row in range(value):
darkhan@17: new_field.append([])
darkhan@17: for col in range(self.width):
darkhan@83: new_field[row].append(self.states[0].symbol)
darkhan@20: init = value
darkhan@20: if value < 0:
darkhan@20: init = 0
darkhan@20: for row in range(init, self.height):
darkhan@17: new_field.append([])
darkhan@17: for col in range(self.width):
darkhan@17: new_field[row].append(self.field[row - value][col])
darkhan@20:
darkhan@17: if side == 2:
darkhan@17: self.height += value
darkhan@82: term = value
darkhan@82: if value < 0:
darkhan@20: term = 0
darkhan@20: for row in range(self.height - term):
darkhan@17: new_field.append([])
darkhan@17: for col in range(self.width):
darkhan@17: new_field[row].append(self.field[row][col])
darkhan@82: for row in range(self.height - term, self.height):
darkhan@17: new_field.append([])
darkhan@17: for col in range(self.width):
darkhan@83: new_field[row].append(self.states[0].symbol)
darkhan@20:
darkhan@20: if side == 1:
darkhan@20: self.width += value
darkhan@82: term = value
darkhan@82: if value < 0:
darkhan@20: term = 0
darkhan@20: for row in range(self.height):
darkhan@20: new_field.append([])
darkhan@20: for col in range(self.width - term):
darkhan@20: new_field[row].append(self.field[row][col])
darkhan@20: for row in range(self.height):
darkhan@82: for col in range(self.width - term, self.width):
darkhan@83: new_field[row].append(self.states[0].symbol)
darkhan@20:
darkhan@20: if side == 3:
darkhan@20: self.width += value
darkhan@20: for row in range(self.height):
darkhan@20: new_field.append([])
darkhan@20: for col in range(value):
darkhan@83: new_field[row].append(self.states[0].symbol)
darkhan@20: init = value
darkhan@20: if value < 0:
darkhan@20: init = 0
darkhan@20: for row in range(self.height):
darkhan@20: for col in range(init, self.width):
darkhan@20: new_field[row].append(self.field[row][col - value])
darkhan@20: self.field = new_field