4 Gewinnt - Diagonalen Abfrage



  • Hey Guten Morgen,
    ich bin derzeit...wie so viel andere 😛 dabei das Vier-Gewinnt Spiel zu programmieren.
    Nun geht wirklich alles bis auf 2 Abfragen. Nämlich die auf die möglichkeit von 4 Steinen in einer Diagonalen. Die Beiden funktionen unten sollen das tun, tun es aber nicht richtig.

    Bei einer Diagonalen von links unten nach rechts oben darf man den letzten stein nicht links unten setzten sonst gehts es nicht.
    Bei einer Diagonalen von rechts oben nach links unten geht gar nicht.

    Ich versteh einfach nicht was da falsch ist, weil die Struktur von den andern Gewinnfunktionen sehen genau so aus und funktionieren einwandfrei.

    Könnt ihr mir helfen?
    Lg

    int gewinndiag1(char array[ARRAY_ZEILE][ARRAY_SPALTE],  int i, int j, int zeile, int spalte, char spieler)
    {
    	int gewinnz=0;
    	while(array[i][j]==spieler && j>=0 && i>=0)
    	{
    		j--;
    		i--;		
    	}
    
    	while(array[i][j]==spieler && j<=spalte && i<=zeile)
    	{
    		j++;
    		i++;	
    		gewinnz++;
    		if (gewinnz>=1)
    		{
    			printf ("Gewonnen %c\n",spieler);
    			exit(0);
    		}
    	}
    	return(0);
    }
    
    int gewinndiag2(char array[ARRAY_ZEILE][ARRAY_SPALTE],  int i, int j, int zeile, int spalte, char spieler)
    {
    
    	int gewinnz=0;
    	while(array[i][j]==spieler && j<=spalte && i>=0)
    	{
    		j++;
    		i--;	
    
    	}
    	while(array[i][j]==spieler && j>=0 && i<=zeile)
    	{
    		j--;
    		i++;	
    		gewinnz++;
    		if (gewinnz>=4)
    		{
    			printf ("Gewonnen %c\n",spieler);
    			exit(0);
    		}
    	}
    	return(0);
    }
    


  • Hallo

    Zum einen, bei deiner Funktion "gewinndiag1" kommt die 2te while Schleife nie zum Zug. Da du in der ersten solange nach links unten (ich nehm mal an, das i=0 linke Seite und j=0 untere Seite bedeutet) läuft bis du ein Element findest, das _nicht_ mehr dem angegeben Spieler gehört. Dadurch fällt dann deine 2te While schleife gleich mit false durch, da die erste Bedingung ja ein Element des angegeben Spielers verlangt.

    Bei der 2ten Funktion ist es das gleiche.

    MfG Marc-o



  • Thörb schrieb:

    int gewinndiag1(char array[ARRAY_ZEILE][ARRAY_SPALTE],  int i, int j, int zeile, int spalte, char spieler)
    {
    	int gewinnz=0;
    	while(array[i][j]==spieler && j>=0 && i>=0)
    	{
    		j--;
    		i--;		
    	}
    	
    	while(array[i][j]==spieler && j<=spalte && i<=zeile)
    	{
    		j++;
    		i++;	
    		gewinnz++;
    		if (gewinnz>=1)
    		{
    			printf ("Gewonnen %c\n",spieler);
    			exit(0);
    		}
    	}
    	return(0);
    }
    

    Was soll die zweite Schleife in dieser Funktion? Sie wird maximal ein einziges Mal betreten, weil gewinnz sofort von 0 auf 1 hochgezählt wird und damit die Schleife mit "gewonnen" verlassen wird.
    Mal angenommen:

    int gewinndiag1(char array[ARRAY_ZEILE][ARRAY_SPALTE], int zeile, int spalte, char spieler)
    

    zeile, spalte zeigt auf den Platz, an den spieler seinen letzten Stein gelegt hat, dann würde mM Deine erste Schleife

    int gewinnz=0;
    	while(array[zeile][spalte]==spieler && zeile>=0 && spalte>=0)
    	{
    		zeile--;
    		spalte--;		
    	}
    

    ausreichen, wenn Du sie um gewinnz++ erweiterst und am Schleifenende prüfst, ob gewinnz größer als 3 geworden ist.



  • oh sorry:/ gewinnz also der zähler ist sonst auf 4^^ hab da bloß wild rumprobiert weil ich langsam keinen plan mehr habe was ich machen soll.

    also sonst steht da schon ne 4 drinn
    und ich glaube du brauchst, wenn man es so löst, auf jedenfall 2 schleifen. denn wenn du die steine in die mitte setzt
    oooX
    oo
    oX
    X

    also da wo jetzt nix steht den letzten stein hinsetzt, musst du ja in 2 richtungen zählen um alle steine zu erwischen.

    @ mark-o: ich hab auch schon versucht nach der 1. schleife auf die ausgangsposition zurückzugehen (hab ich gelöst indem ich auf i und j den wert des gewinnz zähler addiert bzw subtrahiert habe...zwar nicht elegant aber sollte eigentlich funktionieren....eigentlich



  • Noch ein Problem:
    Wenn array[0][0]==spieler ist werden i und j zu -1.

    while(j>0 && i>0 && array[i-1][j-1]==spieler) // Wenn j<=0 und/oder i<=0 wird array[i-1][j-1] gar nicht erst ausgewertet.
        {
            j--;
            i--;       
        }
    


  • Thörb schrieb:

    oh sorry:/ gewinnz also der zähler ist sonst auf 4^^ hab da bloß wild rumprobiert weil ich langsam keinen plan mehr habe was ich machen soll.

    also sonst steht da schon ne 4 drinn
    und ich glaube du brauchst, wenn man es so löst, auf jedenfall 2 schleifen. denn wenn du die steine in die mitte setzt
    oooX
    oo
    oX
    X

    also da wo jetzt nix steht den letzten stein hinsetzt, musst du ja in 2 richtungen zählen um alle steine zu erwischen.

    Ja, das stimmt allerdings ... also Ausgangsposition merken und einmal runter zählen, wenn gewinnz dann kleiner 4 ist, ab Ausgangsposition hoch zählen, Ausgangsposition beim hochzählen nicht mehr mitrechnen, weil sonst doppelt.



  • Hey,

    ich hab gestern noch mal ca. 3h fehler gesucht. Sowohl am rechner als auch am Papier. Ich hab keinen mehr gefunden.

    Wie kann es denn sein dass das Spiel bei mir hier nicht läuft, also die beiden abfragen nicht Funktionieren, und bei meinem Kumpel aufm Rechner schon??
    Das macht für mich keinen Sinn, ich habs gestern auf dem Rechner meines Freundes gespiel, und hier auf der Arbeit gehts nüch-.-

    Ich hab euch hier mal den gesamten Code hochgeladen. Wer lust und Zeit hat kann ja mal schauen. Da ich noch nicht sooo lang programmiere ist der Stil vielleicht nicht der schönste:P
    http://www.file-upload.net/download-3325658/viergewinnt.c.html

    Danke übrigens an die Vorposter für die Hilfe 🙂



  • Thörb schrieb:

    Wie kann es denn sein dass das Spiel bei mir hier nicht läuft, also die beiden abfragen nicht Funktionieren, und bei meinem Kumpel aufm Rechner schon??
    Das macht für mich keinen Sinn, ich habs gestern auf dem Rechner meines Freundes gespiel, und hier auf der Arbeit gehts nüch-.-

    Tja, da gehörst du aber zur Minderheit, die sowas stört.
    Das Ganze nennt sich Portabilität bzw. Plattformunabhängigkeit und den meisten Anfängern hier reicht es, wenn ihr Programm auf ihrer Plattform und mit ihrer Compilerversion funktioniert.
    Halte dich an Standards, dann garantieren dir standardkonforme Entwicklungswerkzeuge auch die gewünschte unabhängige Arbeitsweise.
    Konkret:
    programmiere strikt konformes ANSI C (89) und du erreichst damit maximale Plattformunabhängigkeit.

    Lade deinen Code auf codepad.org bzw. ideone.com, da kann man Code halbwegs vernünftig ansehen.



  • http://codepad.org/0m1btPfy
    hier der Link. Bin immer noch nicht weiter...jetzt soll ich das Teil mit Qt aufbauen...ich glaube die wollen mcih fertig machen^



  • - du hast die Compilerwarnungen ignoriert
    - warum verwendest du float? (statt durchgängig int)
    - die Funktion pruef1 gibt die dort abgefragten Werte NICHT an den aufrufenden Kontext weiter
    - die Abfrage von 2 Zahlenwerten aus einer Zeile macht man anders richtig
    - ...
    Auch habe ich nicht verstanden, warum du 2 Computer und 2 Spieler benötigst.
    <edit> jetzt habe ich es verstanden.



  • Aber bis zu den Gewinnabfragen stimmen die Variablen und Werte.
    Das mit dem float kann ich ändern stimmt. Macht ja eigentlich keinen Sinn.
    Und für die Abfrage mit den 2 Werten gleichzeitig ist mir nix anderes eingefallen. Damit will ich nur verhindern das man keine Kommazahlen einlesen kann. (Ist nicht schön, funktioniert aber)
    Das mit der funktion pruef1 hab ich noch nicht ganz verstanden, also was du meinst.



  • Eigentlich muss doch Zeilen == Spalten gelten?
    Dann reicht auch die Abfrage nach einer Zahl (zu Beginn).
    Hier mal eine Variante zum Einlesen zweier Zahlen (int):

    void lies2int(int *a,int *b)
    {
      while( printf("Gib 2 Zahlen ein (getrennt mit Leerzeichen): "), 2!=scanf("%d%d",a,b) ) while( getchar()!='\n' );
      while( getchar()!='\n' );
    }
    

    Hier mal eine einfache Lösung:

    http://www.ideone.com/SawLP


Anmelden zum Antworten