Frage zu Gewinnbedingung 4-gewinnt
-
Hi,
ich hab folgendes 4-Gewinnt-Spiel geschrieben. Es läuft alles wunderbar, nur die Gewinnbedingung funktioniert einfach gar nicht. Kann mir da jemand helfen? Hier ist der Code:
#include <stdio.h> #include "eingabe.h" #include <stdlib.h> void initialisiere_2dim_int_array(int zeilen, int spalten, int array[zeilen][spalten], int initialwert); void initialisiere_int_array(int array[], int laenge, int initialwert); void anzeige(int zeilen, int spalten, int spielfeld[zeilen][spalten]); int setze(int zeilen, int spalten, int spielfeld[zeilen][spalten], int auswahl, int spieler, char wert); int ueberpruefe_siegbedingung(int zeilen, int spalten, int spielfeld[zeilen][spalten]); void schreibe_2dim_int_array(int zeilen, int spalten, int array[zeilen][spalten]); void schreibe_int_array(int array[], int laenge); int main(void) { int spieler_1 = 1; int spieler_2 = 2; printf("Bitte die Anzahl der Spalten waehlen [7-9]: "); int spalten = erfasse_ganze_zahl(7, 9); printf("Bitte die Anzahl der Zeilen waehlen [6-9]: "); int zeilen = erfasse_ganze_zahl(6, 9); int spielfeld[zeilen][spalten]; int laenge = sizeof(spielfeld) / sizeof(spielfeld[0]); initialisiere_2dim_int_array(zeilen, spalten, spielfeld, 0); int gewonnen = 0; int spieler = 1; int wert = 0; int erfolg = 0; int sieg = 0; int auswahl = 0; while(gewonnen == 0) { switch(spieler) { case 1: anzeige(zeilen, spalten, spielfeld); auswahl = erfasse_ganze_zahl(0, spalten); erfolg = setze(zeilen, spalten, spielfeld, auswahl, 1, 120); if(erfolg == -1) { printf("Fehler, Zug ist nicht moeglich, bitte probieren sie es nochmal\n"); break; } sieg = ueberpruefe_siegbedingung(zeilen, spalten, spielfeld); if(sieg == 1) { printf("check\n"); return 0; } printf("Spieler 1 ist an der Reihe: \nSpalte auswaehlen, in die der Spielstein geworfen werden soll: \n"); spieler = 2; break; case 2: anzeige(zeilen, spalten, spielfeld); auswahl = erfasse_ganze_zahl(0, spalten); erfolg = setze(zeilen, spalten, spielfeld, auswahl, 1, 111); if(erfolg == -1) { printf("Fehler, Zug ist nicht moeglich, bitte probieren sie es nochmal\n"); break; } sieg = ueberpruefe_siegbedingung(zeilen, spalten, spielfeld); if(sieg == 1) { printf("check\n"); return 0; } printf("Spieler 2 ist an der Reihe: \nSpalte auswaehlen, in die der Spielstein geworfen werden soll: \n"); spieler = 1; break; } } return 0; } int setze(int zeilen, int spalten, int spielfeld[zeilen][spalten], int auswahl, int spieler, char wert) { auswahl--; for (int i = spalten - 1; i >= 0; i--) { if(spielfeld[i][auswahl] == 0) { spielfeld[i][auswahl] = wert; return 0; } } return -1; } void initialisiere_2dim_int_array(int zeilen, int spalten, int array[zeilen][spalten], int initialwert) { for (int i = 0; i < zeilen; i++) initialisiere_int_array(array[i], spalten, initialwert); } void initialisiere_int_array(int array[], int laenge, int initialwert) { for (int i = 0; i < laenge; i++) array[i] = initialwert; } void schreibe_2dim_int_array(int zeilen, int spalten, int array[zeilen][spalten]) { for (int i = 0; i < zeilen; i++) schreibe_int_array(array[i], spalten); } void schreibe_int_array(int array[], int laenge) { for (int i = 0; i < laenge; i++) printf("%d, ", array[i]); } void anzeige(int zeilen, int spalten, int spielfeld[zeilen][spalten]) { int i, j, k = 0; for(i = 0; i < spalten; i++) { for(j = 0; j < zeilen; j++) { printf("%c", spielfeld[i][j]); printf(" | "); if (j == zeilen - 1) { printf("\n"); for (k = 0; k < spalten; k++) printf("----"); printf("\n"); } } } } int ueberpruefe_siegbedingung(int zeilen, int spalten, int spielfeld[zeilen][spalten]) { int vertikal = 1;//(|) int horizontal = 1;//(-) int diagonal1 = 1;//(\) int diagonal2 = 1;//(/) char spieler = spielfeld[zeilen][spalten]; int i; int j;//horizontal //check for vertikal(|) for(i = 0; spielfeld[i][spalten] == spieler && i <= zeilen; i++) vertikal++;//Check down printf("\n%d, %d\n\n%d, %d\n", vertikal, horizontal, diagonal1, diagonal2); for(i = zeilen; spielfeld[i][spalten] == spieler && i >= 0; i--) vertikal++;//Check up printf("\n%d, %d\n\n%d, %d\n", vertikal, horizontal, diagonal1, diagonal2); if(vertikal >= 4) return 1; //check for horizontal(-) for(j = spalten -1; spielfeld[zeilen][j] == spieler && j >= 0; j--,horizontal++);//Check left for(j = spalten +1; spielfeld[zeilen][j] == spieler && j <= 6; j++,horizontal++);//Check right if(horizontal >= 4) return 1; //check for diagonal 1 (\) for(i = zeilen -1, j = spalten - 1; spielfeld[i][j] == spieler && i >= 0 && j >= 0; diagonal1 ++, i --, j --);//up and left for(i = zeilen +1, j = spalten + 1; spielfeld[i][j] == spieler && i <= 5 && j <= 6; diagonal1 ++, i ++, j ++);//down and right if(diagonal1 >= 4) return 1; //check for diagonal 2(/) for(i = zeilen -1, j= spalten +1;spielfeld[i][j] == spieler && i>=0 && j <= 6; diagonal2 ++, i --, j ++);//up and right for(i = zeilen +1, j= spalten -1;spielfeld[i][j] == spieler && i<=5 && j >=0; diagonal2 ++, i ++, j --);//up and left if(diagonal2 >= 4) return 1; printf("\n%d, %d\n\n%d, %d\n", vertikal, horizontal, diagonal1, diagonal2); return 0; }
und hier die eingabe:
int erfasse_ganze_zahl(int min, int max) { int zahl = 0; char eingabe = '\0'; while (scanf("%d", &zahl) != 1 || zahl < min || zahl > max) { while ((eingabe = getchar()) != EOF && eingabe != '\n'); printf("Bitte geben Sie eine positive Zahl zwischen %d und %d ein:",min, max); } return zahl; }
-
Erstmal zu
erfasse_ganze_zahl
Das EOF liegt ausserhalb des Wertebereichs eines char.
Damit das funktioniert muss eingabe einint
sein.So wie du es aufrufst, kann du dort als Maximalwert auch den Wert von spalten/zeilen eingeben. Der liegt dann aber ausserhalb von deinem Array.
Jetzt zu eingabe überprüfen:
Du hast:
[url]for(j = spalten -1; spielfeld[zeilen][j] == spieler && j >= 0; j--,horizontal++);//Check left
[/url] Da gibt es zwei Probleme:
Du hast spielfeld als Array mit zeilen*spalten Elemente Definiert.
Ein Element an der Position spielfeld[zeilen][?] bzw. spielfeld[?][spalten] existiert aber nicht.Angenommen du bist mit dem Durchlauf fertig, wo j 0 ist.
Dann kommt j-- (j ist also -1) und du kommst in die Überprüfung der Schleifenbedingung. Dann steht da:spielfeld[zeilen][-1] == ...
Negativer Index ist selten gut.
Das kannst du aber umgehen indem du die Bedingung umstellst :...; j >= 0 && spielfeld[zeilen][j] == spieler; ...
Da die Bedingung schon nach
j >= 0
nicht mehr erfüllt werden kann, wird der Rest nicht mehr geprüft.Und schau mal bei deinem
switch(spieler)
.
Die Fälle unterscheiden sich in an 2 Stellen (die Siegmitteilung zähle ich nicht mit wegenprintf("Spieler %d gewonn", spieler);
)
Das kannst du zusammenfassen. Ganz ohne switch.Welchen Compiler benutzt du denn?
VLA in Funktionsparamtern kannte ich noch nicht.
-
Deine komplette Überprüfung sehr merkwürdig.
int j;//horizontal //check for vertikal(|) for(i = 0; spielfeld[i][spalten] == spieler && i <= zeilen; i++) vertikal++;//Check down printf("\n%d, %d\n\n%d, %d\n", vertikal, horizontal, diagonal1, diagonal2); for(i = zeilen; spielfeld[i][spalten] == spieler && i >= 0; i--) vertikal++;//Check up printf("\n%d, %d\n\n%d, %d\n", vertikal, horizontal, diagonal1, diagonal2); if(vertikal >= 4) return 1;
Du überprüfst dort zweimal (einmal hoch und dann runter) eine Spalte, die noch nicht einmal esistiert.
Dann schaust du nur nach ob es 4 Stein von deinem Spieler in der Zeile gibt.
Dabei ist es dir auch egal ob die nebeneinander liegen oder nicht.