Game of life Problem

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
Blank44
User
Beiträge: 5
Registriert: Samstag 5. Januar 2019, 19:04

Hallo,
ich habe gerade angefangen mit Python zu programmieren, ist auch meine erste Sprache.
Jetzt bin ich dabei das Game of Life zu programmieren habe aber das Problem nicht zu wissen wie man die Generationen wiederholt also das er das Spiel immer wieder ausführt.Ich verwende kein Numpy, da ich das ohne machen muss.

Code: Alles auswählen

from random import *
import os
import time

def clear():
    print("\n" * 10)
    
def Ausgabe(feld,x,y):
    clear()
    os.system('CLS')
    for i in range (y):
        zeile=""
        for j in range (x) :
            zeile=zeile+str(feld[i][j])
        print(zeile)
    time.sleep(1)

def feldCopy(feld1, feld2, x, y):
    clear()
    for i in range (y):
        for j in range (x) :
            feld2[i][j]=feld1[i][j]


def Neumann(feld,x,y):
    counter=0

    if feld[x+1][y] == 1:
        counter +=1
    if feld[x-1][y] == 1:
        counter +=1
    if feld[x][y+1] == 1:
        counter +=1
    if feld[x][y-1] == 1:
        counter +=1
    if feld[x+1][y] == 0:
        counter +=0
    if feld[x-1][y] == 0:
        counter +=0
    if feld[x][y+1] == 0:
        counter +=0
    if feld[x][y-1] == 0:
        counter +=0
    if counter <2:
        return  0
    if counter >3:
        return 0
    if counter == 2:
        return  1
    if counter == 3:
        return 1
    


 

def nextGen(feld, x, y):
    for y in range(1,y-1):
        for x in range(1,x-1):
            if feld[x][y] == 1:
                if Neumann(feld,x,y) == 0:
                    return 0
            if feld[x][y] == 1:
                if Neumann(feld,x,y) == 1:
                    return 1
            if feld[x][y] == 0:
                if Neumann(feld,x,y) == 1:
                    return 1




   

from random import choice as c
l = list(set(range(-1,1)) ^ set((-1,1)))
x = 5
y= 5
Generationen = 5

feld1 = [[c(l) for j in range(x)] for i in range(y)] 
feld2 = [[c(l) for j in range(x)] for i in range(y)]


Ausgabe(feld1,x,y)
nextGen(feld2,x,y)
feldCopy(feld1,feld2,x,y)
Zuletzt geändert von Blank44 am Samstag 5. Januar 2019, 19:14, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was du aber bitte benutzen musst, sind die code-tags hier im Forum. Das ist der </>-Knopf im vollstaendigen Editor. Sonst ist dein Code unlesbar, und wir koennen dir schwerer helfen.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Sternchenimporte vermeiden, da man nicht kontrollieren kann, was da alles in den eigenen Namensraum geladen wird. Es wird auch nicht aus random benutzt.
Erst `clear` und dann noch `os.system('CLS')` aufzurufen ist irgendwie doppelt. Statt über Indizes iteriert man über das Feld direkt. Dann braucht `Ausgabe` auch nicht die Dimensionen, denn die sind im Feld schon enthalten.
Warum hat `feldCopy` auch ein `clear`? Kopieren geht mit List-Operationen auch einfacher.
In `Neumann`: die if-Blöcke mit `counter += 0` sind ziemlich nichtsmachend.
choice als c abzukürzen ist schlecht, wie generell einbuchstabige Variablennamen schlecht sind. Importe gehören an den Anfang der Datei.
Und zum Schluß fehlt dann halt eine Schleife.

Zum Algorithmus: ein `feld2` brauchst Du, um eine neue Generation anzulegen, was Du aber im Moment gar nicht tust, sondern Dein `nextGen` wird beim ersten `return` verlassen.
Blank44
User
Beiträge: 5
Registriert: Samstag 5. Januar 2019, 19:04

Wie muss ich die schleife machen?
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Ich habe mal den Code etwas aufgeräumt,
ob dein neumann() korrekt ist, habe ich jetzt aber nicht überprüft.

Code: Alles auswählen

import random
    
def ausgabe(feld):
    for zeile in feld:
        for ziffer in zeile:
            print(ziffer, end='')
        print()
    print()

def feldcopy(feld):
    return [[feld[y][x] for x in range(len(feld[0]))] for y in range(len(feld))]

def neumann(feld, xcenter, ycenter):
    counter = 0
    for x in range(-1, 2):
        for y in range(-1, 2):
            try:
                counter += feld[ycenter + y][xcenter + x]
            except IndexError:
                counter += 0
    if counter < 2:
        return 0
    if counter == 2:
        return 1
    if counter == 3:
        return 1
    if counter > 3:
        return 0

def next_generation(feld):
    return [[neumann(feld, y, x) for x in range(len(feld[0]))] for y in range(len(feld))]


width = 15
height = 15
generationen = 15

feld = [[random.choice([0, 1]) for x in range(width)] for y in range(height)] 

for loop in range(generationen):
    ausgabe(feld)
    feld = feldcopy(next_generation(feld))
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@ThomasL: warum wrapped das Feld von der linken zur rechten Seite, aber umgekehrt nicht? Das `feldcopy` ist unnötig.
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Sirius3 hat geschrieben: Samstag 5. Januar 2019, 20:07 @ThomasL: warum wrapped das Feld von der linken zur rechten Seite, aber umgekehrt nicht? Das `feldcopy` ist unnötig.
eigentlich sollte es gar nicht wrappen, ich vermute mal das macht ein array[-1] öhmm.

@Blank44
diese neumann() hier funktioniert, obiger Fehler ist jedoch noch nicht berücksichtigt

Code: Alles auswählen

def neumann(feld, ycenter, xcenter):
    counter = 0
    for y in range(-1, 2):
        for x in range(-1, 2):
            try:
                counter += feld[ycenter + y][xcenter + x]
            except IndexError:
                counter += 0
    counter -= feld[ycenter][xcenter]
    if feld[ycenter][xcenter] == 0 and counter == 3:
        return 1 # Eine tote Zelle mit genau drei lebenden Nachbarn wird in der Folgegeneration neu geboren.
    if feld[ycenter][xcenter] == 1 and counter < 2:
        return 0 # Lebende Zellen mit weniger als zwei lebenden Nachbarn sterben in der Folgegeneration an Einsamkeit
    if feld[ycenter][xcenter] == 1 and counter == 2:
        return 1 # Eine lebende Zelle mit zwei oder drei lebenden Nachbarn bleibt in der Folgegeneration am Leben.
    if feld[ycenter][xcenter] == 1 and counter == 3:
        return 1 # Eine lebende Zelle mit zwei oder drei lebenden Nachbarn bleibt in der Folgegeneration am Leben.
    if feld[ycenter][xcenter] == 1 and counter > 3:
        return 0 # Lebende Zellen mit mehr als drei lebenden Nachbarn sterben in der Folgegeneration an Überbevölkerung.
    return feld[ycenter][xcenter]
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Sirius3 hat geschrieben: Samstag 5. Januar 2019, 20:07 Das `feldcopy` ist unnötig.
Stimmt, es wird ja schon in der next_generation() ein neues Feld generiert.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Antworten