Aktuelle Array Position
-
1. Wie lange brennt denn ein Baum eigentlich? Abgebrannte Bäume kommen bei DocShoe nicht vor, wenn ich das richtig sehe. Will die Aufgabe vielleicht, dass nach einer Runde brennen ein Baum abgebrannt ist?
2. Was tut ignition_progress? Refactoring/Umbenennung in spread_ignition, ohne alle Vorkommen zu ersetzen?
-
wob schrieb:
2. Was tut ignition_progress? Refactoring/Umbenennung in spread_ignition, ohne alle Vorkommen zu ersetzen?
Sehr gut, da passt jemand auf
Edit:
Im Gegensatz zu mir. Hab´ die Aufgabe nur überflogen und überheblicherweise angenommen, das hätte gereicht und ich die Aufgabe verstanden. Pustekuchen...
-
Und wenn du ostream durch std::ostream ersetzen würdest (oder ein using machen würdest), dann würde das auch kompilieren. Macht schon Spaß, einen virtuellen Wald an mehreren Stellen anzustecken und zu schauen, wie sich das Feuer ausbreitet
-
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.
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.