2017-08-05 3 views
0

Ich versuche, eine Funktion nextGen schreiben, die ein einzelnes Argument (das aktuelle Raster) nimmt und dann berechnet, aber das neue Raster nicht gedruckt. Im Grunde bin ich nicht sicher, wie man das Überprüfungsbit macht, wo es die 9 umgebenden Zellen überprüft. Zuerst dachte ich, ich könnte ein Basisgitter erstellen, das komplett aus Nullen besteht und zwei Zeilen und zwei Spalten größer als das aktuelle Gitter ist, so dass es ein Rand von Nullen wäre, aber ich kann nicht herausfinden, wie man die Anfangsgitterwerte erhält in das Grundraster. Mein aktueller Code ist:Conways Spiel des Lebens: Wie initialisiert man das Gitter?

def initlist(positions,initval): 
    newlist = [] 
    for i in range(0,positions): 
     newlist.append(initval) 
    return newlist 

def init2DTableV3(rows,cols,initval): 
    newrow = initlist(cols,initval) 
    table = initlist(rows,newrow) 
    return table 

def nextGen(current_grid): 
    rows = len(current_grid) 
    cols = len(current_grid[0]) 
    base_value = 0 
    base_grid = init2DTableV3(rows + 2, cols + 2, base_value) 
    import copy 
    init_newgrid = copy.deepcopy(current_grid) 

Könnte mir jemand helfen? Ich bin ein Anfänger bei Python, also wenn jemand erklären könnte, wie man mit einfachen Python-Funktionen macht, wäre das großartig.

+0

Wenn Sie GoL-Gitter doppelt gewickelt ist, dann müssen Sie die Nachbarn über das Gitter überprüfen. – DyZ

Antwort

1

Wenn ich richtig verstehe, haben Sie das Grundraster und Sie sind nicht sicher, wie Sie es mit Nullen an den Rändern auffüllen, richtig?

Manchmal ist es einfacher, zuerst über das Problem in 1D nachzudenken und dann zu sehen, ob es möglich ist, es auf 2D zu erweitern. Lassen Sie sich sagen, dass Ihr 1D Raster wie Dann

1 0 0 1 0 0 0 0 1 0 1 

sehen, wenn Sie Pad das Array mit einer Null an jedem Ende wollten, wäre es stattdessen aussehen

0 1 0 0 1 0 0 0 0 1 0 1 0 

Dies ist sehr einfach unter der Annahme zu tun Sie verwenden nur Standard-Python-Listen. Sie können einfach list.insert() verwenden, um am Anfang einfügen, und .insert() oder .append() am Ende einfügen.

>>> L = [1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1] 
>>> L.insert(0,0) 
>>> L.append(0) 
>>> L 
[0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0] 

Also lassen Sie sich das gleiche mit einer 2D-Liste versuchen, um zu sehen, was passiert:

>>> M = [[1,1],[1,1]] 
>>> M.insert(0,[0,0]) 
>>> M.append([0,0]) 
>>> M 
[[0, 0], [1, 1], [1, 1], [0, 0]] 

Also, das eine Reihe von oben und unten mit Nullen gibt, aber wir haben nicht die linke und rechte Seite. Wir werden uns gleich damit befassen. Als ich die obere und untere Reihe hinzugefügt habe, gab ich ihr explizit die Anzahl der benötigten Nullen (d. H. [0,0]). Aber man kann dies leicht automatisch tun, nur die Länge einer Zeile mit:

>>> M = [[1,1],[1,1]] 
>>> M.insert(0,[0]*len(M[0])) 
>>> M.append([0]*len(M[0])) 
>>> M 
[[0, 0], [1, 1], [1, 1], [0, 0]] 

nun jede der Zeilenvektoren ist nur Länge 2, aber es sollte 4 sein Eine einfache und explizite Möglichkeit, dies zu tun, ist nur eine Schleife durch die Teil-Listen und einfügen und die 0 anhängen:

>>> for r in M: 
...  r.insert(0,0) 
...  r.append(0) 
... 
>>> M 
[[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]] 

Dies wird Ihnen Ihre Liste gepolsterte 2D. jedoch


Im Allgemeinen würde ich mit numpy für diese Aufgaben vorschlagen, wie Sie einfach numpy.pad() auf einem 2D-numpy Array für den Anfang verwenden können, aber kompliziertere Operationen werden auch schneller sein und die Arrays sind leichter zu indizieren, usw.

0

Ein anderer Ansatz wäre, das, was bereits vorhanden ist, zu verwenden, anstatt zusätzliche Elemente hinzuzufügen.

Ich schrieb vor kurzem eine Kopie von Leben in Javascript, aber die Ideen sind die gleichen. Jede Zelle wurde anhand ihrer Koordinaten identifiziert und mit einem Objekt (Python: Wörterbuch) der Koordinaten ihrer Nachbarn initialisiert.

makeCell(x, y) { 
    let div = $('<div></div>'); 
    let id = "x" + x + "y" + y; 

    let neighbors = this.getNeighbors(x, y); 

    let attributes = { 
       "id": id, 
       "data-entity": _entity.id 
     } 

    $("#grid").append(div); 
} 

function getNeighbors(x, y) { 
    let leftX =  x - 1; 
    let rightX = x + 1; 
    let topY =  y - 1; 
    let bottomY = y + 1; 

    // neighbor positions 
    let neighbors = [ 
     "#x" + leftX + "y" + topY, 
     "#x" + x + "y" + topY, 
     "#x" + rightX + "y" + topY, 
     "#x" + leftX + "y" + y, 
     "#x" + rightX + "y" + y, 
     "#x" + leftX + "y" + bottomY, 
     "#x" + x + "y" + bottomY, 
     "#x" + rightX + "y" + bottomY, 
    ]; 
    return neighbors; 
} 

Am Ende der Runde wurden alle lebenden Zellen in einer Liste gespeichert. Jede lebende Zelle und jeder ihrer Nachbarn wurde überprüft, um ihre jeweilige lebende Nachbarzelle zu zählen.

this.cellCountNeighbors = function() { 
    let count = 0; 
    let neighbors = this.neighbors; 
    let n = this.entity; 
    let u = this; 

    neighbors.forEach(function(neighbor) { 
     let div = $(neighbor); 
     if ($(div).hasClass("alive")) { 
      count++; 
     } else if (!check_cells.includes(neighbor)) { 
      check_cells.push(neighbor); 
     } 
    }); 

    return count; 
} 

und die Prüfbedingung für das Leben:

this.setNextLife = function(_count) { 
    if (this.alive) { 

     if (_count == 2 || _count == 3) { 
      return this.age++; 
     } else { 
      changes.push(this); 
      return; 
     } 

    } else { 
     changes.push(this); 
    } 
} 

Wo changes eine Liste von Zellen zu bool lebendig/tot umgeschaltet werden.

Verwandte Themen