William Fernandes
William Fernandes

Reputation: 239

Cellular Automata algorithm doesn't seem to work

I'm currently working on an electronics simulation software (something really basic) using Python and libTCOD (just to "render" the board). So, I've got a 78x47 2D list which stores the board information (cell type, id, state, coords...) and a simple algorithm to simulate wires (wireworld). Everything seems to be going fine, except for one thing: The "electrons" only move towards the left side of the wires. So I thought it may be something related to the way it runs the algorithm.

WireWorld wires have three possible states: Conductor, tail or head.

Here's how the simulation should go (H for head, t for tail, - for wire):

But this is what currently happens:

See? The electron head only moves towards the left side of the wires.

That's my current algorithm code:

def run(self):
    for DX, DY in ((-1,-1), (-1,+0), (-1,+1), (+0,-1), (+0,+1), (+1,-1), (+1,+0), (+1,+1)):
        if BOARD[self.Y+DY][self.X+DX].STATE == 2 and self.STATE == 0:
            self.STATE = 2
            return True

        if self.STATE == 2:
            self.STATE = 1
        elif self.STATE == 1:
            self.STATE = 0

And that's how I run the simulation steps:

for y in range(BOARD_HEIGHT):
    for x in range(BOARD_WIDTH):
        BOARD[y][x].run()

Do I need to simulate each cell in an independent thread?

Upvotes: 2

Views: 233

Answers (1)

Jasper
Jasper

Reputation: 3947

There's no need for multithreading, you just have to make sure that more than one '- -> H'-transitions are possible in each simulation step.

I've coded a minimal example starting from your code (but with slightly different class layout):

class Simul(object):

    def __init__(self, width, height):
        board_1 = [[None for _ in range(width)] for _ in range(height)]
        board_2 = [[None for _ in range(width)] for _ in range(height)]
        self.boards = [board_1, board_2]
        self.current = 0
        self.pretty = {None: ' ', 0: '-', 1: 't', 2: 'H'}
        self.w = width
        self.h = height

    def print_board(self):
        for row in self.boards[self.current]:
            for cell in row:
                print(self.pretty[cell], end='')
            print()

    def run(self):
        BOARD = self.boards[self.current]
        other_board = self.boards[- self.current + 1]
        for row in range(self.h):
            for col in range(self.w):
                cur_cell = BOARD[row][col]
                set_h = False
                for DX, DY in ((-1,-1), (-1,+0), (-1,+1), (+0,-1), (+0,+1),  (+1,-1), (+1,+0), (+1,+1)):
                    try:
                        if BOARD[row+DY][col+DX] == 2 and cur_cell == 0:
                            other_board[row][col] = 2
                            set_h = True
                            break
                    except IndexError:
                        pass

                if set_h:
                    continue

                if cur_cell == 2:
                    other_board[row][col] = 1
                elif cur_cell == 1:
                    other_board[row][col] = 0
                elif cur_cell == 0:
                    other_board[row][col] = 0
        self.current = - self.current + 1




if __name__ == '__main__':
    simul = Simul(10, 5)
    for col in range(10):
        simul.boards[0][3][col] = 0
    for row in range(3):
        simul.boards[0][row][4] = 0
    simul.boards[0][3][4] = 2
    simul.print_board()
    simul.run()
    simul.print_board()

Output:

    -     
    -     
    -     
----H-----

    -     
    -     
    H     
---HtH----

Upvotes: 1

Related Questions