3

I have some project which I decide to do in Python. In brief: I have list of lists. Each of them also have lists, sometimes one-element, sometimes more. It looks like this:

rules=[
[[1],[2],[3,4,5],[4],[5],[7]]
[[1],[8],[3,7,8],[3],[45],[12]]
[[31],[12],[43,24,57],[47],[2],[43]]
]

The point is to compare values from numpy array to values from this rules (elements of rules table). We are comparing some [x][y] point to first element (e.g. 1 in first element), then, if it is true, value [x-1][j] from array with second from list and so on. Five first comparisons must be true to change value of [x][y] point. I've wrote sth like this (main function is SimulateLoop, order are switched because simulate2 function was written after second one):

def simulate2(self, i, j, w, rule):
        data = Data(rule)
        if w.world[i][j] in data.c:
            if w.world[i-1][j] in data.n:
                if w.world[i][j+1] in data.e:
                    if w.world[i+1][j] in data.s:
                        if w.world[i][j-1] in data.w:
                            w.world[i][j] = data.cc[0]
                        else: return
                    else: return
                else: return
            else: return
        else: return




def SimulateLoop(self,w):
    for z in range(w.steps):
            for i in range(2,w.x-1):
                for j in range(2,w.y-1):
                    for rule in w.rules:
                        self.simulate2(i,j,w,rule)

Data class:

class Data:
    def __init__(self, rule):
        self.c = rule[0]
        self.n = rule[1]
        self.e = rule[2]
        self.s = rule[3]
        self.w = rule[4]
        self.cc = rule[5]

NumPy array is a object from World class. Rules is list as described above, parsed by function obtained from another program (GPL License).

To be honest it seems to work fine, but it does not. I was trying other possibilities, without luck. It is working, interpreter doesn't return any errors, but somehow values in array changing wrong. Rules are good because it was provided by program from which I've obtained parser for it (GPL license).

Maybe it will be helpful - it is Perrier's Loop, modified Langton's loop (artificial life).

Will be very thankful for any help! )

Mateusz Korycinski
  • 1,037
  • 3
  • 10
  • 24
  • It might help if you were to provide data from an example `World` where this fails. The only thing I see here that looks slightly out of place is `i` and `j` starting at 2 instead of 1. – Andrew Clark Mar 31 '11 at 22:40
  • Also, all of your `else: return` lines are unnecessary, just put a single `return` statement outside of the outermost `if` and it will do the same thing. – Andrew Clark Mar 31 '11 at 22:42
  • Unfortunately array is to big (50x50 at least). It is filled by some numbers from 0 to 64 in proper conformation to create loop shape. Algorithm is for testing 4 neighbours of 'pixel' in array. Basing on it, state is changed by 6th value from rule. But of course firstly 5 values must be equal (state we want to change and 4 neighbours) to values from rule (1-5). It starts from 2 instead of 1 or 0 because I don't want to change first two columns and 2 rows. Loop begins at 3rd row and 3rd col. Thx for advice with return, I will do that. – Mateusz Korycinski Mar 31 '11 at 23:39
  • Naive/quick guess... Could it be that you crossed the x and y axis and/or more generally do not map properly the rules with the board geometry. As written, Simulate2() has its i and j in the north-south direction and west-east direction, respectively which seems a bit odd, oft' the first coordinate is for the x axis (west-to-east) and the 2nd coordinate is for south-to-north axis. – mjv Jul 19 '11 at 03:31

1 Answers1

0

I am not familiar with Perrier's Loop, but if you code something like famous "game life" you would have done simple mistake: store the next generation in the same array thus corrupting it.

Normally you store the next generation in temporary array and do copy/swap after the sweep, like in this sketch:

def do_step_in_game_life(world):
    next_gen = zeros(world.shape)    # <<< Tmp array here
    Nx, Ny = world.shape
    for i in range(1, Nx-1):
        for j in range(1, Ny-1):
            neighbours = sum(world[i-1:i+2, j-1:j+2]) - world[i,j]
            if neighbours < 3:
                next_gen[i,j] = 0
            elif ...
    world[:,:] = next_gen[:,:]       # <<< Saving computed next generation
dmitry_romanov
  • 5,146
  • 1
  • 33
  • 36
  • Thanks for response! I've managed to do that (it was some time ago already). I've started to clear whole array at the beginning of each step and it works fine. Another thing is speed, but this is for some time in future. – Mateusz Korycinski Aug 18 '11 at 08:57