Brauche dringend Hilfe zu meinem Code



  • Hallo, ich muss ein Tic Tac Toe Spiel programmieren, aber das klappt nicht so richtig, und es ist total deprimierend, wenn du einfach nicht weiterkommst

    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    
    char Spielfeld [9];
    char Feldname [3];
    int punkteSpieler1 = 0;
    int punkteSpieler2 = 0;
    int zug = 1;
    
    void Spielfeldaufbau ()
    {
    	system("cls");
    		printf("        A         B         C\n");
    		printf("   %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%cPlayer 1: %d Punkte\n", 201/*Ecke*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,203/*oberes Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,203/*oberes Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,187/*Ecke*/, 9, 9, punkteSpieler1);
    		printf("   %c         %c         %c         %c%c%cPlayer 2: %d Punkte\n", 186,186,186,186, 9, 9, punkteSpieler2);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf(" 1 %c    %c    %c    %c    %c    %c    %c\n", 186, Spielfeld[0], 186, Spielfeld[1], 186, Spielfeld[2], 186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 204/*linkes Mittelstück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,206/*Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,206/*Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,185/*rechtes Mittelstück*/);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf(" 2 %c    %c    %c    %c    %c    %c    %c\n", 186, Spielfeld[3], 186, Spielfeld[4], 186, Spielfeld[5], 186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 204/*linkes Mittelstück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,206/*Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,206/*Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,185/*rechtes Mittelstück*/);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf(" 3 %c    %c    %c    %c    %c    %c    %c\n", 186, Spielfeld[6], 186, Spielfeld[7], 186, Spielfeld[8], 186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n\n", 200/*linkes Mittelstück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,202/*unteres Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,202/*unteres Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,188/*Ecke*/);
    }
    
    int Gewinnbedingung ()
    {
    	if ((Spielfeld [0] == 'X' && Spielfeld [1] == 'X' && Spielfeld [2] == 'X') ||		// waagrechte Gewinnbedingung
    		(Spielfeld [3] == 'X' && Spielfeld [4] == 'X' && Spielfeld [5] == 'X') ||
    		(Spielfeld [6] == 'X' && Spielfeld [7] == 'X' && Spielfeld [8] == 'X') ||
    		(Spielfeld [0] == 'X' && Spielfeld [4] == 'X' && Spielfeld [8] == 'X') ||		// diagonale Gewinnbedingung
    		(Spielfeld [2] == 'X' && Spielfeld [4] == 'X' && Spielfeld [6] == 'X') ||
    		(Spielfeld [0] == 'X' && Spielfeld [3] == 'X' && Spielfeld [6] == 'X') ||		// senkrechte Gewinnbedingung
    		(Spielfeld [1] == 'X' && Spielfeld [4] == 'X' && Spielfeld [7] == 'X') ||
    		(Spielfeld [2] == 'X' && Spielfeld [5] == 'X' && Spielfeld [8] == 'X'))
    	{return 1;} //Spieler 1 hat gewonnen
    
    	else if ((Spielfeld [0] == 'X' && Spielfeld [1] == 'X' && Spielfeld [2] == 'X') ||		// waagrechte Gewinnbedingung
    		(Spielfeld [3] == 'X' && Spielfeld [4] == 'X' && Spielfeld [5] == 'X') ||
    		(Spielfeld [6] == 'X' && Spielfeld [7] == 'X' && Spielfeld [8] == 'X') ||
    		(Spielfeld [0] == 'X' && Spielfeld [4] == 'X' && Spielfeld [8] == 'X') ||		// diagonale Gewinnbedingung
    		(Spielfeld [2] == 'X' && Spielfeld [4] == 'X' && Spielfeld [6] == 'X') ||
    		(Spielfeld [0] == 'X' && Spielfeld [3] == 'X' && Spielfeld [6] == 'X') ||		// senkrechte Gewinnbedingung
    		(Spielfeld [1] == 'X' && Spielfeld [4] == 'X' && Spielfeld [7] == 'X') ||
    		(Spielfeld [2] == 'X' && Spielfeld [5] == 'X' && Spielfeld [8] == 'X'))
    	{return 2;} //Spieler 2 hat gewonnen
    	else 
    	{return 0;} //niemand hat gewonnen
    }
    
    int Feldnameumwandeln()								
    {
    	if (zug == 1)
    	{
    		if ((Feldname[0] == 'A') && (Feldname[1] == '1') && (Spielfeld[0] == NULL))	
    			{Spielfeld[0] = 'X';return 1;}
    		if ((Feldname[0] == 'A') && (Feldname[1] == '2') && (Spielfeld[3] == NULL))
    			{Spielfeld[3] = 'X';return 1;}
    		if ((Feldname[0] == 'A') && (Feldname[1] == '3') && (Spielfeld[6] == NULL))
    			{Spielfeld[6] = 'X';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '1') && (Spielfeld[1] == NULL))
    			{Spielfeld[1] = 'X';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '2') && (Spielfeld[4] == NULL))
    			{Spielfeld[4] = 'X';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '3') && (Spielfeld[7] == NULL))
    			{Spielfeld[7] = 'X';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '1') && (Spielfeld[2] == NULL))
    			{Spielfeld[2] = 'X';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '2') && (Spielfeld[5] == NULL))
    			{Spielfeld[5] = 'X';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '3') && (Spielfeld[8] == NULL))
    			{Spielfeld[8] = 'X';return 1;}
    	}
    
    	if (zug == 2)
    	{
    		if ((Feldname[0] == 'A') && (Feldname[1] == '1') && (Spielfeld[0] == NULL))	
    			{Spielfeld[0] = 'O';return 1;}
    		if ((Feldname[0] == 'A') && (Feldname[1] == '2') && (Spielfeld[3] == NULL))
    			{Spielfeld[3] = 'O';return 1;}
    		if ((Feldname[0] == 'A') && (Feldname[1] == '3') && (Spielfeld[6] == NULL))
    			{Spielfeld[6] = 'O';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '1') && (Spielfeld[1] == NULL))
    			{Spielfeld[1] = 'O';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '2') && (Spielfeld[4] == NULL))
    			{Spielfeld[4] = 'O';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '3') && (Spielfeld[7] == NULL))
    			{Spielfeld[7] = 'O';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '1') && (Spielfeld[2] == NULL))
    			{Spielfeld[2] = 'O';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '2') && (Spielfeld[5] == NULL))
    			{Spielfeld[5] = 'O';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '3') && (Spielfeld[8] == NULL))
    			{Spielfeld[8] = 'O';return 1;}
    	}
    	else {return 0;} //ungültiger Feldname
    }
    
    void Spielzug()
    {
    	do 
    	{
    		if (zug == 1)
    		{
    			do 
    			{
    				printf ("Spieler 1(X) ist am Zug. Geben Sie ein Feld ein (z.B. A2): ");
    				scanf ("%2s", Feldname);
    				Spielfeldaufbau ();
    			}
    			while (Feldnameumwandeln() == 0);
    		}
    		Spielfeldaufbau ();
    		zug = 2;
    		if (zug == 2)
    		{
    			do 
    			{
    				printf ("Spieler 2(O) ist am Zug. Geben Sie ein Feld ein (z.B. A2): ");
    				scanf ("%2s", Feldname);
    				Spielfeldaufbau();
    
    			}
    			while (Feldnameumwandeln() == 0);
    		zug =1;
    		Spielfeldaufbau ();
    		}
    	}
    	while (1<2);
    }
    
    int main ()
    {
    	char neuesSpiel;
    
    	/*do
    	{*/
    	Spielfeldaufbau();
    	Spielzug();
    
    		scanf ("%c", &neuesSpiel);
    	/*}
    	while ((neuesSpiel == 'j') || (neuesSpiel != 'n'));*/
    }
    

    Also ich bin momentan dabei den Spielzug zu programmieren, dass die Spieler nacheinander, das gewünschte Feld eingeben können, und dass dann ein X bzw O dahin geschrieben wird. Wenn man ein Freies Feld eingibt funktioniert alles gut, bei Spieler 1 kann man auch ein belegtes Feld angeben

    do 
    			{
    				printf ("Spieler 1(X) ist am Zug. Geben Sie ein Feld ein (z.B. A2): ");
    				scanf ("%2s", Feldname);
    				Spielfeldaufbau ();
    			}
    			while (Feldnameumwandeln() == 0);
    

    Hier die Schleife funktioniert, sobald man ein belegtes Feld eingibt, soll man nochmal eins eingeben.
    JETZT KOMMT MEIN PROBLEM:
    Die Schleife von Spieler 2 funktioniert NICHT, diese:

    do 
    			{
    				printf ("Spieler 2(O) ist am Zug. Geben Sie ein Feld ein (z.B. A2): ");
    				scanf ("%2s", Feldname);
    				Spielfeldaufbau();
    
    			}
    			while (Feldnameumwandeln() == 0);
    

    Ich versteh das einfach nicht, es ist doch alles gleich 😞 ich bin am verzweifeln, falls ihr wisst woran das liegt, könnt ihr mir bitte sagen was ich falsch gemacht habe, am besten so verständlich wie es geht, bin noch Anfänger.



  • if ((Feldname[0] == 'A') && (Feldname[1] == '1') && (Spielfeld[0] == NULL))
    

    DA GEHÖRT KEINE NULL HIN!
    Da ich noch keine Ahnung habe, was Feldnameumwandeln bewirken soll, kann ich's nicht reparieren.

    char Spielfeld [9];
    char Feldname [3];
    int punkteSpieler1 = 0;
    int punkteSpieler2 = 0;
    int zug = 1;
    

    Globale Variablen sind pöse.

    void Spielfeldaufbau()
    …//Das quote ich nichtmal
    

    Es gibt kleinere Einheiten als das ganze Spielfeld auf einmal zu zeichnen.

    int Gewinnbedingung() {
    	if((Spielfeld [0] == 'X' && Spielfeld [1] == 'X' && Spielfeld [2] == 'X') ||        // waagrechte Gewinnbedingung
    			(Spielfeld [3] == 'X' && Spielfeld [4] == 'X' && Spielfeld [5] == 'X') ||
    			(Spielfeld [6] == 'X' && Spielfeld [7] == 'X' && Spielfeld [8] == 'X') ||
    			(Spielfeld [0] == 'X' && Spielfeld [4] == 'X' && Spielfeld [8] == 'X') ||       // diagonale Gewinnbedingung
    			(Spielfeld [2] == 'X' && Spielfeld [4] == 'X' && Spielfeld [6] == 'X') ||
    			(Spielfeld [0] == 'X' && Spielfeld [3] == 'X' && Spielfeld [6] == 'X') ||       // senkrechte Gewinnbedingung
    			(Spielfeld [1] == 'X' && Spielfeld [4] == 'X' && Spielfeld [7] == 'X') ||
    			(Spielfeld [2] == 'X' && Spielfeld [5] == 'X' && Spielfeld [8] == 'X')) {
    		return 1;   //Spieler 1 hat gewonnen
    	}
    
    	else if((Spielfeld [0] == 'X' && Spielfeld [1] == 'X' && Spielfeld [2] == 'X') ||       // waagrechte Gewinnbedingung
    			(Spielfeld [3] == 'X' && Spielfeld [4] == 'X' && Spielfeld [5] == 'X') ||
    			(Spielfeld [6] == 'X' && Spielfeld [7] == 'X' && Spielfeld [8] == 'X') ||
    			(Spielfeld [0] == 'X' && Spielfeld [4] == 'X' && Spielfeld [8] == 'X') ||       // diagonale Gewinnbedingung
    			(Spielfeld [2] == 'X' && Spielfeld [4] == 'X' && Spielfeld [6] == 'X') ||
    			(Spielfeld [0] == 'X' && Spielfeld [3] == 'X' && Spielfeld [6] == 'X') ||       // senkrechte Gewinnbedingung
    			(Spielfeld [1] == 'X' && Spielfeld [4] == 'X' && Spielfeld [7] == 'X') ||
    			(Spielfeld [2] == 'X' && Spielfeld [5] == 'X' && Spielfeld [8] == 'X')) {
    		return 2;   //Spieler 2 hat gewonnen
    	}
    	else {
    		return 0;   //niemand hat gewonnen
    	}
    }
    

    Bin verwirrt. Beide Spieler haben 'X'?

    int Feldnameumwandeln() {
    	if(zug == 1) {
    		…
    	}
    	if(zug == 2) {
    		…
    	}
    	else {//???
    		…
    	}
    }
    

    Was genau macht dieses else da? Das sieht doch gleich oberschuldig aus, so asymmetrisch, wie es da rumlungert, an den zweiten Spieler gebunden, aber an den ersten nicht, direkt unästetisch.



  • Das Feldnameumwandeln bewirkt, das der string also das B1, A2 oder wasauchimmer
    erkannt wird, und jenachdem was man halt eingegeben hat wird dann halt das X in das jeweilige Spielfeld geschrieben

    Wieso gehört da keine NULL hin ? ich hab mir gedacht, dass der da halt nur reinschreibt wenn es NULL ist, so wird zum Beispiel das X nicht überschrieben, wenn Spieler 2 das gleiche Feld macht, funktioniert auch so eigentlich

    und wieso sind die globalen variablen schlecht ? dann muss man die doch nicht übergeben oder net ?

    Ja, bei dem Gewinnbedingung das ist ein Fail xD, der andere spielt mit 'O'

    ps Ich bin jetzt schon voll weit gekommen 😃 kann ja nochmal mein code posten

    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    
    char Spielfeld [9];
    char Feldname [3];
    int punkteSpieler1 = 0;
    int punkteSpieler2 = 0;
    int zug = 1;
    
    void Spielfeldaufbau ()
    {
    	system("cls");
    		printf("        A         B         C\n");
    		printf("   %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%cPlayer 1: %d Punkte\n", 201/*Ecke*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,203/*oberes Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,203/*oberes Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,187/*Ecke*/, 9, 9, punkteSpieler1);
    		printf("   %c         %c         %c         %c%c%cPlayer 2: %d Punkte\n", 186,186,186,186, 9, 9, punkteSpieler2);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf(" 1 %c    %c    %c    %c    %c    %c    %c\n", 186, Spielfeld[0], 186, Spielfeld[1], 186, Spielfeld[2], 186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 204/*linkes Mittelstück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,206/*Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,206/*Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,185/*rechtes Mittelstück*/);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf(" 2 %c    %c    %c    %c    %c    %c    %c\n", 186, Spielfeld[3], 186, Spielfeld[4], 186, Spielfeld[5], 186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 204/*linkes Mittelstück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,206/*Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,206/*Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,185/*rechtes Mittelstück*/);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf(" 3 %c    %c    %c    %c    %c    %c    %c\n", 186, Spielfeld[6], 186, Spielfeld[7], 186, Spielfeld[8], 186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c         %c         %c         %c\n", 186,186,186,186);
    		printf("   %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n\n", 200/*linkes Mittelstück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,202/*unteres Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,202/*unteres Mittelsück*/,205,205,205,205,205,205,205,205,205/*9 Geraden*/,188/*Ecke*/);
    }
    
    int Gewinnbedingung ()
    {
    	if 
    		((Spielfeld [0] == 'X' && Spielfeld [1] == 'X' && Spielfeld [2] == 'X') ||		// waagrechte Gewinnbedingung
    		(Spielfeld [3] == 'X' && Spielfeld [4] == 'X' && Spielfeld [5] == 'X') ||
    		(Spielfeld [6] == 'X' && Spielfeld [7] == 'X' && Spielfeld [8] == 'X') ||
    		(Spielfeld [0] == 'X' && Spielfeld [4] == 'X' && Spielfeld [8] == 'X') ||		// diagonale Gewinnbedingung
    		(Spielfeld [2] == 'X' && Spielfeld [4] == 'X' && Spielfeld [6] == 'X') ||
    		(Spielfeld [0] == 'X' && Spielfeld [3] == 'X' && Spielfeld [6] == 'X') ||		// senkrechte Gewinnbedingung
    		(Spielfeld [1] == 'X' && Spielfeld [4] == 'X' && Spielfeld [7] == 'X') ||
    		(Spielfeld [2] == 'X' && Spielfeld [5] == 'X' && Spielfeld [8] == 'X'))
    	{return 1;} //Spieler 1 hat gewonnen	
    
    	 if ((Spielfeld [0] == 'O' && Spielfeld [1] == 'O' && Spielfeld [2] == 'O') ||		// waagrechte Gewinnbedingung
    		(Spielfeld [3] == 'O' && Spielfeld [4] == 'O' && Spielfeld [5] == 'O') ||
    		(Spielfeld [6] == 'O' && Spielfeld [7] == 'O' && Spielfeld [8] == 'O') ||
    		(Spielfeld [0] == 'O' && Spielfeld [4] == 'O' && Spielfeld [8] == 'O') ||		// diagonale Gewinnbedingung
    		(Spielfeld [2] == 'O' && Spielfeld [4] == 'O' && Spielfeld [6] == 'O') ||
    		(Spielfeld [0] == 'O' && Spielfeld [3] == 'O' && Spielfeld [6] == 'O') ||		// senkrechte Gewinnbedingung
    		(Spielfeld [1] == 'O' && Spielfeld [4] == 'O' && Spielfeld [7] == 'O') ||
    		(Spielfeld [2] == 'O' && Spielfeld [5] == 'O' && Spielfeld [8] == 'O'))
    	 {return 2;} //Spieler 2 hat gewonnen
    	else
    	{return 0;} //niemand hat gewonnen
    }
    
    int Feldnameumwandeln()								
    {
    	if (zug == 1)			//Die Eingabe von Spieler 1 wird überprüft und in ein Spielfeld geschrieben
    	{
    		if ((Feldname[0] == 'A') && (Feldname[1] == '1') && (Spielfeld[0] == NULL))	
    			{Spielfeld[0] = 'X';return 1;}
    		if ((Feldname[0] == 'A') && (Feldname[1] == '2') && (Spielfeld[3] == NULL))
    			{Spielfeld[3] = 'X';return 1;}
    		if ((Feldname[0] == 'A') && (Feldname[1] == '3') && (Spielfeld[6] == NULL))
    			{Spielfeld[6] = 'X';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '1') && (Spielfeld[1] == NULL))
    			{Spielfeld[1] = 'X';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '2') && (Spielfeld[4] == NULL))
    			{Spielfeld[4] = 'X';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '3') && (Spielfeld[7] == NULL))
    			{Spielfeld[7] = 'X';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '1') && (Spielfeld[2] == NULL))
    			{Spielfeld[2] = 'X';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '2') && (Spielfeld[5] == NULL))
    			{Spielfeld[5] = 'X';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '3') && (Spielfeld[8] == NULL))
    			{Spielfeld[8] = 'X';return 1;}
    	}
    
    	if (zug == 2)			//Die Eingabe von Spieler 2 wird überprüft und in ein Spielfeld geschrieben
    
    		if ((Feldname[0] == 'A') && (Feldname[1] == '1') && (Spielfeld[0] == NULL))	
    			{Spielfeld[0] = 'O';return 1;}
    		if ((Feldname[0] == 'A') && (Feldname[1] == '2') && (Spielfeld[3] == NULL))
    			{Spielfeld[3] = 'O';return 1;}
    		if ((Feldname[0] == 'A') && (Feldname[1] == '3') && (Spielfeld[6] == NULL))
    			{Spielfeld[6] = 'O';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '1') && (Spielfeld[1] == NULL))
    			{Spielfeld[1] = 'O';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '2') && (Spielfeld[4] == NULL))
    			{Spielfeld[4] = 'O';return 1;}
    		if ((Feldname[0] == 'B') && (Feldname[1] == '3') && (Spielfeld[7] == NULL))
    			{Spielfeld[7] = 'O';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '1') && (Spielfeld[2] == NULL))
    			{Spielfeld[2] = 'O';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '2') && (Spielfeld[5] == NULL))
    			{Spielfeld[5] = 'O';return 1;}
    		if ((Feldname[0] == 'C') && (Feldname[1] == '3') && (Spielfeld[8] == NULL))
    			{Spielfeld[8] = 'O';return 1;}	
    	else {printf ("Ungueltige Eingabe oder Feld bereits belegt\n"); return 0;} //ungültiger Feldname
    }
    
    int Spielzug()
    {
    	do 
    	{
    		if (zug == 1)
    		{
    			do								//Spielzug von Spieler 1
    			{
    				printf ("Spieler 1(X) ist am Zug. Geben Sie ein Feld ein (z.B. A2): ");		
    				scanf ("%2s", Feldname);
    				Spielfeldaufbau ();
    			}
    			while (Feldnameumwandeln() == 0);
    		zug = 2;
    		Spielfeldaufbau ();
    		}
    		if (Gewinnbedingung () == 1)		// Es wird nach Spielzug von Spieler 1 abgefragt, ob er die Gewinnbedingung erfüllt hat
    		{return 1;}
    		if (zug == 2)
    		{
    			do								//Spielzug von Spieler 2
    			{
    				printf ("Spieler 2(O) ist am Zug. Geben Sie ein Feld ein (z.B. A2): ");
    				scanf ("%2s", Feldname);
    				Spielfeldaufbau();	
    			}
    			while (Feldnameumwandeln() == 0);
    		zug =1;
    		Spielfeldaufbau ();
    		}
    	if (Gewinnbedingung () == 2)			// Es wird nach Spielzug von Spieler 2 abgefragt, ob er die Gewinnbedingung erfüllt hat
    	{return 2;}
    	}
    	while ((Gewinnbedingung() != 1) || (Gewinnbedingung() != 2));
    }
    
    int main ()
    {
    	char neuesSpiel;
    
    	/*do
    	{*/
    	Spielfeldaufbau();
    	Spielzug();
    	if (Spielzug () == 1)
    		{printf ("Spieler 1 hat gewonnen!");}
    	if (Spielzug () == 2 )
    		{printf ("Spieler 2 hat gewonnen!");}
    
    		scanf ("%c", &neuesSpiel);
    	/*}
    	while ((neuesSpiel == 'j') || (neuesSpiel != 'n'));*/
    }
    

    Aber bei der Gewinnbedingung, das stimmt irgendwas nicht, es kann nur spieler 1 gewinnen 😞 Bei Spieler 2 wird irgendwie nichts übergeben, wieder ein problem mit den blöden if Sachen da, die wollen bei mir nicht



  • Das else in Feldnameumwandeln ware falsch, oberschuldig. Wie gesagt, es band an den zweiten Spieler aber nicht an den ersten.
    Das hättest Du wegmachen sollen.

    Stattdessen haste es leben lassen und dafür das ganz lieb aussehende else in Gewinnbedingung weggemacht. Jenes band an beide Spieler, das ist auch hübsch.

    Nu haste beide Funktionen kaputt. 🤡



  • Spielzug() ist nicht symetrisch aufgebaut. Das

    zug = ;
            Spielfeldaufbau ();
    

    ist einmal im if-Zweig und einmal ausserhalb.

    Zum Rest:
    Keine globalen Variablen. Die sind hier absolut überflüssig.
    Da verlierst du den Überblick, wann und wo welche Funktion die benutzt.
    Ohne globale Variablen kannst du das Programm auch kompakter machen, da du gleichartige Teile in Funktionen zusammenfassen kannst. Denen übergibst du nur die Parameter

    Benutze Schleifen für die Gewinnerkennung und zähle dabei die O und X (oder 1 und 2 oder +1 und -1 oder SPIELER1 und SPIELER2)

    Berechne den Feldindex aus der Spalten-Zeilen-Angabe.

    #define FELDBREITE 3
    ...
    int setzeSpielzug(int Spielfeld[], char Feldname[], int aktSpieler)
    {
      unsigned int spalte, zeile, index;
    
      spalte = Feldname[0] - 'A';
      zeile  = Feldname[1] - '1';
      if (spalte < FELDBREITE && zeile < FELDBREITE ) 
      { // nur bei gültiger Eingabe
    
        index = zeile * FELDBREITE + spalte;
        if (Spielfeld[index] == 0)
        { Spielfeld[index ] = aktSpieler; 
          return 0;  // ok
        } 
        else
          return 2;  // Feld besetzt.
      }
      return 1;  // Fehler falsches Feld
    }
    

    Für die Rückgabewert nimmst du besser enums (oder #defines)

    Benutze Schleifen für die Gewinnerkennung und zähle dabei die O und X (oder 1 und 2 oder +1 und -1)

    int Gewinnbedingung (int Spielfeld[])
    { unsigned int spalte, zeile, index;
      int spieler1, spieler2;
    
    // Ueberprüfung der Spalten
      for (spalte = 0; spalte < FELDBREITE; spalte++)
      { spieler1 = 0;
        spieler2 = 0; 
        for (zeile = 0; zeile < FELDBREITE; zeile++)
        { index = zeile * FELDBREITE + spalte;
          if (Spielfeld[index] == SPIELER1) spieler1++;
          if (Spielfeld[index] == SPIELER2) spieler2++;
        }
        if (spieler1 ==  FELDBREITE) 
          return SPIELER1;     
        if (spieler1 ==  FELDBREITE) 
          return SPIELER1;   
      }
    
    // Ueberprüfung der Zeilen
    ... Code anpassen erst zeilen, dann spalten-Schleife
    
    // Ueberprüfung der ersten Diagonalen
      zeile = spalte;
    
    // Ueberprüfung der zweiten Diagonalen
       zeile = FELDBREITE -1 - spalte;
    }
    

    Das kann man auch kompakter machen

    Das Spielfeld kannst du auch mit Schleifen aufbauen.
    So eins mit den Rahmensymbolen ist aber erst am Ende nötig. vorher reicht | - + oder Leerzeichen.

    NULL steht für einen ungültigen Zeiger.
    Zeiger hast du aber nicht sondern char oder int. Dann nimm 0



  • Domooo93 schrieb:

    Das Feldnameumwandeln bewirkt, das der string also das B1, A2 oder wasauchimmer erkannt wird, und jenachdem was man halt eingegeben hat wird dann halt das X in das jeweilige Spielfeld geschrieben

    Ich hätte den Feldern die Namen '1' bis '9' gegeben in diesem Layout:
    789
    456
    123
    damit der Benutzer mit dem Ziffernblock ganz leichte und intuitive Eingabe hat.
    Und dazu

    char Spielfeld [10];//Spielfeld[0] wird einfach nicht benutzt, hihi
    

    Domooo93 schrieb:

    Wieso gehört da keine NULL hin?

    Weil NULL ein Zeiger ist und kein char. Ich hatte zum Testen '0' draus gemacht, natürlich muss das SPielfeld dann uch mit '0','0',… initialisiert werden. Sah aber kacke aus. Denke, ' ' wäre schlau.

    Domooo93 schrieb:

    ich hab mir gedacht, dass der da halt nur reinschreibt wenn es NULL ist, so wird zum Beispiel das X nicht überschrieben, wenn Spieler 2 das gleiche Feld macht, funktioniert auch so eigentlich

    Bei mir compiliert's nicht, aber ich habe auch alle Warnungen eingeschaltet und zu Fehlern erklärt. Solltest Du auch Dir irgendwann angewöhnen.

    Domooo93 schrieb:

    und wieso sind die globalen variablen schlecht ? dann muss man die doch nicht übergeben oder net?

    Jo, sparst Dir in der Tat ein wenig Tipperei. Ist auch jetzt ok. Aber später, wenn die Programme ein wenig komplexer werden, dann werden Dich die globalen Variablen umbringen.

    Domooo93 schrieb:

    wieder ein problem mit den blöden if Sachen da, die wollen bei mir nicht

    So Fehler kann man mit dem Debugger voll einfach finden, würde empfehlen, daß Du Dir anliest oder youtubest, wie man den Debugger bedient.



  • Spielzug() ist nicht symetrisch aufgebaut. Das

    zug = ;
            Spielfeldaufbau ();
    

    ist einmal im if-Zweig und einmal ausserhalb.

    Zum Rest:
    Keine globalen Variablen. Die sind hier absolut überflüssig.
    Da verlierst du den Überblick, wann und wo welche Funktion die benutzt.
    Ohne globale Variablen kannst du das Programm auch kompakter machen, da du gleichartige Teile in Funktionen zusammenfassen kannst. Denen übergibst du nur die Parameter

    Benutze Schleifen für die Gewinnerkennung und zähle dabei die O und X (oder 1 und 2 oder +1 und -1 oder SPIELER1 und SPIELER2)

    Berechne den Feldindex aus der Spalten-Zeilen-Angabe.

    #define FELDBREITE 3
    ...
    int setzeSpielzug(int Spielfeld[], char Feldname[], int aktSpieler)
    {
      unsigned int spalte, zeile, index;
    
      spalte = Feldname[0] - 'A';
      zeile  = Feldname[1] - '1';
      if (spalte < FELDBREITE && zeile < FELDBREITE ) 
      { // nur bei gültiger Eingabe
    
        index = zeile * FELDBREITE + spalte;
        if (Spielfeld[index] == 0)
        { Spielfeld[index ] = aktSpieler; 
          return 0;  // ok
        } 
        else
          return 2;  // Feld besetzt.
      }
      return 1;  // Fehler falsches Feld
    }
    

    Für die Rückgabewert nimmst du besser enums (oder #defines)

    Benutze Schleifen für die Gewinnerkennung und zähle dabei die O und X (oder 1 und 2 oder +1 und -1)

    int Gewinnbedingung (int Spielfeld[])
    { unsigned int spalte, zeile, index;
      int spieler1, spieler2;
    
    // Ueberprüfung der Spalten
      for (spalte = 0; spalte < FELDBREITE; spalte++)
      { spieler1 = 0;
        spieler2 = 0; 
        for (zeile = 0; zeile < FELDBREITE; zeile++)
        { index = zeile * FELDBREITE + spalte;
          if (Spielfeld[index] == SPIELER1) spieler1++;
          if (Spielfeld[index] == SPIELER2) spieler2++;
        }
        if (spieler1 ==  FELDBREITE) 
          return SPIELER1;     
        if (spieler1 ==  FELDBREITE) 
          return SPIELER1;   
      }
    
    // Ueberprüfung der Zeilen
    ... Code anpassen erst zeilen, dann spalten-Schleife
    
    // Ueberprüfung der ersten Diagonalen
      zeile = spalte;
    
    // Ueberprüfung der zweiten Diagonalen
       zeile = FELDBREITE -1 - spalte;
    }
    

    Das kann man auch noch kompakter machen

    Das Spielfeld kannst du auch mit Schleifen aufbauen.
    So eins mit den Rahmensymbolen ist aber erst am Ende nötig. Vorher reicht | - + oder Leerzeichen.

    NULL steht für einen ungültigen Zeiger.
    Zeiger hast du aber nicht sondern char oder int. Dann nimm 0

    ~Mein Code oben ist ungetestet und soll das Prinzip verdeutlichen.~



  • Sorry für Doppelpost 🙄



  • volkard schrieb:

    Stattdessen haste es leben lassen und dafür das ganz lieb aussehende else in Gewinnbedingung weggemacht. Jenes band an beide Spieler, das ist auch hübsch.

    Welches meinst du ? ich hab die beiden verglichen, also die Gewinnbedingung, da hab ich doch eigentlich nichts anders gemacht vom alten zum neuen code, die sind nur bisschen anderes eingerückt, aber die anweisungen + klammern sitzen doch gleich oder nicht
    übrigens Danke für die Hilfe 😉 hätte nicht gedacht, das mein post so früh schon gelesen wird



  • [quote="DirkB"]
    Benutze Schleifen für die Gewinnerkennung und zähle dabei die O und X (oder 1 und 2 oder +1 und -1)

    int Gewinnbedingung (int Spielfeld[])
    { unsigned int spalte, zeile, index;
      int spieler1, spieler2;
    
    // Ueberprüfung der Spalten
      for (spalte = 0; spalte < FELDBREITE; spalte++)
      { spieler1 = 0;
        spieler2 = 0; 
        for (zeile = 0; zeile < FELDBREITE; zeile++)
        { index = zeile * FELDBREITE + spalte;
          if (Spielfeld[index] == SPIELER1) spieler1++;
          if (Spielfeld[index] == SPIELER2) spieler2++;
        }
        if (spieler1 ==  FELDBREITE) 
          return SPIELER1;     
        if (spieler1 ==  FELDBREITE) 
          return SPIELER1;   
      }
    
    // Ueberprüfung der Zeilen
    ... Code anpassen erst zeilen, dann spalten-Schleife
    …Nicht angepasst, nur reinkopiert, um ein Gefühl für die Codegröße zu bekommen
      for (spalte = 0; spalte < FELDBREITE; spalte++)
      { spieler1 = 0;
        spieler2 = 0; 
        for (zeile = 0; zeile < FELDBREITE; zeile++)
        { index = zeile * FELDBREITE + spalte;
          if (Spielfeld[index] == SPIELER1) spieler1++;
          if (Spielfeld[index] == SPIELER2) spieler2++;
        }
        if (spieler1 ==  FELDBREITE) 
          return SPIELER1;     
        if (spieler1 ==  FELDBREITE) 
          return SPIELER1;   
      }
    
    // Ueberprüfung der ersten Diagonalen
      zeile = spalte;
    
    // Ueberprüfung der zweiten Diagonalen
       zeile = FELDBREITE -1 - spalte;
    }
    

    [/code]
    Nicht Dein Ernst.



  • Domooo93 schrieb:

    Gewinnbedingung, da hab ich doch eigentlich nichts anders gemacht vom alten zum neuen code, die sind nur bisschen anderes eingerückt, aber die anweisungen + klammern sitzen doch gleich oder nicht

    Das else von Zeile 48 ist verschwunden.

    Ist aber nicht dran schuld, da ist es egal, ob eins steht oder nicht. Der Fehler mit der Siegbedingung liegt woanders. Vielleicht in der Asymmetrie, die DirkB gefunden hat? Soo viele Orte, wo sich Fehler verstecken können, gibt's ja jetzt nicht in dem Programm.


Anmelden zum Antworten