XXO-Spiel



  • Hallo Leute,
    bin neu hier und habe auch schon ein kleines Problem 😃
    Hier ist mein kleines XXO (TicTacToe) Progrämmchen das ich unter MS Visual Studio erstellt habe.
    Das Problem ist nun folgendes, die getchar Anweisungen werden bei fast jedem Neuaufruf genau einmal ignoriert. Das Problem besteht auch weiterhin wenn ich sie durch Scanf ersetze.
    Vieleicht bin ich ja blind oder so, jedenfalls sehe ich den Fehler nicht. währe nett wenn mal jemand rüberschauen und mir das Problem schildern könnte. Die beiden Anweisungen sind in der eingabe und main Funktion.
    Natürlich bin ich für Versbesserungs und Optimierungsvorschläge auch offen. 😃
    Eine Version mit KI kommt später.

    //Brettspiel XXO (oder TicTac Toe) ohne KI für 2 Spieler
    //Spieler 1 -> X		Spieler 2 -> O
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int board[3][3];
    int liste[10];
    
    //Prototypen
    void reset();
    void ausgabe();
    void ausgabe2(int);
    void eingabe(int);
    void zuggenerator();
    int pruefen(int);
    void to_board(int,int);
    
    int main(void)
    {
    	int player, status;
    	int bool1;
    //Neues Spiel
    	do
    	{
    		reset();
    		player = 1;
    		bool1 = 0;
    		//Start neue Runde
    		while(1)
    		{
    			//Brett ausgeben
    			ausgabe();
    			//Eingabe eines neuen Zuges
    			eingabe(player);
    			//Prüfen auf Sieg, Neue Runde oder Remis
    			status = pruefen(player);
    			//Wenn einer gewonnen hat oder unentscheiden
    			if((status == 1) || (status == 2) || (status == 3))
    				{
    					ausgabe2(status);
    					break;
    				}
    			//Spieler wechsel und neue Runde
    			else
    			{
    				if(player == 1)
    					player = 2;
    				else player = 1;
    			}
    		}
    		//Neues Spiel beginnen?
    		while(1)
    		{
    			printf("\nNeues Spiel (j/n): ");
    			bool1 = getchar();// <-- Wird nicht richtig ausgeführt!!
    			if(bool1 != 'j' && bool1 != 'n')
    				printf("\nUngueltige Eingabe!\n\n");
    			else break;
    		}
    	}while(bool1 == 'j');
    	printf("\nAuf Wiedersehen\n\n");
    }
    
    void reset()
    {
    	int i, j;
    	int n='1';
    
    	for(i=0; i<3; i++)
    		for(j=0; j<3; j++){
    			board[i][j] = n;
    			n++;
    		}
    }
    void ausgabe()
    {
    	int i,j;
    	//Bildschirm löschen
    	for(i=0; i<16; i++)
    		printf("\n");
    	//Überschrift
    	printf("\nXXO - Player1 -> X\tPlayer2 ->  O\n\n\n\n\n");
    	//Spielbrett
    	for(i=0; i<3; i++){
    		printf("\t");
    		for(j=0; j<3; j++)
    			printf("  %c", board[i][j]);
    		printf("\n\n\n");
    	}
    }
    void ausgabe2(int ergebnis)
    {
    	ausgabe();
    	if(ergebnis == 3)
    		printf("\n\nUnentschieden, keiner hat gewonnen!\n");
    	else
    		printf("\n\nSpieler%d hat gewonnen.\n",ergebnis);
    }
    void eingabe(int p)
    {
    	int bool2, eingabe, k;
    	//Liste aller gültigen Züge erstellen
    	zuggenerator();
    	//Haupteingabeschleife
    	do
    	{
    		k=0; 
    		bool2=0;
    		printf("\n\nPlayer%d bitte Zahl eingeben(1-9): ",p);
    		eingabe = getchar();  // <-- Wird nicht richtig ausgeführt!!!!
    		//Vergleich aller gültigen Züge mit der Eingabe
    		while(liste[k] != NULL)
    		{
    			if(liste[k] == eingabe)
    			{
    				bool2 = 1;
    				break;
    			}
    			k++;
    		}
    		if(bool2 == 1)
    			to_board(eingabe,p);
    		else 
    			printf("Falsche Eingabe!");
    	}while(bool2 == 0);
    }
    void zuggenerator()
    {
    	//Gibt eine Liste aller legalen Züge zurück
    	int i, j, m=0, n = '1';
    	for(i=0; i<3; i++)
    	{
    		for(j=0; j<3; j++)
    		{
    			if(!(board[i][j] == 'X' || board[i][j] == 'O'))
    			{
    				liste[m] = n;
    				m++;
    			}
    			n++;
    		}
    	}
    	liste[m] = 0;
    	//Debug Liste Zuggenerator
    	/*
    	for(i=0; i<10; i++)
    	{
    		if(liste[i] == 0)
    			break;
    		printf("%c",liste[i]);
    	}
    	*/
    }
    int pruefen(int p)
    {
    	int r=5, i, j, symb;
    	//Auf X oder O Prüfen
    	if(p == 1)
    		symb = 'X';
    	else 
    		symb = 'O';
    	//Auf Sieg prüfen
    	if((board[0][0] == symb)&&(board[0][1] == symb)&&(board[0][2] == symb))
    		r = p;	//Sieger Player p
    	else if((board[1][0] == symb)&&(board[1][1] == symb)&&(board[1][2] == symb))
    		r = p;
    	else if((board[2][0] == symb)&&(board[2][1] == symb)&&(board[2][2] == symb))
    		r = p;
    	else if((board[0][0] == symb)&&(board[1][0] == symb)&&(board[2][0] == symb))
    		r = p;
    	else if((board[0][1] == symb)&&(board[1][1] == symb)&&(board[2][1] == symb))
    		r = p;
    	else if((board[0][2] == symb)&&(board[1][2] == symb)&&(board[2][2] == symb))
    		r = p;
    	else if((board[0][0] == symb)&&(board[1][1] == symb)&&(board[2][2] == symb))
    		r = p;
    	else if((board[2][0] == symb)&&(board[1][1] == symb)&&(board[0][2] == symb))
    		r = p;
    	//Auf neue Runde prüfen
    	if(r != p)
    	{
    		for(i=0; i<2; i++)
    			for(j=0; j<2; j++)
    			{
    				if(!(board[i][j] != 'X') || (board[i][j] != 'O'))
    					r = 0;	//neue Runde
    			}
    	}
    	//Auf Unentschieden prüfen
    	if(!((r == p) || (r == 0)))
    		r = 3;	//Unentschieden
    	return r;
    }
    void to_board(int eingabe,int player)
    {
    	int symb;
    	//Feststellen ob X oder O eingetragen werden soll
    	if(player == 1)
    		symb = 'X';
    	else symb = 'O';
    	//Such nach richtigem Feld auf Spielbrett
    	switch(eingabe)
    	{
    	case '1':
    		board[0][0] = symb;
    		break;
    	case '2':
    		board[0][1] = symb;
    		break;
    	case '3':
    		board[0][2] = symb;
    		break;
    	case '4':
    		board[1][0] = symb;
    		break;
    	case '5':
    		board[1][1] = symb;
    		break;
    	case '6':
    		board[1][2] = symb;
    		break;
    	case '7':
    		board[2][0] = symb;
    		break;
    	case '8':
    		board[2][1] = symb;
    		break;
    	case '9':
    		board[2][2] = symb;
    		break;
    	default:
    		printf("\nFehler in to_board\n");
    	}
    }
    


  • Klassischer Anfängerfehler.
    Die Funktionen der Standardbibliothek arbeiten nur mit einer gepufferten Eingabe, erst mit '\n' wird die Kontrolle an das Programm zurückgegeben, '\n' befindet sich dann meist noch im Eingabepuffer und muss dort "abgeholt" werden, sonst schlägt es auf die nächsten Eingaben "durch".
    Für zeichenweise Eingabe verwende mal

    int c;
    c=getchar();while(getchar()!='\n');
    if( c=='j' ... )
    


  • Vielen Dank,

    hat gut funktioniert.
    Diese ganzen Zeichenketten Sonderregeln verwirren mich immer aufs neue. 🙂


Anmelden zum Antworten