Aktuelle Array Position



  • Hi Leute! Danke für eure Antworten. Da sind für mich echt ein paar gute Lösungsansätze dabei. Ich versuche jetzt erstmal das alles aufzunehmen und umzusetzen und melde mich dann noch einmal mit der (hoffentlich) Lösung 🙂



  • Soo! Geschafft! Vielen lieben Dank an alle die geholfen haben!

    Belli seine Antwort hat sehr geholfen. DocShoe´s Antwort funktioniert auch super, allerdings muss ich das Programm auch vorstellen und da sollte ich dann mit meinem eigenen kommen, sonst gibts bestimmt bei Fragen Probleme.

    Hier mal meine Schleife mit der das ganze nun läuft

    for(i=0; i<20; i++)
            {
                // Schleife fuer Spalten, X-Achse
                for(k=0; k<30; k++) {
    
    		if(Wald[i][k]=='+')Wald[i][k]='-';
    
                if(Wald[i][k]=='-'&&Wald[i+1][k]=='X'||Wald[i][k]=='-'&&Wald[i-1][k]=='X'||Wald[i][k]=='-'&&Wald[i][k+1]=='X'||Wald[i][k]=='-'&&Wald[i][k-1]=='X'){
    
                    if(Wald[i+1][k]=='X')Wald2[i+1][k]='+';
                    if(Wald[i-1][k]=='X')Wald2[i-1][k]='+';
                    if(Wald[i][k+1]=='X')Wald2[i][k+1]='+';
                    if(Wald[i][k-1]=='X')Wald2[i][k-1]='+';
                }
                }
    
            }
    
            for(i=0;i<20;i++)
            {
                for(k=0;k<30;k++)
                {
                    if(Wald2[i][k]=='+')Wald[i][k]='+';
                    if(Wald2[i][k]=='+')Wald2[i][k]='-';
                }
            }
    
            for(i=0;i<20;i++){
                for(k=0;k<30;k++){
               		cout<<Wald[i][k]<<" ";
    
                }
          	cout<<endl;
            }
    


  • Du greifst immer noch auf Speicher außerhalb der Arraygrenzen zu.



  • Oh... Das Problem mit [0-1] richtig?

    Ich Sehe gerade, dass wenn ich nur den ersten Baum im brand setze, der Wald auch von rechts nach Links abbrennt.

    https://imgur.com/4XaH68Z

    Hab ich jetzt mal so gelöst:

    if(Wald[i][0]){}
                    else{
                    if(Wald[i][k-1]=='X')Wald2[i][k-1]='+';
                    }
    

    Funktioniert aber auch nicht richtig 🙄

    Edit:

    Okay jetzt aber. Ich hab eine Schleife extra für (k=0;k<1;k++) und den Rest in eine Schleife (k=1;k<30;k++)

    Ihr seid die besten 🙂



  • b4mbus schrieb:

    Mit dem Thema Debugger werd ich mich mal auseinander setzen. Ich hab keine Ahnung noch wie das geht.

    sowas macht man eigentlich gleich nach "hallo welt!". vereinfacht gesagt klickst du auf den bereich neben der zeilennummer, damit da ein roter punkt o.ä. erscheint und dann wählst du "debuggen" aus. wenn der code dann an die stelle mit dem roten punkt angelangt ist, bleibt das programm stehen und du kannst dir den inhalt der variablen ansehen. damit ersparst du dir eine menge arbeit.



  • wob schrieb:

    Und wenn du ostream durch std::ostream ersetzen würdest (oder ein using machen würdest), dann würde das auch kompilieren.Feuer ausbreitet
    ...

    Jo, stimmt. Komischerweise übersetzt und läuft das bei mir so. Hab´s jetzt korrigiert.
    Das Embarcadero RAD Studio ist wohl besser als C++, weil der Compiler einige Sachen korrigieren kann 😃



  • @bamb4s

    Um eine Fehlerquelle komplett auszumerzen (Zugriff auf ungültige Arrayelemente) solltest du dir zwei Funktionen bauen: Eine, die den Wert eines Arrayelements zurückgibt und eine, die den Wert eines Arrayelements setzt. Wenn du in diesen beiden Funktionen eine Gültigkeitsprüfung der Indizes vor dem Arrayzugriff durchführst kannst du nicht mehr auf ungültige Arrayelemente zugreifen.

    char tree_state( std::size_t x, std::size_t y )
    {
       if( x < DimX && y < DimY ) return Wald[x][y];
       else                       return 0;
    }
    
    void set_tree_state( std::size_t x, std::size_t y, char NewState )
    {
       if( x < DimX && y < DimY ) 
       {
          Wald[x][y] = NewState;
       }
    }
    


  • DocShoe schrieb:

    lol?

    Wieso lol? Vielleicht habe ich die Aufgabe auch falsch verstanden, aber wenn Bäume nur eine Runde brennen, ist dies in Relation zur Gesamtfläche sehr wenig. Außerdem weiß man so auch, wann man ferig ist. Das sieht bei den geposteten Codes eher nicht so aus.
    Ich werde das mal testen...



  • Wenn man zwischen brennend und abgebrannt unterscheiden muss, muss man den floodfill doch ein wenig anpassen.

    Stack 1 enthält brennende Bäume (am Anfang drei - rot), diese suchen sich Nachbarn (im Link unten acht, also auch diagonal) zum Entzünden. Werden welche gefunden, werden die Punkte auf Stack 2 gepusht.
    Eine „Runde” ist dann beendet, wenn Stack 1 komplett abgebaut wurde. Der Inhalt von Stack 2 wird kopiert (die entzündeten sind nun die brenndenden Bäume) und die Koordinaten entsprechend markiert (gelb).
    Anschließend wird ein Bild gemacht.

    Das gif ist leider etwas groß geworden (~2MB). Es sind drei Runden mit gleichen Startpunkten aber einer unterschiedlichen Anzahl an Bäumen (Karte 120*80).



  • Wenn kein Baum mehr brennt ist man fertig, das kriegt man auch ohne Stack raus.



  • DocShoe schrieb:

    @bamb4s

    Um eine Fehlerquelle komplett auszumerzen (Zugriff auf ungültige Arrayelemente) solltest du dir zwei Funktionen bauen: Eine, die den Wert eines Arrayelements zurückgibt und eine, die den Wert eines Arrayelements setzt. Wenn du in diesen beiden Funktionen eine Gültigkeitsprüfung der Indizes vor dem Arrayzugriff durchführst kannst du nicht mehr auf ungültige Arrayelemente zugreifen.

    char tree_state( std::size_t x, std::size_t y )
    {
       if( x < DimX && y < DimY ) return Wald[x][y];
       else                       return 0;
    }
    
    void set_tree_state( std::size_t x, std::size_t y, char NewState )
    {
       if( x < DimX && y < DimY ) 
       {
          Wald[x][y] = NewState;
       }
    }
    

    Ich muss zugeben das ich mich noch nicht wirklich mit class beschäftigt habe. Eigentlich sollte da für die Übung auch nicht nötig sein. Trotzdem versuche ich das mal mit einzupacken, denn ich glaub ich hab ein bisschen Blut geleckt fürs Programmieren 🙂



  • Ich wollte nochmal danke an alle für die Hilfe sagen! Hier auch das fertige Programm 🙂

    Testat bestanden! 👍 👍

    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    
    int rand();                                         //Randomizer für den Wald
    void meldung(char a, int b);                        //Funktion für Textausgabe
    int wald1(int a[20][30],int b);                     //Funktion zur Walderstellung
    int brand1(int a[20][30], int b);                   //Brand mit nur einem Baum
    int brand2(int a[20][30], int b);                   //Brand erste Reihe
    int schritt(int a[20][30], int b, int c, char d);   //Schrittschleife für Simulation
    int simulation(int a[20][30], char d);              //Simulation Waldbrand
    void ausgabe(int a[20][30]);                        //Übersetzung des int Arrays in char Array
    
    int auswahl;                                        //Steuert die Menüführung
    int feuer;                                          //Wie wird der Wald angezündet
    int startwert;                                      //Initialisierung von int rand();
    
    double dichte = 1;                                  //Initialisierung der Var für die Dichte des Waldes
    int i, k;                                           //Zähler für die Arrayschleife
    
    int main() {
    
    	//Abfrage der Sprache mit Schleife
    	char Sprache;
    	int wald[20][30];
    
    	cout << endl << "  Please select your language // Bitte Sprache auswaehlen" << endl << endl;
    	cout << "    'e' = English" << endl << "    'd' = Deutsch" << endl << endl;
    	cout << "    Press 'e' or 'd' // Druecken Sie 'e' oder 'd'" << endl;
    	cin >> Sprache;
    	cout << endl;
    
    	//Schleife zur Abfrage ob "e" oder "d" eingegeben wurde
    	while ((Sprache != 'e'&&Sprache != 'd'))
    	{
    		cout << "    Wrong input! Please retry // Falsche Eingabe! Bitte wiederholen" << endl;
    		cin >> Sprache;
    	}
    
    	//Ausgabe des Menüs in vertikaler Ausrichtung (Geht auch in einer Funktion)
    	meldung(Sprache, 1);
    	meldung(Sprache, 2);
    	meldung(Sprache, 3);
    	meldung(Sprache, 4);
    	cout << endl;
    
    	do{
    
          cin >> auswahl;
          switch(auswahl){
    
      case 1:
    
                    //Startwert für Randomizer
                    meldung(Sprache, 9);
                    cin >> startwert;
    
    				meldung(Sprache, 5);
    				cin >> dichte;
    				cout << endl;
    
    				//Dichte wird abgefragt
    				while (dichte>1 || dichte<0)
    				{
    					meldung(Sprache, 6);
    					cin >> dichte;
    					cout << endl;
    				}
    
    				wald1(wald, startwert);
    				ausgabe(wald);
    				meldung(Sprache, 7);
    				break;
    
      case 2:
    
                    meldung(Sprache, 8);
    				cin >> feuer;
    
    				//Schleife um falsche Eingabe zu verhindern
    				while (feuer != 1 && feuer != 2)
    				{
    					meldung(Sprache, 6);
    					cin >> feuer;
    				}
    
    				//Zuweisung der Variablen für Unterprogramm
    				if (feuer == 1)
    				{
    					brand1(wald, startwert);
    					ausgabe(wald);
    					feuer =1;
    				}
    				else {
    					brand2(wald, startwert);
    					ausgabe(wald);
    					feuer =2;
    				}
    				cout << endl;
    				meldung(Sprache, 7);
    				break;
    
      case 3:
    
                    schritt(wald, startwert, feuer, Sprache);
                    cout << endl;
    				meldung(Sprache, 7);
    				break;
    
      case 4:
    
                    break;
    
    	}
    
    	if(auswahl==4){
    
            break;
    	}
    
    	} while(auswahl >0 || auswahl<4);
    
    }
    
    //Meldungen zweisprachig
    void meldung(char a, int b) {
    
        if (a == 'e')    //Englisch
    
        {
                switch(b)
    
                {
    
            case 1:     cout << "\t1: New forest" << endl;
                        break;
    
            case 2:     cout << "\t2: Set fire" << endl;
                        break;
    
            case 3:     cout << "\t3: Simulate fire" << endl;
                        break;
    
            case 4:     cout << "\t4: Exit program" << endl;
                        break;
    
            case 5:     cout << "\tSet forest density 0-1" << endl << endl;
                        break;
    
            case 6:     cout << "\tInvalid Input" << endl << "\tTry again" << endl;
                        break;
    
            case 7:     cout << " 1:New forest  2: Set fire  3:Simulate fire  4:Exit program" << endl;
                        break;
    
            case 8:     cout << "  Set the first tree with (1) on fire. Press (2) to set the first line on fire" << endl;
                        break;
    
            case 9:     cout << "\tSet starting value for randomizer " << endl;
                        break;
    
            case 10:    cout << "\tPress (1) to Continue, any other key to stop" << endl;
                        break;
    
            case 11:    cout << "\tInvalid Input! Press (1)-(4)" << endl;
    
                }
        }
    
        else            //Deutsch
    
    	{
                switch(b)
    
                {
    
            case 1:     cout << "\t1: Neuer Wald" << endl;
                        break;
    
            case 2:     cout << "\t2: Feuer legen" << endl;
                        break;
    
            case 3:     cout << "\t3: Feuer simulieren" << endl;
                        break;
    
            case 4:     cout << "\t4: Programm beenden" << endl;
                        break;
    
            case 5:     cout << "\tDichte des Waldes von 0-1 eingeben" << endl << endl;
                        break;
    
            case 6:     cout << "\tUngueltige Eingabe" << endl << "\tErneute eingeben" << endl;
                        break;
    
            case 7:     cout << " 1:Neuer Wald  2:Feuer legen  3:Feuer simulieren  4:Programm beenden" << endl;
                        break;
    
            case 8:     cout << "  Ersten Baum mit (1) anzuenden. Druecke (2) um die erste Reihe in brand zu setuen" << endl;
                        break;
    
            case 9:     cout << "\tStartwert fuer Zufallsfunktion eingeben" << endl;
                        break;
    
            case 10:    cout << "\tUm fortzufahren (1) druecken, zum abbrechen beliebige Taste druecken" << endl;
                        break;
    
            case 11:    cout << "\tFalsche Eingabe! Druecke (1)-(4)" << endl;
                        break;
    
                }
    	}
    
    }
    //Unterprogramm für Wald Erstellung
    int wald1(int a[20][30],int b){
    
    	srand(b);
    
    	// Schleife fuer Zeilen, Y-Achse
    		for (i = 0; i<20; i++) {
    			// Schleife fuer Spalten, X-Achse
    			for (k = 0; k<30; k++) {
    				//Code für zufällig generierten Wald
    				if (((dichte * 10) - 1) < (rand() % 10))
    					a[i][k] = 0;
    				else
    					a[i][k] = 3;
    			}
    
    		}
    return **a;
    }
    //Unerprogramm um den ersten Baum anzuzünden
    int brand1(int a[20][30], int b){
    
    	srand(b);
    	wald1(a,b);
    
    	int gefunden = 0;
    
    	for(i=0;i<20;i++){
            for(k=0;k<30;k++){
                if (a[i][k] == 3 && gefunden == 0)
                                    {
    					a[i][k] = 2;
    					gefunden = 1;
                                    }
                            }
                        }
        return **a;
    }
    //Unterprogramm um die erste REIHE anzuzünden
    int brand2(int a[20][30], int b){
    
    	srand(b);
        wald1(a, b);
    
        for(i=0;i<20;i++){
            for(k=0;k<30;k++){
               if (a[0][k] == 3)
                {
                a[0][k] = 2;
                }
            }
        }
        return **a;
    }
    //Unterprogramm für Schritte in Simulation
    int schritt(int a[20][30], int b, int c, char d){
    
    	srand(b);
    
    	//Simulation für brennende Reihe
    		if (c==2) {
    
                brand2(a, b);
                cout << endl;
    
                    simulation(a, d);
    
    		} //Int für Abfrage um zu wissen ob schon ein Baum angezündet worden ist}
    		if (c==1) {
    
                brand1(a, b);
                cout << endl;
    
                    simulation(a,d);
    
    			}
    
    		}
    // Unterprogramm simulation
    int simulation(int a[20][30], char d){
    
    int Wald2[20][30] = { 0 };  //Array zur Übergabe
    int weiter = 1;
    
    			while (weiter == 1)
    			{
    
    				for (i = 0; i<20; i++)
    				{
    					for (k = 0; k<1; k++) {
    
    						if (a[i][k] == 2)a[i][k] = 1;
    
    						if (a[i][k] == 1&&a[i + 1][k] == 3 || a[i][k] == 1&&a[i - 1][k] == 3 || a[i][k] == 1&&a[i][k + 1] == 3 || a[i][k] == 1&&a[i][k - 1] == 3) {
    
    							if (a[i + 1][k] == 3)Wald2[i + 1][k] = 2;
    							if (a[i - 1][k] == 3)Wald2[i - 1][k] = 2;
    							if (a[i][k + 1] == 3)Wald2[i][k + 1] = 2;
    						}
    					}
    				}
    
    				for (i = 0; i<20; i++)
    				{
    					for (k = 1; k<30; k++) {
    
    						if (a[i][k] == 2)a[i][k] = 1;
    
    						if (a[i][k] == 1&&a[i + 1][k] == 3 || a[i][k] == 1&&a[i - 1][k] == 3 || a[i][k] == 1&&a[i][k + 1] == 3 || a[i][k] == 1&&a[i][k - 1] == 3) {
    
    							if (a[i + 1][k] == 3)Wald2[i + 1][k] = 2;
    							if (a[i - 1][k] == 3)Wald2[i - 1][k] = 2;
    							if (a[i][k + 1] == 3)Wald2[i][k + 1] = 2;
    							if (a[i][k - 1] == 3)Wald2[i][k - 1] = 2;
    						}
    					}
    				}
    
    				for (i = 0; i<20; i++)
    				{
    					for (k = 0; k<30; k++)
    					{
    						if (Wald2[i][k] == 2)a[i][k] = 2;
    						if (Wald2[i][k] == 2)Wald2[i][k] = 1;
    					}
    				}
    
                ausgabe(a);
    
                meldung(d, 10);
                cin >> weiter;
    }
    
        return **a;
    }
    //Übersetzung
    void ausgabe(int a[20][30]){
    
        char ubersetzung[20][30]= {0};
    
    for(i=0;i<20;i++){
        for(k=0;k<30;k++){
            if(a[i][k]==3)ubersetzung[i][k]='X';
            if(a[i][k]==2)ubersetzung[i][k]='+';
            if(a[i][k]==1)ubersetzung[i][k]='.';
            if(a[i][k]==0)ubersetzung[i][k]=' ';
    
            cout << ubersetzung[i][k] << " ";
    }
     cout << endl;
    }
    
    }
    

    Das return **a; hab ich nicht ganz verstanden, weil return 0; auch geht, aber der Prof hat nichts gesagt. Vielleicht hat er es auch garnicht gesehen.

    Ich dachte erst das wäre nötig um Arrays aus der Funktion zurück zu geben, aber scheinbar ist das nicht so ^^



  • Puhh was soll man dazu sagen, außer ⚠ bitte nicht nachmachen.

    Hab keine Stelle gefunden, wo der return Wert weiterverarbeitet wird. Der einzig sinnvolle return Wert ist dann void.

    An welcher Uni/FH bist du und welches Fach studierst du?



  • Ich hab das noch für mich in return 0; geändert. Das Programm läuft aber eigentlich ordentlich durch.

    Ich studiere Maschinenbau ab der Uni in Erlangen. Also kein Informatik oder so 🙂 So genau hat der Prof auch nicht geschaut, da das Programm lief.



  • So wird das aber nichts mit dem Nachwuchs, wenn an Unis immer noch "C mit cin/cout" als C++ "gelehrt" wird!



  • Aus Interesse: Warum lehrt man es dann überhaupt, wenn man es später eh nicht richtig anwenden soll?

    Wenn nur für den Überblick, wäre Java oder Phyton nicht die bessere Wahl? Oder ein BASIC-Dialekt?



  • lemon03 schrieb:

    Aus Interesse: Warum lehrt man es dann überhaupt, wenn man es später eh nicht richtig anwenden soll?

    Wenn nur für den Überblick, wäre Java oder Phyton nicht die bessere Wahl? Oder ein BASIC-Dialekt?

    Weil Maschinen meist mit C++ programmiert sind und der Ingenieur in der Lage sein soll nachzuvollziehen was der Programmierer in seinem Programm gemacht hat.
    Der Programmierer weis in der Regel zwar für was sein Programm genutzt wird, aber kennt die technischen Hintergründe nicht immer. So zumindest unser Prof.

    https://imgur.com/a/sIMGBZC : Programmiersprachen bei der Programmierung von Embedded Prozessoren

    https://imgur.com/a/E1jdvYb : Beispiel Airbag

    Ich würde es auch gut finden, es einmal richtig zu lernen, aber ich denke hier geht es weniger um die Syntax und mehr um die Abläufe an sich. Bei laut Modulhandbuch 28Std. Seminatischer Unterricht, 24 Stunden Übungen und 38Std. Vor- Nachbearbeitung (Summe 90Std.) Kann der Umfang allerdings auch nicht so hoch ausfallen.



  • Aha, danke 🙂

    Ich denke aber, Maschinen werden eher in C programmiert. Aus Speicherplatzgründen oder so.

    Für die Abläufe extra C++ falsch lernen finde ich nicht richtig. Da sollte man dann doch besser eine höher-levelige (:D) Sprache wählen.


Log in to reply