Seite 1 von 1

Game Of Life 3D

Verfasst: Montag 9. April 2007, 12:52
von mawe
Sorry dass ich einen neuen Thread starte, aber ich kann hier mysteriöserweise nicht antworten :?
Wie auch immer, hier meine zusammengeschusterte 3d Version (wirklich 3d :)):

Code: Alles auswählen

from visual import *
import time

class GOL:
    def __init__(self, width, height, depth, living_cells):
        self.width = width
        self.height = height
        self.depth = depth
        self.living_cells = living_cells

    def is_alive( self, pos ):
        return pos in self.living_cells

    def is_empty( self, pos ):
        return not self.is_alive(pos)

    def neighbours( self, (x, y, z) ):
        return [ self.wrap( (a, b, c) ) for (a,b,c) in
                    [
                        (x-1, y-1, z-1), (x, y-1, z-1), (x+1, y-1, z-1), 
                        (x-1, y,   z-1), (x, y,   z-1), (x+1, y,   z-1), 
                        (x-1, y+1, z-1), (x, y+1, z-1), (x+1, y+1, z-1),
                        (x-1, y-1, z  ), (x, y-1, z  ), (x+1, y-1, z  ), 
                        (x-1, y,   z  ),                (x+1, y,   z  ), 
                        (x-1, y+1, z  ), (x, y+1, z  ), (x+1, y+1, z  ),
                        (x-1, y-1, z+1), (x, y-1, z+1), (x+1, y-1, z+1), 
                        (x-1, y,   z+1), (x, y,   z+1), (x+1, y,   z+1), 
                        (x-1, y+1, z+1), (x, y+1, z+1), (x+1, y+1, z+1),
                    ] 
                ]

    def wrap( self, (x, y, z) ):
        return ( ( (x-1) % self.width  ) + 1, 
                 ( (y-1) % self.height ) + 1,
                 ( (z-1) % self.depth  ) + 1 )

    def living_neighbours( self, (x, y, z) ):
        return len([ pos for pos in self.neighbours((x,y,z)) 
                                         if self.is_alive(pos) ] )

    def survivors( self ):
        return [ pos for pos in self.living_cells if 
                                    self.living_neighbours( pos ) in [4,5,6] ]

    def births( self ):
        all_living_neighbours = []
        for pos in self.living_cells:
            for n in self.neighbours( pos ):
                if self.is_empty(n) and self.living_neighbours(n) == 4:
                    all_living_neighbours.append(n)
        return set(all_living_neighbours)
            
    def next_gen( self ):
        s = self.survivors()
        b = self.births()
        self.living_cells = []
        self.living_cells.extend(s)
        self.living_cells.extend(b)


if __name__ == '__main__':
    def show(b):
        for pos in b:
            box(pos=pos)
         
    def run(g):
        i = 0
        while 1:
            i += 1
            print "generation: %s   living: %s" % (i, len(g.living_cells))
            for o in scene.objects:
                if o.__class__ != curve: 
                    o.visible=0
                    del(o)
            show(g.living_cells)
            time.sleep(0.1)
            g.next_gen()
        
    def draw_box(l, rad=1):
        for p in [ [ (0,0,0), (l,0,0), (l,l,0), (0,l,0), (0,0,0) ],
                   [ (0,0,l), (l,0,l), (l,l,l), (0,l,l), (0,0,l) ],
                   [ (0,0,0), (0,0,l) ],
                   [ (l,0,0), (l,0,l) ],
                   [ (l,l,0), (l,l,l) ],
                   [ (0,l,0), (0,l,l) ] ]:
            curve(pos=p, radius=rad)
        
    scene.autocenter = 1 
    scene.autozoom = 1
    draw_box(100, rad=0.5)
    g = GOL(100, 100, 100, [(50,48,50),(48,49,50),(50,49,50),(49,50,50),(50,50,50)])
    run(g)
Rechte Maustaste -> Rotieren, mittlere -> Zoomen.

Die Startkonfiguration ist ein 2d Glider. Wird nach kurzer Zeit seeeeehr langsam.

Verfasst: Montag 9. April 2007, 16:43
von BlackJack
Du kannst in dem anderen Thread nichts mehr schreiben, weil dieses sch…öne Board bei viel Code mit Syntaxhighlighting 'nen Hänger hat. Längere Quelltexte solltest Du besser bei einem Paste-Service ablegen und hier nur einen Link veröffentlichen.

Bei `draw_box()` dachte ich übrigens erst das Syntaxhighlighting funktioniert nicht richtig weil die ganzen Einsen ja blau sein müssten. Einbuchstabige Namen sind ja sowieso schon nicht so toll, aber ein kleines 'L' ist genauso ungünstig wie ein grosses 'o', weil es Zeichensätze gibt bei denen man l und 1 bzw. O und 0 nicht auseinanderhalten kann.

Verfasst: Montag 9. April 2007, 19:32
von mawe
Du hast natürlich recht. Diese kleine 'l' war mal ein 'boxlength'. Das war mir zu lang, ein sinnvolles Kürzel ist mir nicht eingefallen, also ... l :) Aber ansonsten war ich brav, oder? Oh, da seh ich gerade o, i, s, b, ... :oops:

Verfasst: Montag 9. April 2007, 19:57
von apollo13
Das Modul visual ist genial :)
Und stimmt es wird schnell langsam und das bei einem Intel Core 2 Duo @ 2.00Ghz

Verfasst: Dienstag 10. April 2007, 14:17
von Panke
Was hast du denn für ein Regelwerk? Wenn ein Gleiter in 50 Generationen 600 nachkommen hat, sollte man vielleicht von 23/3 abweichen.

Verfasst: Dienstag 10. April 2007, 14:56
von mawe
50 Generationen? So weit bin ich nie gekommen :)
Überleben: 4-6 Nachbarn
Geburt: 4 Nachbarn
Kannst es gerne ändern. Zeilen 43 und 49.

Verfasst: Dienstag 10. April 2007, 19:43
von Craven
Hi!

Ich hab grad mal das visual-Modul runtergeladen und installiert. Mawe, deine Version ist verdammt cool :D . Auch wenns'n bisschen langsam ist. Aber: Wenns mal wieder länger dauert ... :wink:
Ich lass es hier auf nem Intel Pentium 4 3 Ghz laufen.

MfG,
Craven

Verfasst: Donnerstag 12. April 2007, 18:02
von rayo
Hi

Ich hab mal ein wenig dran rumgebastelt und hauptsächlich 2 Änderungen gemacht:
- living_cells ist ein dict (in ist schneller)
- neighbours werden gecached (schneller)

Braucht zwar mehr Speicher, lief aber bei mir einiges schneller

http://paste.pocoo.org/show/1390/

Gruss

Verfasst: Freitag 13. April 2007, 12:22
von lost_mind
hm also ich hab keinen schimmer wo ich das visual herbekomme ? hat wern nen link ? *hundeblick*

Verfasst: Freitag 13. April 2007, 12:48
von mawe
@lost_mind: VPython

@rayo: Cool :)

Verfasst: Freitag 13. April 2007, 18:26
von rayo
Hi

Das sind mir doch glatt ein paar Tabs reingerutscht (das kommt davon wenn man mit einem nicht konfigurierten Editor verwendet)

Habs rausgenommen und is_alive noch gelöscht und den Code direkt in die anderen Funktionen geschrieben (schneller da 500k Calls bei Generation 20 schon ziemlich viel Overhead produziert)

http://paste.pocoo.org/show/1394/

Sollte nochmals ein wenig schneller sein.

Gruss