Denkfehler bei 2D Liste

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
misterjosu
User
Beiträge: 44
Registriert: Samstag 29. Dezember 2012, 21:40

Hey,

Ich habe mich vor längerem schon mal mit dem Game of Life beschäftigt, allerdings wurde mir geraten OOP zu vertiefen, was ich versucht hab. Nun hatte ich aber vorhin zeit und beschloss mich nochmals darin zu versuchen. allerdings bekomme ich immer die falschen Ergebnisse z.B. dass die Zelle 8 lebendige nachbarn hat obwohl sie am rand ist und alles was nicht inder liste unthalten ist gillt als tot.
ich selbst verstehe nicht was falsch ist, ichwäre euch sehr dankbar wenn ihr meinen fehlen finden würdet.

Code: Alles auswählen

from tkinter import *

class Main(object):

        world_len = 3

        world = []
        new_world = []

        # generate empty world
        for x in range(0, world_len):
                world.append([])
                for y in range(0, world_len):
                        world[x].append("1")

        # generate empty new world(new generation)
        for x in range(0, world_len):
                new_world.append([])
                for y in range(0, world_len):
                        new_world[x].append("0")
                        
        print(world)

        def __init__(self):
                pass

        def set_life(self, x, y):
                self.world[x][y] = 1

        def calc_new_gen(self):

            # each Cell
            for x in range(0, self.world_len):
                for y in range(0, self.world_len):
                    print("---- Cell", x, y, "---")

                    neigh = 0
                    
                    for new_x in[x-1, x, x+1]:
                        for new_y in[y-1, y, y-1]:
                            try:
                                if x == new_x and y == new_y:
                                    print("cell center detected")
                                    break
                                elif self.world[new_x][new_y] == "1":
                                    neigh += 1
                                    self.new_world[x][y] = "1"
                                    print("Neigbour detcted @",new_x, new_y)
                            except IndexError:
                                print("Rim detected @", new_x, new_y)
                    print("NEIGH >>", neigh)
M = Main()

M.calc_new_gen()
mine
User
Beiträge: 3
Registriert: Mittwoch 19. Juni 2013, 22:08

Hi,
ich denke, nicht deine 2d-Liste war Dein Problem, viel mehr hast Du "1" mit 1 verglichen, also str und int, was schief lief. Ich hab das mal korrigiert und bekomme dann auch eine bessere Anzahl an Nachbarn. Außerdem hab ich die Erstellung der Welt in den Konstruktor gepackt (war mal ein Mindfuck von mir, läuft aber :D ) und eine Methode zum Feld ansehen hinzugefügt.

Code: Alles auswählen

from tkinter import *

class Main:
        def __init__(self, world_len):
            self.world = [ [[1 for i in range(0, world_len)]] * world_len ][0]
            self.new_world = [ [[0 for i in range(0, world_len)]] * world_len ][0]
            
            self.world_len = world_len
            
            print("World with %d fields generated"%world_len**2)
            self.print_field()
            print("\n")
                
        def print_field(self, padding=3):
            for x in range(0, self.world_len):
                s = ""
                for y in range(0, self.world_len):
                    s += str(self.world[x][y]).center(padding) + "|"
                print(s[:-1])
                if x < self.world_len - 1: 
                    print("-"*(self.world_len*padding + 2))
        
        def set_life(self, x, y):
                self.world[x][y] = 1

        def calc_new_gen(self):
            for x in range(0, self.world_len):
                for y in range(0, self.world_len):
                    print("\n---- Cell", x, y, "---")
                    neigh = 0
                    
                    for new_x in[x-1, x+1]:
                        for new_y in[y-1, y-1]:
                            try:
                                if x == new_x and y == new_y:
                                    print("cell center detected")
                                    break
                                elif self.world[new_x][new_y] == 1:
                                    neigh += 1
                                    self.new_world[x][y] = 1
                                    print("Neigbour detcted @",new_x, new_y)
                            except IndexError:
                                print("Rim detected @", new_x, new_y)
                            
                    print("NEIGH >>", neigh)
            self.world = self.new_world
