2017-11-06 1 views
4

Ich versuche, das Spiel des Lebens in C++ im Moment zu machen, dies ist meine erste C++ Übung überhaupt. Ich habe eine Frage, wir müssen einige Spielmodi machen, wie man "Torus" nennt, wo Zellen, die das Board verlassen, auf der gegenüberliegenden Seite wieder betreten werden sollten.Game of Life Nachbar-Check (einfachere Methode möglich?)

Jetzt überprüfe ich gerade die Nachbarn. Aber ich schreibe es mit der Hölle viele If-Klauseln hart, weil ich einige for-Schleifen versuchte, aber es hat nicht funktioniert.

Aber ist das wirklich die einzige Option? Um jede Möglichkeit (Zellen auf der linken Seite, auf der rechten Seite, Oberseite, Unterseite etc hard

Dies ist ein Fragment des Codes ich habe dafür:

int countNeighboursTorus(int a, int b) { 

int living = 0; 

// when the starting cell is the one on the upper left (start of the board) 
if (a == 0 && b == 0) { 

    // cell below 
    if (board[a - 1][b] != DEAD) { 
     living++; 
    } 
    // cell right below 
    if (board[a + 1][b + 1] != DEAD) { 
     living++; 
    } 
    // cell right 
    if (board[a][b + 1] != DEAD) { 
     living++; 
    } 
    // cell above (other side of the board) 
    if (board[HEIGHT - 1][b] != DEAD) { 
     living++; 
    } 
    // cell above right (other side of the board) 
    if (board[HEIGHT - 1][b + 1] != DEAD) { 
     living++; 
    } 

} 

// first edge case (height = 0, width != 0): 
else if (a == 0 && b != 0) { 
    // cell below 
    if (board[a - 1][b] != DEAD) { 
     living++; 
    } 
    // cell right below 
    if (board[a + 1][b + 1] != DEAD) { 
     living++; 
    } 
    // cell right 
    if (board[a][b + 1] != DEAD) { 
     living++; 
    } 
    // cell left below 
    if (board[a + 1][b - 1] != DEAD) { 
     living++; 
    } 
    // cell left 
    if (board[a][b - 1] != DEAD) { 
     living++; 
    } 
    // cell left above (other side of the board) 
    if (board[HEIGHT - 1][b - 1] != DEAD) { 
     living++; 
    } 
    // cell above (other side of the board) 
    if (board[HEIGHT - 1][b] != DEAD) { 
     living++; 
    } 
    // cell above right (other side of the board) 
    if (board[HEIGHT - 1][b + 1] != DEAD) { 
     living++; 
    } 
} 

return living; 

}

Eine der for-Schleifen, die ich geschrieben habe, aber nicht wirklich funktionierte, war die folgende - die Schleife zählte immer zu viele Zellen.Nach der Schleife hatten alle Zellen IMMER den Status tot, weil das Programm immer mehr als 3 Lebende zählte Zellen, auch wenn nur 2 Zellen von Anfang an lebten Ich hoffe diese Erklärung ist hilfreich, es ist ein bisschen schwer zu erklären Ich machte einen Outprint - "+" - und es Normalerweise zeigte sich etwa 5/6 Plus, auch wenn es nur zweimal angezeigt werden sollte (zwei lebende Zellen).

// for any other "normal" cases inside of the board: 
else if (a != 0 && b != 0 && a < HEIGHT - 1 && b < WIDTH - 1) { 
    for (int c = -1; c < 2; c++) { 
     for (int d = -1; d < 2; d++) { 
      if (!(c == 0 && d == 0)) { 
       if (board[a + c][b + d] != DEAD) { 
        living++; 
       } 
      } 
     } 
    } 
} 

Gibt es irgendeine Möglichkeit, das zu vereinfachen? Zum Beispiel mit Loops, wie ich es versucht habe? Oder ist das so, wie es gemacht werden sollte? Ich sehe gerade kein Licht am Ende des Tunnels. Nur damit ich weiß, ob ich das umsonst mache. Ich habe wirklich ein paar Probleme mit der C++ - Syntax, weil ich Java nur ungefähr ein Jahr bis jetzt gemacht habe, also bin ich ein Anfänger, wenn es um C++ geht. Ich bin dankbar für irgendwelche Tipps!

+0

Sie vor gegoogelt Haben? Es gibt sogar eine StackOverflow-FAQ für Game of Life: [SO: Tagged Questions] (https://stackoverflow.com/questions/tagged/conways-game-of-life). – Scheff

+0

"_Eine der for-Schleifen, die ich geschrieben habe, aber nicht wirklich funktioniert_" Beschreiben Sie genau, was, darüber, hat nicht funktioniert. Eine solche Problembeschreibung ist nutzlos und sagt nichts aus. –

+0

Natürlich googelte ich es mehrmals, aber die Codes, die ich fand, enthielten solche "Modi" nicht. Also weiß ich das nicht wirklich zu tun. Und natürlich werde ich hinzufügen, was nicht funktioniert hat, um die Frage 1sek! – Calimera

Antwort

5

Ja. Verwenden Sie den Modulo-Operator:

Statt

if (board[a + 1][b + 1] != DEAD) { 

Verwendung:

if (board[(a + 1) % HEIGHT][(b + 1) % WIDTH] != DEAD) { 

Es gibt eine leichte Komplexität, wenn Sie Subtraktion tun (% ist nicht wirklich der Modulo-Operation, es ist der Rest Betrieb). Sie wollen nicht, es zu benutzen auf -1 (es wird nur zurückgeben -1), so fügen Sie eine zusätzliche Höhe/Breite:

if (board[(a - 1 + HEIGHT) % HEIGHT][(b - 1 + WIDTH) % WIDTH] != DEAD) { 

Anschließend können Sie den gleichen Code für alle Zellen des Boards verwenden.

+0

DANKE SO VIEL! Genau das habe ich gesucht! Ich wusste wirklich nicht, dass Sie den Modulo-Operator dafür verwenden könnten, Sie hören nie auf zu lernen! – Calimera

+0

@Caleth Aber dann Subtraktion würde übergelaufene Werte, in der Nähe von max int. – Dialecticus

1

Diese Linie versucht, Elemente der Matrix zuzugreifen, die nicht in Matrix Bereich sind:

if (board[a + c][b + d] != DEAD) { 

Bevor diese Zeile ausgeführt wird Sie überprüfen müssen, wenn a + c und b + d in Matrix Bereich sind, und wenn sie nicht sind, was sollte stattdessen getan werden. Für "Torus" -Anforderung, ich denke, "links" und "rechts" außerhalb des Bereichs sollte durch verpackte Werte ersetzt werden, und "oben" und "unten" außerhalb des Bereichs sollten einfach übersprungen werden.

+0

Sie haben völlig Recht, ich war mir dessen gar nicht bewusst, Gott, ich habe diesen Code wirklich zu lange angeguckt. Vielen Dank für Ihre Antwort! – Calimera

+0

Eigentlich habe ich Begriffe wie "Torus" und "Zylinder" gemischt, daher sollte Martins Antwort akzeptiert werden. Wenn die Anforderung in Zukunft "Zylinder" wird, könnten Sie zusätzliche Prüfungen in seinem Code einführen. – Dialecticus

1

Neben Martin Bonner's answer, bereiten die Tabelle der Offsets zu acht Nachbarn:

static const int NoOfNeighbors = 8; 

int dVertNeigh [NoOfNeighbors] = { 
    HEIGHT-1, HEIGHT-1, HEIGHT-1, 
    0,     0, 
    1,  1,  1}; 

int dHorizNeigh [NoOfNeighbors] = { 
    WIDTH-1, 0,  1, 
    WIDTH-1,   1, 
    WIDTH-1, 0,  1}; 

dann können Sie Nachbarzellen mit einer einfachen Schleife zählen:

for (int ngh = 0; ngh < NoOfNeighbors; ngh++) { 
    int neighborV = (a + dVertNeigh[ngh]) % HEIGHT; 
    int neighborH = (b + dHorizNeigh[ngh]) % WIDTH; 

    if (board[neighborV][neighborH] != DEAD) { 
     living++; 
    } 
} 
Verwandte Themen