pls pimp my 4gewinnt!



  • c.rackwitz schrieb:

    das syntaxhighlighting (und den nicht-monospace font) vom debianforum nopaste find ich kindisch und ablenkend.

    ok

    davon abgesehen ist dein programm nicht modular. deine "funktionen" haben ja nicht mal parameter.

    ok, aber was soll ich zB bei print_matrix für parameter übergeben.
    und die matrix lokal zu deklarieren und durch die ganzen funktionen "durchzuschleifen" ist ja wohl blöd?

    die breite und hoehe hast du mehrmals als magic number im code verstreut. das gehoert an eine stelle definiert und mit aussagekraeftigen namen ueberall wiederverwendet.

    hm...du meinst du rows und columns vom spieldeld?
    soll ich leiber sowas machen?

    #define ROWS 6
    #define COLUMNS 7
    

    deine check_pl() und check_pc() haben optimierungspotential.

    deswegen habe ich den thread aufgemacht 😉

    die diagonalpruefungen lassen sich mit einer einzigen laufvariable schreiben. ausserdem lassen sich deine 4 diagonalpruefungen zu einem einzigen doppel-loop (x und y) mit jeweils zwei pruefungen zusammenschrumpfen.

    😕
    du schreibst:
    "die diagonalpruefungen lassen sich mit einer einzigen laufvariable schreiben.
    und dann:
    "deine 4 diagonalpruefungen zu einem einzigen doppel-loop (x und y) mit jeweils zwei pruefungen zusammenschrumpfen."

    ich gehe jetzt mal davon aus, dass du beim ersteren die horizontalen und
    vertikalen meinst 🙂

    ok. dann setze ich mich morgen nochmal ran und überleg mir was gescheiteres bzw
    ich warte jetzt erst mal ab, ob ich das bis jetzt verstanden habe, was du sagen
    wolltest...

    davon abgesehen gehoeren beide funktionen vereint.
    doppelter code ist boese.

    ja habe ich auch festgestellt, das das unelegant gelöst ist.
    ich werde check_pl & check_pc in eine funktion zusammenfassen und
    mir außerdem was neues für die überprüfung auf unentschieden einfallen lassen.

    danke für die bis jetzt gekommene hilfe!
    (aber habt bitte weiterhin verständnis, dass ich nicht -im gegensatz
    zu anderen- 4 jahre informatik studium hinter mir habe...)

    lg icepacker



  • info studium hat nix mit proggen zu tun 🙂



  • wichtigeInfo(naja) schrieb:

    info studium hat nix mit proggen zu tun 🙂

    kann ja sein, aber ich denke, dass das hier eher ein logisches (<- ist jetzt wahrscheinlich der falsche ausdruck 😉 )
    problem ist, da ich scheinbar zu blöd bin anhand einfacher kontrollstrukturen
    ein problem zu lösen bzw. meine lösung ist sehr umständlich.
    und ich denke schon das man so eine herangehensweise und lösung mit der zeit lernt
    und es dann auch besser macht.
    natürlich muss dazu nicht informatik studiert haben, aber man wird hier ja
    generell angepöpelt egal um was es geht.

    @c.rackwitz

    deine 4 diagonalpruefungen zu einem einzigen doppel-loop (x und y) mit jeweils zwei pruefungen zusammenschrumpfen.

    "doppel-loop" sind das 2 verschachtelte oder nacheinander ablaufende schleifen?

    //also so??
    loop
    {
      1pruefung1   //also if?
      1pruefung2
    
      loop
      {
        2pruefung1
        2pruefung2
      }
    }
    


  • c.rackwitz schrieb:

    die diagonalpruefungen lassen sich mit einer einzigen laufvariable schreiben.

    int diagonalpruefung(char **matrix, char player, int x, int y)
    {
        int i, c1, c2, n=4;
        // char player: "davon abgesehen gehoeren beide funktionen vereint" -> auf wen geprueft wird, gehoert als funktionsparameter uebergeben
    
        for (c1 = c2 = i = 0; i < n; ++i)
        {
            c1 += (matrix[y+i][x+i] == player);
            c2 += (matrix[y+i][x+n-1-i] == player);
        }
    
        return (c1 == n || c2 == n);
    }
    


    damit kreuzt du ueber das spielfeld...

    c.rackwitz schrieb:

    ausserdem lassen sich deine 4 diagonalpruefungen zu einem einzigen doppel-loop (x und y) mit jeweils zwei pruefungen zusammenschrumpfen.

    int x, y, w = 7, h = 6;
    int n = 4; // 4-gewinnt
    for (y = 0; y < h-n; ++y)
        for (x = 0; x < w-n; ++x)
            if (diagonalpruefung(matrix, player, x, y)) puts("irgendwer hat diagonal 4 steine"); // das hier sind zwei pruefungen, versteckt in der funktion
    

    fuer die senkrechten und waagerechten pruefungen wuerde ich nen anderen loop benutzen, vorzugsweise den du schon benutzt. der hat naemlich eine interessante optimale logik (die sache mit dem counter).



  • 2 sachen:

    1.@ c.rackwitz
    mal davon abgesehen, dass ich noch nicht kapiert habe wie deine lösung funktioniert.
    IMO ist sie falsch bzw sie überprüft nicht alle möglichen gewinnreihen.
    zB die reihe:

    2/0, 3/1, 4/2, 5/3

    und da ich keine lust habe, zu versuchen, einen höchstwahrscheinlich mangelhaften
    algo zu kapieren, wäre es super wenn du
    a) mir sagst, dass der algo doch richtig ist und ich mich geirrt habe
    oder
    b) den algo korrigierst,
    und/oder
    c) diese schleifen konstruktionen da, ein bisschen erläuterst damit
    ich es verstehe und den vermeindlichen fehler selber beheben kann.

    2. ich verstehe nicht warum ich beim kompilieren folgenden fehler erhalte:

    Warnung: Übergabe des Arguments 1 von »diagonalpruefung« von inkompatiblem Zeigertyp

    danke für eure hilfe!

    lg icepacker



  • du irrst dich.

    die pruefung arbeitet mit verschiedenen offsets, also wird das ganze feld getestet.

    du verstehst also meinen code nicht einmal, aber willst schon behauptungen ueber seine richtigkeit anstellen? schaem dich.



  • ok ich schäm mich 🤡

    aber noch ist nichts bewiesen :p

    meine 2 beweise:
    - ich habe mir die matrix bei jedem durchlauf ausgeben lassen!

    void diagonalpruefung(char **matrix, char player, int x, int y)
    {
        int i, c1, c2, n=4;
        // char player: "davon abgesehen gehoeren beide funktionen vereint" -> auf wen geprueft wird, gehoert als funktionsparameter uebergeben
    
        for (c1 = c2 = i = 0; i < n; ++i)
        {
            printf("%d %d", y+i, x+i);
            printf("\t %d %d", y+i, x+n-1-i);
        }
    
    }
    

    dann habe ich alle koardinaten in meine matrix skizze(auf papier) eingezeichnet
    => manche felder sind ungeschoren davon gekommen.

    - dann habe ich deinen code in mein programm eingebaut und gezielt auf die
    schwachstellen gespielt und siehe da! bei manchen gabs kein gewinn signal
    natürlich die, die ich schon vorher aufm papier festgestellt hatte...

    q.e.d

    icepacker



  • du benutzt die diagonalpruefung ja auch nicht allein, sondern wiederum in einer doppelten schleife (ueber y und x). hast du doch, oder?



  • ja habe ich!
    genauso wie bei deinem code
    und trotzdem bleiben felder überig, wo potentielle vierer reihen entstehen können!



  • darstellenden beispielcode bitte.



  • bin mir jetzt nicht sicher was du sehen willst 😞

    naja...

    #include <stdio.h>
    
    char matrix[6][7]; //wieder global, wegen dem kompiler-error (s.oben)
    
    void diagonalpruefung(int x, int y)
    {
        int i, c1, c2, n=4;
    
        puts("diagonalpruefung:");
    
        for (c1 = c2 = i = 0; i < n; ++i)
        {
            printf("%d %d\n", y+i, x+i);
            printf("\t %d %d\n", y+i, x+n-1-i);
        }
    }
    
    int main (void)
    {
        int x, y, w = 7, h = 6;
        int n = 4; // 4-gewinnt
        for (y = 0; y < h-n; ++y)
            for (x = 0; x < w-n; ++x)
            {
                 printf("\n\nmain:%d %d\n", x, y);
                 diagonalpruefung(x, y);
            }
    
        return 0;
    }
    

    output:

    main:0 0
    diagonalpruefung:
    0 0
        0 3
    1 1
        1 2
    2 2
        2 1
    3 3
        3 0
    
    main:1 0
    diagonalpruefung:
    0 1
    	 0 4
    1 2
    	 1 3
    2 3
    	 2 2
    3 4
    	 3 1
    
    main:2 0
    diagonalpruefung:
    0 2
    	 0 5
    1 3
    	 1 4
    2 4
    	 2 3
    3 5
    	 3 2
    
    main:0 1
    diagonalpruefung:
    1 0
    	 1 3
    2 1
    	 2 2
    3 2
    	 3 1
    4 3
    	 4 0
    
    main:1 1
    diagonalpruefung:
    1 1
    	 1 4
    2 2
    	 2 3
    3 3
    	 3 2
    4 4
    	 4 1
    
    main:2 1
    diagonalpruefung:
    1 2
    	 1 5
    2 3
    	 2 4
    3 4
    	 3 3
    4 5
    	 4 2
    

    und da fehlen einfach welche!



  • hast du dir auch mal ueberlegt, welche da fehlen?
    http://catb.org/~esr/jargon/html/O/off-by-one-error.html

    korrektur geht so:

    ...
    for (y = 0; y <= h-n; ++y)
        for (x = 0; x <= w-n; ++x)
    ...
    

    du hast nen compiler und moeglicherweise auch noch debugger zur verfuegung und kannst dir sogar anzeigen lassen, welche felder nie angeruehrt werden. ich dagegen mach das alles im kopf und aus dem handgelenk. eigentlich haettest du diesen schnitzer finden muessen, zumal solche arten von fehlern schnell passieren koennen und man sie deshalb auch frueh erkennen lernen sollte.

    nichtsdestotrotz habe ich den fehler gemacht und es bleibt meiner. sorry dafuer.



  • c.rackwitz schrieb:

    korrektur geht so:

    ...
    for (y = 0; y <= h-n; ++y)
        for (x = 0; x <= w-n; ++x)
    ...
    

    super danke!

    du hast nen compiler und moeglicherweise auch noch debugger zur verfuegung und kannst dir sogar anzeigen lassen, welche felder nie angeruehrt werden. ich dagegen mach das alles im kopf und aus dem handgelenk. eigentlich haettest du diesen schnitzer finden muessen, zumal solche arten von fehlern schnell passieren koennen und man sie deshalb auch frueh erkennen lernen sollte.

    ja du hast recht.
    wenn ich mehr eigeninitiative gezeigt hätte, wäre ich vermutlich selber darauf
    gekommen. leider ist man oft, besonders anfangs, einfach zu faul 😞
    also, ich gelobe besserung 🙂

    nichtsdestotrotz habe ich den fehler gemacht und es bleibt meiner. sorry dafuer.

    kein thema, schließlich sollte ich -bin ich auch- dafür dankbar sein, dass überhaupt
    jemand versucht mir zu helfen!

    naja gut dass jetzt alles geklärt ist 👍

    icepacker


Anmelden zum Antworten