8 Damenproblem



  • Der Spass wäre leichter zu Lesen (und zu Schreiben) wenn du die Variablen für X und Y ... naja "x" und "y" nennen würdest 😉

    Ps:

    Buffer Overflow oder wie man das nennt

    "oder wie man das nennt" ist schlecht, gerade als Anfänger.
    Wir wissen was ein Buffer Overflow ist. Aber woher sollen wir wissen ob du wirklich einen Buffer Overflow meinst?


  • Mod

    Leider ziemlich viel falsch 😞 . Fangen wir mal an:

    • Wieso prüfst du nicht zuerst, ob das Feld legal ist? Das würde sehr viele deiner Probleme lösen, unter anderem dein Vorhaben mit dem

    Aber wie fixiere ich die erste Dame, ohne dass ich das Feld auf "false" setze.

    Es würde auch so einiges an Problemen lösen, die du noch gar nicht erkannt hast. Darunter unter anderem:
    -Was, wenn die Platzierung nicht legal ist? Wie die Markierung rückgängig machen?
    -Was, wenn bei der nächsten Eingabe eine Dame an die gleiche Position gesetzt wird? Momentan bei dir legal.

    • Wie schon erwähnt, sind alle Schleifen Bedingungen von der Art, dass die Schleife läuft, solange die Bedingung erfüllt ist. Das gilt auch für for-Schleifen.
    • = ist eine Zuweisung, kein Vergleich
    • Wenn du sich ähnelnde Schleifen per Copy&Paste&Ändern programmierst, dann stell auch sicher, dass du alle relevanten Teile änderst. Besonders bei Buchstaben, die sich ähnlich sehen, wie 'i' und 'j', passieren da schnell Fehler...
    • Wenn du sich ähnelnde Schleifen nicht per Copy&Paste&Ändern programmierst, sondern per Abschreiben, dann stell auch sicher, dass du alle relevanten Teile mit abschreibst. Und beispielsweise nicht vergisst, was die Schleife überhaupt machen soll...
    • Sei dir sicher, welche Variable in deinem Code welche Bedeutung hat. Du änderst ziemlich willkürlich ein paar Werte, die du besser nicht ändern solltest. Und benutzt an anderen Stellen die falschen Werte.
    • Es kann hilfreich sein, den Programmfluss auf einem Stück Papier durchzugehen, indem man sich selber in die Lage des Computers versetzt und ganz genau den Code abarbeitet, wie er das steht. Dabei aufschreiben, welche Variable wo welchen Wert hat. Doppelt hilfreich, wenn man nebenher noch mit einem Debugger im Einzelschritt durch das Programm geht und vergleicht, ob man wirklich richtig liegt.

    Ehrlich gesagt ist das ziemlicher schlecht. Klingt hart, ist aber so. Der Code sieht aus wie mal eben schnell hingekotzt, damit da überhaupt irgendwas steht. Ohne auch nur einen einzigen Moment lang mal zu gucken, ob das irgendwie Sinn macht oder so richtig ist. Wenn du mit derart wenig Sorgfalt programmierst oder wenn dies die größte Sorgfalt ist, zu der du fähig bist, dann wird das nichts. Programmieren ist das Übersetzen deiner Gedanken in eine streng mathematische Form. Code ist Logik pur, kein hingeschluderter Haufen Zeichen. Du musst von jedem Zeichen in deinem Programm genau wissen, wo du es warum setzt. Wenn du dazu nicht fähig bist, dann ist Programmieren vielleicht nichts für dich. Zumal der Anfangspunkt dieses Übersetzungsprozesses, also deine Gedanken, bereits falsch zu sein scheinen. Du hast keinen Plan, wie das Programm überhaupt ablaufen soll, siehe den ersten Punkt ganz oben. Niemand wäre hier auf den Gedanken gekommen, dass du die Prüfung, ob die Eingabe legal war, nach dem Markieren der Felder durchführen wolltest. Das macht einfach keinen Sinn und daher hat niemand so richtig verstanden, was du mit dem

    Aber wie fixiere ich die erste Dame, ohne dass ich das Feld auf "false" setze.

    überhaupt erreichen wolltest. Auch an einfachen Problemen scheitert es bereits, du scheinst keinen Algorithmus formulieren zu können, wie man diagonal durch das Spielfeld gehen kann. Ansätze sind da, aber du scheinst komische Zusatzvorstellungen zu haben, die ein sehr einfaches Problem so weit verkomplizieren, bis die Lösung falsch ist.



  • Danke für die ausführliche Rückmeldung.

    Ich habe auf keinen Fall vor, das Programmieren sein zu lassen, da es mir Spaß macht.
    Allerdings ist es wirklich schwer für mich, das was ich umsetzen muss, zu verstehen.

    Ich hatte bis jetzt keinerlei zweifel daran, dass Logisch zu denken ein Problem für mich darstellt.
    Ich hoffe, dass es einfach daran liegt, dass ich die Basics nicht beherrsche.

    Ich werde einfach üben, bis ich es kann. 😉

    lG D.

    EDIT: Ich komme nicht drauf wie man die Diagonalfelder "abdeckt" also auf false setzt, ohne die anderen Felder, die die Dame nicht abdeckt, auf false zu setzen.



  • Karmon schrieb:

    Danke für die ausführliche Rückmeldung.

    Ich habe auf keinen Fall vor, das Programmieren sein zu lassen, da es mir Spaß macht.
    Allerdings ist es wirklich schwer für mich, das was ich umsetzen muss, zu verstehen.

    Ich hatte bis jetzt keinerlei zweifel daran, dass Logisch zu denken ein Problem für mich darstellt.
    Ich hoffe, dass es einfach daran liegt, dass ich die Basics nicht beherrsche.

    Ich werde einfach üben, bis ich es kann. 😉

    lG D.

    EDIT: Ich komme nicht drauf wie man die Diagonalfelder "abdeckt" also auf false setzt, ohne die anderen Felder, die die Dame nicht abdeckt, auf false zu setzen.

    niemand hat die weisheit mit löffeln gegessen und es ist noch nie ein meister vom himmel gefallen...

    üben üben und theorie und grundlagen wiederholen, das hilft meistens viel...

    auch um methoden und herangehensweisen besser zu durchdringen oder überhaupt einmal richtig zu verstehen!

    lass dich aber nicht demotivieren! und verlier den spaß daran...! 😃



  • Karmon schrieb:

    EDIT: Ich komme nicht drauf wie man die Diagonalfelder "abdeckt" also auf false setzt, ohne die anderen Felder, die die Dame nicht abdeckt, auf false zu setzen.

    Hier mal eine exemplarische Schleife von dir. Ich weiß nicht genau, was die machen soll, aber sie enthält einige grobe Schnitzer sowohl in der Logik als auch was dein Wissen über C++ angeht.

    for(int i=damenposition2-1;i=0;i--){
        for(int j=damenposition1+1;i<8;i++){
            brett[i][j]=false;
            damenposition2--;
        }
    }
    

    Auf den ersten Blick sind das zwei verschachtelte Schleifen, d.h. es wird ein zweidimensionaler Bereich abgelaufen, vielleicht ein Rechteck. Eine Diagonale ist aber ein eindimensionales Objekt, nur eine Linie. Der einzige naheliegende Ansatz ist daher, das mit nur einer for-Schleife zu machen.

    Auf den zweiten Blick fällt auf, dass die Bedingung in der ersten Schleife, i = 0 , eine Zuweisung ist. Mit an Sicherheit grenzender Wahrscheinlichkeit ist der Vergleich i == 0 gemeint, so dass die Schleife i runterzählt und bei 0 abbricht. Jetzt musst du aber wissen, dass das eine "Solange"-Bedingung ist, d.h. wenn du bei 0 abbrechen willst, muss da i != 0 stehen.

    In der zweiten Schleife initialisierst du j, benutzt aber in der Bedingung und im Update-Ausdruck i. Was da dann genau passiert ist relativ undurchdringlich, höchstwahrscheinlich ist das auch nicht so gemeint.

    Um den richtigen Algorithmus zu finden, solltest du die Aufgabe aufteilen:

    1. Schreibe eine Schleife, die die Koordinaten der Felder entlang einer Diagonale ausgibt.
    2. Überlege dir geometrisch, von wo bis wo diese Schleife laufen muss, damit die richtigen Felder auf dem Schachbrett getroffen werden.
    3. Erst wenn das funktioniert baue es in dein 8-Damen-Programm ein.


  • MfG schrieb:

    niemand hat die weisheit mit löffeln gegessen und es ist noch nie ein meister vom himmel gefallen...

    üben üben und theorie und grundlagen wiederholen, das hilft meistens viel...

    auch um methoden und herangehensweisen besser zu durchdringen oder überhaupt einmal richtig zu verstehen!

    lass dich aber nicht demotivieren! und verlier den spaß daran...! 😃

    Danke für die Aufmunterung :p.

    Bashar schrieb:

    Karmon schrieb:

    EDIT: Ich komme nicht drauf wie man die Diagonalfelder "abdeckt" also auf false setzt, ohne die anderen Felder, die die Dame nicht abdeckt, auf false zu setzen.

    Hier mal eine exemplarische Schleife von dir. Ich weiß nicht genau, was die machen soll, aber sie enthält einige grobe Schnitzer sowohl in der Logik als auch was dein Wissen über C++ angeht.

    for(int i=damenposition2-1;i=0;i--){
        for(int j=damenposition1+1;i<8;i++){
            brett[i][j]=false;
            damenposition2--;
        }
    }
    

    Auf den ersten Blick sind das zwei verschachtelte Schleifen, d.h. es wird ein zweidimensionaler Bereich abgelaufen, vielleicht ein Rechteck. Eine Diagonale ist aber ein eindimensionales Objekt, nur eine Linie. Der einzige naheliegende Ansatz ist daher, das mit nur einer for-Schleife zu machen.

    Auf den zweiten Blick fällt auf, dass die Bedingung in der ersten Schleife, i = 0 , eine Zuweisung ist. Mit an Sicherheit grenzender Wahrscheinlichkeit ist der Vergleich i == 0 gemeint, so dass die Schleife i runterzählt und bei 0 abbricht. Jetzt musst du aber wissen, dass das eine "Solange"-Bedingung ist, d.h. wenn du bei 0 abbrechen willst, muss da i != 0 stehen.

    In der zweiten Schleife initialisierst du j, benutzt aber in der Bedingung und im Update-Ausdruck i. Was da dann genau passiert ist relativ undurchdringlich, höchstwahrscheinlich ist das auch nicht so gemeint.

    Um den richtigen Algorithmus zu finden, solltest du die Aufgabe aufteilen:

    1. Schreibe eine Schleife, die die Koordinaten der Felder entlang einer Diagonale ausgibt.
    2. Überlege dir geometrisch, von wo bis wo diese Schleife laufen muss, damit die richtigen Felder auf dem Schachbrett getroffen werden.
    3. Erst wenn das funktioniert baue es in dein 8-Damen-Programm ein.

    Ich denke ich hab es verstanden.

    Hier ist mal ein Code für eine Diagonale die von 0/0 ausgeht und die diagonale nach rechts unten entlang wandern sollte.

    Falls diese richtig ist, sollte es nicht zu schwer sein, davon ausgehend, die anderen Richtungen zu bestimmen.

    for(int i=damenposition1; i<8;i++){
       int j=damenposition2;
          brett[i][j]=false;
             j++;
    }
    

    ist das jetzt so die richtige Denkweise?

    Mein Gedankengang ist folgender:
    i wird immer um 1 erhöht und j auch.
    das heißt es geht vom Feld 0/0 auf das Feld 1/1.

    Wenn die Benutzereingabe dann 5/5 ist, ist i gleich 5 also hört es wieder bei 7 auf.

    Anschließend noch eine Frage. (falls der vorherige Code richtig ist.)
    Ausgehend von z.B. 4/2 (also C5)

    for(int i=damenposition1;i>=0;i--){ //i>=0 damit es bis 0 geht, und dann abbricht, richtig?
        int j=damenposition2;
        brett[i][j]=false;
        j--;
    }
    

    Dann geht i bis 0 und j geht mit i jeweils um -1 mit. also wird aus 4/2 -> 3/1 und dann 2/0, wo die schleife dann aufhört, da der "Rand" des Spielbretts erreich wurde.



  • Karmon schrieb:

    Hier ist mal ein Code für eine Diagonale die von 0/0 ausgeht und die diagonale nach rechts unten entlang wandern sollte.

    Falls diese richtig ist, sollte es nicht zu schwer sein, davon ausgehend, die anderen Richtungen zu bestimmen.

    for(int i=damenposition1; i<8;i++){
       int j=damenposition2;
          brett[i][j]=false;
             j++;
    }
    

    ist das jetzt so die richtige Denkweise?

    Schon besser, aber immer noch falsch. Das j wird in jedem Durchlauf wieder auf damenposition2 gesetzt. Das sollte nur am Anfang passieren:

    for (int i = damenposition1, j = damenposition2; ......)
    

    Du solltest die Koordinaten übrigens ausgeben und nicht in dein brett-Array eintragen, damit du sofort siehst, wenn es falsch ist. Ja, in einem eigenen Programm. Wenn es funktioniert, überträgst du den Algorithmus in das Damenprogramm.

    Mein Gedankengang ist folgender:
    i wird immer um 1 erhöht und j auch.
    das heißt es geht vom Feld 0/0 auf das Feld 1/1.

    Richtig.

    Anschließend noch eine Frage. (falls der vorherige Code richtig ist.)
    Ausgehend von z.B. 4/2 (also C5)

    for(int i=damenposition1;i>=0;i--){ //i>=0 damit es bis 0 geht, und dann abbricht, richtig?
        int j=damenposition2;
        brett[i][j]=false;
        j--;
    }
    

    Dann geht i bis 0 und j geht mit i jeweils um -1 mit. also wird aus 4/2 -> 3/1 und dann 2/0, wo die schleife dann aufhört, da der "Rand" des Spielbretts erreich wurde.

    Hier wird ja j negativ, aber deine Bedingung prüft i, dh die Schleife geht weiter: 1/-1, 0/-2.



  • Karmon schrieb:

    Bashar schrieb:

    Karmon schrieb:

    EDIT: Ich komme nicht drauf wie man die Diagonalfelder "abdeckt" also auf false setzt, ohne die anderen Felder, die die Dame nicht abdeckt, auf false zu setzen.

    Hier mal eine exemplarische Schleife von dir. Ich weiß nicht genau, was die machen soll, aber sie enthält einige grobe Schnitzer sowohl in der Logik als auch was dein Wissen über C++ angeht.

    for(int i=damenposition2-1;i=0;i--){
        for(int j=damenposition1+1;i<8;i++){
            brett[i][j]=false;
            damenposition2--;
        }
    }
    

    Auf den ersten Blick sind das zwei verschachtelte Schleifen, d.h. es wird ein zweidimensionaler Bereich abgelaufen, vielleicht ein Rechteck. Eine Diagonale ist aber ein eindimensionales Objekt, nur eine Linie. Der einzige naheliegende Ansatz ist daher, das mit nur einer for-Schleife zu machen.

    Auf den zweiten Blick fällt auf, dass die Bedingung in der ersten Schleife, i = 0 , eine Zuweisung ist. Mit an Sicherheit grenzender Wahrscheinlichkeit ist der Vergleich i == 0 gemeint, so dass die Schleife i runterzählt und bei 0 abbricht. Jetzt musst du aber wissen, dass das eine "Solange"-Bedingung ist, d.h. wenn du bei 0 abbrechen willst, muss da i != 0 stehen.

    In der zweiten Schleife initialisierst du j, benutzt aber in der Bedingung und im Update-Ausdruck i. Was da dann genau passiert ist relativ undurchdringlich, höchstwahrscheinlich ist das auch nicht so gemeint.

    Um den richtigen Algorithmus zu finden, solltest du die Aufgabe aufteilen:

    1. Schreibe eine Schleife, die die Koordinaten der Felder entlang einer Diagonale ausgibt.
    2. Überlege dir geometrisch, von wo bis wo diese Schleife laufen muss, damit die richtigen Felder auf dem Schachbrett getroffen werden.
    3. Erst wenn das funktioniert baue es in dein 8-Damen-Programm ein.

    Ich denke ich hab es verstanden.

    Hier ist mal ein Code für eine Diagonale die von 0/0 ausgeht und die diagonale nach rechts unten entlang wandern sollte.

    Falls diese richtig ist, sollte es nicht zu schwer sein, davon ausgehend, die anderen Richtungen zu bestimmen.

    for(int i=damenposition1; i<8;i++){
       int j=damenposition2;
          brett[i][j]=false;
             j++;
    }
    

    ist das jetzt so die richtige Denkweise?

    Mein Gedankengang ist folgender:
    i wird immer um 1 erhöht und j auch.
    das heißt es geht vom Feld 0/0 auf das Feld 1/1.

    Wenn die Benutzereingabe dann 5/5 ist, ist i gleich 5 also hört es wieder bei 7 auf.

    Anschließend noch eine Frage. (falls der vorherige Code richtig ist.)
    Ausgehend von z.B. 4/2 (also C5)

    for(int i=damenposition1;i>=0;i--){ //i>=0 damit es bis 0 geht, und dann abbricht, richtig?
        int j=damenposition2;
        brett[i][j]=false;
        j--;
    }
    

    Dann geht i bis 0 und j geht mit i jeweils um -1 mit. also wird aus 4/2 -> 3/1 und dann 2/0, wo die schleife dann aufhört, da der "Rand" des Spielbretts erreich wurde.

    ich glaube die denkweise war eher so gemeint:

    for(int i=damenposition1;i<8;i++)
    {
         brett[i][i]=false;
    }
    

    versuch so wenig variablen wie möglich zu deklarieren ... 😃
    vll ist das auch nicht das was du machen willst? aber so wie ich es verstanden habe müsste das so passen oder? 🙂

    bei dem anderen dann halt genau so ...



  • sry vergiss meinen post...
    hatte nicht gesehen das du damenposition2 nimmst in j... -> also einen anderen wert als in i... 🙄

    aber es hat einen anderen fehler...
    wenn du variablen wie j lokal gültig nutzt dann verlieren sie danach die gültigkeit achtung!

    desweiteren bashar hatte es schon geschrieben...

    for (int i = damenposition1, j = damenposition2; ......)
    

    also so:

    for(int i=damenpos1, int j = damenpos2; i<8 ; i++)
    {
      brett[i][j];
    }
    


  • Jetzt beginnt sich der Nebel langsam zu verdünnen.

    Um die Zeilen und Spalten auf false zu setzen brauche ich 4 Schleifen.

    jetzt habe ich noch eine frage zu diesen 2 Zeilen.

    for(int i=0;i<8;i++){
    	brett[i][damenposition2]=false;
    }
    for(int j=0; j<8;j++){
    	brett[damenposition1][j]=false;
    }
    

    Hier brauche ich dann noch 2 Schleifen, die mir falls die Benutzereingabe wieder mitten im Feld ist, auch noch in die anderen Richtungen geht.

    Wäre dann der folgende Code dafür richtig?

    for(int i=damenposition1;i>=0;i--){
        brett[i][damenposition2]=false;
    }
    
    for(int j=damenposition2;j>=0;j--){
        brett[damenposition1][j]=false;
    }
    

    Nun sollte ich jede Möglichkeit Spalten und Zeilen auf "false" zu setzen abgedeckt habe.

    Mit den 4 Schleifen für die Diagonalen bin ich nun fertig.



  • Karmon schrieb:

    for(int i=0;i<8;i++){
    	brett[i][damenposition2]=false;
    }
    for(int j=0; j<8;j++){
    	brett[damenposition1][j]=false;
    }
    

    Hier brauche ich dann noch 2 Schleifen, die mir falls die Benutzereingabe wieder mitten im Feld ist, auch noch in die anderen Richtungen geht.

    Äh.
    Nein.
    Wieso meinst du du bräuchtest da noch mehr?

    Das Brett hat nicht mehr als 8 Zeilen bzw. Spalten, und mit den beiden Schleifen gehst du beide durch.

    Kannst du sogar zu einer Schleife zusammenfassen (was aber die Verständlichkeit nicht unbedingt erhöt):

    for(int i=0;i<8;i++){
    	brett[i][damenposition2]=false;
    	brett[damenposition1][i]=false;
    }
    

Anmelden zum Antworten