Game Of Life/nicht funktionsfähig



  • @DirkB Besser gesagt weiß ich nicht ganz wie ich mit den new_int umgehen soll und was die bewirken.



  • @sandra1 sagte in Game Of Life/nicht funktionsfähig:

    new_int

    was soll das sein?

    Du übergibst deiner Summenfunktion das Array und die Indizes für das Feld, für das die Summe berechnet werden soll.

    Du musst dir noch Gedanken für die Ränder machen.



  • @DirkB
    also ich hätte das jetzt so gemacht

    
    int summe(int l[10][10], int x, int y){
    int summe1;
        for(int ja=-1; ja<11; ja++){
                for(int bi=-1; bi<11; bi++){
                    if(ja<0){
                        l[ja][bi]=0;
                    }
                    if(bi<0){
                        l[ja][bi]=0;
                    }
                }
        }
    
                    summe1=l[x+1][y]+l[x-1][y]+l[x][y+1]+l[x][y-1]+l[x+1][y+1]+l[x-1][y-1]+l[x+1][y-1]+l[x-1][y+1];
                    return summe1;
    
    
    
        return summe1;
    

    und so würde ich die Fkt. aufrufen

    summe1=summe(l, a , ba);
    

    Die Ränder behandel ich ja in der ersten Schleife.



  • @sandra1 Was soll denn diese verschachtelte Schleife machen?

    Elemente mit den Indizes -1 und 10 existieren nicht. darauf darfst du nicht zugreifen.



  • @DirkB
    also rein von der Logik könnte ich das Spielfeld einfach bei den Rändern erweitern(dann mit 0 belegen), dass das Ränderproblem nicht einmal aufkommt und dann nur die gesuchten Feldern kontrollieren.
    Das hab ich da probiert.



  • @sandra1 sagte in Game Of Life/nicht funktionsfähig:

    @DirkB
    also rein von der Logik könnte ich das Spielfeld einfach bei den Rändern erweitern(dann mit 0 belegen), dass das Ränderproblem nicht einmal aufkommt und dann nur die gesuchten Feldern kontrollieren.
    Das hab ich da probiert.

    Dann kannst du an den Rändern (x bzw y ist 0 oder 9) einfach 0 zurück geben dann entsteht an den Rändern erst gar kein Leben.

    Du kannst auch eine "Kugelwelt" bauen. Was rechts raus geht, geht links wieder rein und umgekehrt, ebenso oben und unten.

    Auch dein Konzept mit dem prüfen und dem temp-Array solltest du nochmal überdenken.
    Du prüfst in l, überschreibst dann l wieder. Das ist blöd, weil du in der nächsten Zeile ja die alten Informationen brauchst.

    Also in l prüfen und nach temp schreiben. Am Schluss dann temp nach l kopieren. (für den Anfänger)



  • @DirkB
    Also ich hab jetzt den ganzen Code umgeschrieben aber ich kann mir nicht erklären warum es nicht funktioniert.

    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    void belegen(int l[12][12]);
    void pruefen(int l[12][12], int temp[12][12]);
    int summe(int l[12][12], int x, int y);
    void ausgabe(int temp[12][12]);
    
    int main()
    {
    
      int la[12][12];
      int tempo[12][12];
    
      belegen(la);
    
      for(int jo=0; jo<5; jo++){
        pruefen(la, tempo);
        ausgabe(tempo);
      }
    
    }void belegen(int l[12][12]){
    int nr;
    int x;
    int y;
        for(int a=1; a<11; a++){
           for(int ba=1; ba<11; ba++){
                l[a][ba]=0;
           }
        }
        printf("Wie viele lebende Zellen wollen Sie haben? ");
        cin>>nr;
    
        for(int j=0; j<nr; j++){
            printf("Bitte geben Sie die x Koordinate der %i .ten Zahl ein.\n", j);
            cin>>x;
            printf("Bitte geben Sie die y Koordinate der %i .ten Zahl ein.\n", j);
            cin>>y;
            l[x][y]=1;
        }
    
        for(int a=1; a<11; a++){
            for(int ba=1; ba<11; ba++){
                if(l[a][ba]==0){
                    printf(" ");
                }
                if(l[a][ba]==1){
                    printf("%c ", 219);
                }
            } cout<< "\n";
        }
    
    
    }void pruefen(int l[12][12], int temp[12][12]){
        int summe1=0;
        for(int a=1; a<11; a++){
           for(int ba=1; ba<11; ba++){
                summe1=summe(l, a , ba);
                if(l[a][ba]==0){
                    if(summe1==3){
                        l[a][ba]=temp[a][ba];
                        temp[a][ba]=1;
                    }
                }
                if(l[a][ba]==1){
                    if(summe1<2){
                        l[a][ba]=temp[a][ba];
                        temp[a][ba]=0;
                    }
                    if(summe1==2){
                        l[a][ba]=temp[a][ba];
                        temp[a][ba]=1;
                    }
                    if(summe1==3){
                        l[a][ba]=temp[a][ba];
                        temp[a][ba]=1;
                    }else{
                        l[a][ba]=temp[a][ba];
                        temp[a][ba]=0;
                    }
                }
           }
        }
    }int summe(int l[12][12], int x, int y){
        int summe1;
        for(int i=0; i<12; i++){
            for(int j=0; j<12; j++){
                if(i==0){
                    l[i][j]=0;
                }if(j==0){
                    l[i][j]=0;
                }if(i==12){
                     l[i][j]=0;
                }if(j==12){
                    l[i][j]=0;
                }
            }
        }
        summe1=l[x+1][y]+l[x][y+1]+l[x-1][y-1]+l[x+1][y+1]+l[x-1][y+1]+l[x-1][y]+l[x+1][y-1]+l[x][y-1];
        return summe1;
    }void ausgabe(int temp[12][12]){
    
        for(int a=1; a<11; a++){
            for(int ba=1; ba<11; ba++){
                if(temp[a][ba]==0){
                    printf(" ");
                }
                if(temp[a][ba]==1){
                    printf("%c", 219);
                }
            }cout<< "\n";
        }
    
    }
    


  • @sandra1 hast du mal was vom eva-prinzip gehört? und kommentare, die deine gedankengänge, d.h.: "was soll in den nächsten zeilen passieren?", beschreiben, wären auch gut.



  • @sandra1 sagte in Game Of Life/nicht funktionsfähig:

    Also ich hab jetzt den ganzen Code umgeschrieben

    Das finde ich stark übertrieben.
    Der ist genauso konfus wie vorher auch.

    Vorweg:
    Die Feldgröße muss einstellbar/änderbar sein. Nicht zur Programmlaufzeit, neu compilieren ist ok.
    char als Datentyp für das Array ist ausreichend, es muss ja nur 0 oder 1 rein.
    (ich kann kein C++, aber du machst bis jetzt ja nur C mit cout)

    #define FELDGROESSE  12;
    
    int summe(char l[FELDGROESSE  ][FELDGROESSE], int x, int y){
        int summe1;
    
        if ((x <=0) || (y <=0) || (x >= FELDGROESSE) || (x >= FELDGROESSE)) // der Randbereich ist tot
           return 0;
    
         summe1= l[x+1][y]+l[x][y+1]+l[x-1][y-1]+l[x+1][y+1]+l[x-1][y+1]+l[x-1][y]+l[x+1][y-1]+l[x][y-1];
        return summe1;
    }
    
    void ausgabe(char temp[FELDGROESSE][FELDGROESSE]){
    
        for(int a=0; a<FELDGROESSE  ; a++) {
            for(int ba=0; ba<FELDGROESSE  ; ba++) {
                if(temp[a][ba]==0) {
                    putchar(' ');
                } else {
                    putchar( 219);
                }
            } putchar('\n');
        }  putchar('\n');
    }
    
    void pruefen (char l[FELDGROESSE][FELDGROESSE], char temp[FELDGROESSE][FELDGROESSE]){
        int summe1=0;
        for(int a=0; a<FELDGROESSE; a++) {
           for(int ba=1; ba<FELDGROESSE; ba++) {
                summe1=summe(l, a , ba);
    // je nach summe1 und l[a][ba] musst du den Inhalt   in temp ändern
                temp[a][ba] = ....  // ist etwas mehr als eine Zeile
           }
      }
    
    //jetzt wird der ganze Kram von temp zurück   nach l geschrieben
        for(int a=0; a<FELDGROESSE; a++){
           for(int ba=1; ba<FELDGROESSE; ba++){
             l[a][ba] = tempo[a][ba];
    }
    
    void belegen(....)
    {
    // nur belegen, per Hand oder feste Werte zum testen 
    // keine Ausgabe
    }
    
    int main()
    {
      char la[FELDGROESSE][FELDGROESSE];
      char tempo[FELDGROESSE][FELDGROESSE];
    
      belegen(la);
      ausgabe(la);
    
      for(int jo=0; jo<5; jo++){
        pruefen(la, tempo);
        ausgabe(la);
      }
    
    }
    

    Das ist keine optimale/gute Lösung für C++ oder C.
    Du solltest es aber nachvollziehen können.



  • @DirkB sagte in Game Of Life/nicht funktionsfähig:

    (x >= FELDGROESSE) || (x >= FELDGROESSE))

    Doppelt testen hilft besser? 😉



  • Falls Du Windows benutzt, hast Du hier etwas zum spielen:

    #include <windows.h>
    #include <array>
    
    using namespace std;
    
    // Spielfeld
    const int zeilen = 5;
    const int spalten = 7;
    
    using spielfeldTyp = array<int, zeilen * spalten>;
    
    //Regeln
    const int minAnzFuerNeu = 2;
    const int minAnzFuerErhalt = 2;
    const int maxAnzFuerErhalt = 3;
    
    //Ausgabeoffset
    const int spielfeldOffX = 3;
    const int spielfeldOffY = 15;
    const int nextOffX = 25;
    const int nextOffY = spielfeldOffY;
    
    
    // n paar Konsolefunktionen
    void SetCursorVisible(BOOL v)
    {
        CONSOLE_CURSOR_INFO ci;
    
        GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ci);
    
        ci.bVisible = v;
    
        SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ci);
    }
    
    void SetWindowExt(int x, int y, int yMulti = 1)
    {
        SMALL_RECT sr_window = {0, 0, static_cast<SHORT>(x) - 1, static_cast<SHORT>(y) - 1};
        COORD      extension;
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        
        GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    
        extension.X = max(x, csbi.dwMaximumWindowSize.X);
        extension.Y = max(y, csbi.dwMaximumWindowSize.Y);
    
        SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), extension);
        SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &sr_window);
        
        extension.X = x;
        extension.Y = y * yMulti;
        SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), extension);
    }
    
    
    void ClearScreen(WORD attribute = 7)
    {
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        COORD target = {0, 0};
        DWORD written;
    
        GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
        FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), ' ',
                                                csbi.dwSize.X * csbi.dwSize.Y,
                                                target, &written);
        FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attribute,
                                                csbi.dwSize.X * csbi.dwSize.Y,
                                                target, &written);
    }
    
    
    void DruckSimpleText(int x, int y, char const *text)
    {
        COORD target = {static_cast<SHORT>(x), static_cast<SHORT>(y)};
        DWORD written;
    
        WriteConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), text,
                                                strlen(text),
                                                target, &written);
    }
    
    
    void DruckSimpleChar(int x, int y, char c)
    {
        char text[2] = {c, 0};
       
        DruckSimpleText(x, y, text);
    }
    
    struct taste
    {
       taste(int c, int k) : AsciiChar(c), VirtualKey(k){};
       int AsciiChar;
       int VirtualKey;
    };
    
    taste getInput()
    {
        INPUT_RECORD ir;
       
        DWORD dummy;
        do
        {
            ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &ir, 1, &dummy);
        }while(ir.EventType != KEY_EVENT || !ir.Event.KeyEvent.bKeyDown);
       
        return taste(ir.Event.KeyEvent.uChar.AsciiChar, ir.Event.KeyEvent.wVirtualKeyCode);
    }
    
    
    // Funktionen zum Spiel
    void BerechneNextGeneration(const spielfeldTyp &spielfeld, spielfeldTyp &next)
    {
    	next = spielfeld;
    	
    	for(int z = 0; z < zeilen; ++z)
    	{
    		for(int s = 0; s < spalten; ++s)
    		{
    			int nachbarn = 0;
    			
    			for(int pz = z - 1; pz < z + 2; ++pz)
    			{
    				for(int ps = s - 1; ps < s + 2; ++ps)
    				{
    					if(pz == z && ps == s                       //zu prüfendes Feld ausschließen
    					   || pz < 0 || ps < 0                      //linker oder oberer Rand
    					   || pz > zeilen - 1 || ps > spalten - 1   //recher oder unterer Rand
    					  )
    						continue;
    						
    					if(spielfeld[pz * spalten + ps] == 1)
    						nachbarn++;
    				}
    			}
    			
    			if(spielfeld[z * spalten + s] == 0 && nachbarn >= minAnzFuerNeu)
    			   next[z * spalten + s] = 1;
    			   
    			if(spielfeld[z * spalten + s] == 1 && (nachbarn < minAnzFuerErhalt || nachbarn > maxAnzFuerErhalt))
    			   next[z * spalten + s] = 0;
    		}
    	}
    }
    
    void WarteAufTaste()
    {
       getInput();
    }
    
    void SpielfeldAusgeben(const spielfeldTyp &spielfeld, int xOffset = 0, int yOffset = 0)
    {
    	for(int z = 0; z < zeilen; ++z)
    	{
    		for(int s = 0; s < spalten; ++s)
    		{
    			DruckSimpleChar(2 * s + xOffset, 2 * z + yOffset, spielfeld[spalten * z + s] + '0');
    		}
    	}
    }
    
    int main()
    {
    	
    	// Spielfeld initialisieren
    	spielfeldTyp spielfeld;
    	spielfeldTyp nextGeneration;
    	
    	for(int i = 0; i < spalten * zeilen; ++i)
    	   spielfeld[i] = 0;
    	
    	
    	SetWindowExt(60, 40);
    	
    	//Testwerte ins Spielfeld schreiben
    	spielfeld[2 * spalten + 3] = 1;
    	spielfeld[2 * spalten + 5] = 1;
    	spielfeld[3 * spalten + 2] = 1;
    	spielfeld[4 * spalten + 3] = 1;
    	
    	ClearScreen();
    	SetCursorVisible(false);
    	
    	DruckSimpleText(spielfeldOffX, spielfeldOffY - 3, "Spielfeld");
    	DruckSimpleText(nextOffX, nextOffY - 3, "naechste Gen.");
    	
    	BerechneNextGeneration(spielfeld, nextGeneration);
    	SpielfeldAusgeben(spielfeld, spielfeldOffX, spielfeldOffY);
    	SpielfeldAusgeben(nextGeneration, nextOffX, nextOffY);
    	WarteAufTaste();
    	
    	for(int i = 0; i < 10; ++i)
    	{
    		spielfeld.swap(nextGeneration);
    		BerechneNextGeneration(spielfeld, nextGeneration);
    		SpielfeldAusgeben(spielfeld, spielfeldOffX, spielfeldOffY);	
    		SpielfeldAusgeben(nextGeneration, nextOffX, nextOffY);
    		WarteAufTaste();
    	}
    	
    	SetCursorVisible(true);
    }
    

Anmelden zum Antworten