M = Main(3)

M.calc_new_gen()
misterjosu
User
Beiträge: 44
Registriert: Samstag 29. Dezember 2012, 21:40

Danke !
Sirius3
User
Beiträge: 18230
Registriert: Sonntag 21. Oktober 2012, 17:20

@mine: Dein Erzeugen der Welt ist nicht nur seltsam sondern auch falsch. Du erzeugst eine Liste mit immer dem selben List-Element.
- für print_field solltest Du kein »range« brauchen und deutlich mehr gebrauch von »join« machen.
- calc_new_gen hat mehrere Fehler:
* für x=0 kann new_x -1 werden, Du läufst also wieder von rechts in Deine Welt hinein.
* Du durchläufst nur die Ecknachbarn und nicht die oben, unten, links und rechts
* self.world = self.new_world sorgt endgültig dafür, dass es nur noch eine Listen-Objekt gibt.
misterjosu
User
Beiträge: 44
Registriert: Samstag 29. Dezember 2012, 21:40

Hab das genze mal kopiert und probiert obs klappt und ich hab festgestellt, dass es ungefähr gleich viele fehler enthält wie mein code. trotzdem danke.

Wenn ich jetzt die strings in der liste alle zu integrern mache und auch nach integrern frage gehts oder ?

ich finde den fehler nicht.ich hab auch schon auf nem blatt papier den algorythmus nachgerechnet(war mehr zeichnen).
Sirius3
User
Beiträge: 18230
Registriert: Sonntag 21. Oktober 2012, 17:20

Negative List-Indizierung:

Code: Alles auswählen

>>> world = [[0, 0, 0], [0, 0, 0], [0, 0, 1]]
>>> x = 0
>>> y = 0
>>> world[y-1][x-1]
1
misterjosu
User
Beiträge: 44
Registriert: Samstag 29. Dezember 2012, 21:40

Danke wusste gar net dass das geht!
ich habs mal auch noch anders gelöst:

Code: Alles auswählen

from tkinter import *

class Main(object):

        world_len = 2

        world = []
        new_world = []

        # generate empty world
        for x in range(0, world_len):
            world.append([])
            for y in range(0, world_len):
                world[x].append(int(1))

        # generate empty new world(new generation)
        for x in range(0, world_len):
            new_world.append([])
            for y in range(0, world_len):
                new_world[x].append(int(0))
                        
        print(world)
        print(new_world)

        def __init__(self):
            pass

        def set_life(self, x, y):
            self.world[x][y] = 1

        def print_w(self):
            print(self.world)

        def print_nw(self):
            print(self.new_world)

        def calc_new_gen(self):

            # positions of all cells in world
            for x in range(0, self.world_len):
                for y in range(0, self.world_len):
                    print("---- Cell", x, y, "---")

                    neigh = 0
                    # positions around a cell to check
                    for new_x in[x-1, x, x+1]:
                        for new_y in[y-1, y, y+1]:
                            print("scan:",new_x, new_y)
                            
                            # check if cell is in world
                            if not new_x < 0 and not new_x > self.world_len - 1:# vllf
                                if not new_y < 0 and not new_y > self.world_len - 1:# vllf
                                    
                                    if self.world[new_x][new_y] == 1:
                                       neigh += 1
                                       print("Neigbour detcted @",new_x, new_y)
                    # subtract if cell is negative
                    if self.world[x][y] == 0:
                        neigh -= 1
                               

                    # check if next gen of cell lives or is dead
                    if neigh == 3:
                        self.new_world = 1
                    elif neigh > 3:
                        self.new_world = 0
                    elif neigh < 3:
                        self.new_world = 0

            print(self.new_world)





                    

                                

M = Main()

M.calc_new_gen()
Antworten