TicTacToe -- Hilfe?



  • Ich sehe hier nichts Unix-spezifisches. curses benutzt Du soweit ich sehen kann ja auch nirgends, bzw. wenn doch, nimmt es keine zentrale Rolel in Deinem Programm ein.

    Ich verschiebe Dich mal ins C++-Forum.



  • Dieser Thread wurde von Moderator/in nman aus dem Forum Linux/Unix in das Forum C++ (auch C++0x) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ich habe alles angepasst was Ihr mir gesagt habt und veränder Hier nochmal der gesamte Code:

    /* 
     * File:   main.cpp
     * Created on 24. Jänner 2011, 23:06
     */
    
    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    
    using namespace std;
    
    const int maxfield = 9; 													//Constante für Feld
    char cfield[maxfield] = { '1','2', '3','4','5','6','7','8','9'}; 		   //Feld
    int iselectedfield;													  		//welches Feld gewählt wurde
    int nplayerturn = 1; 													  //Wer ist dran?
    bool bgameover = false;													 //spielvorbei
    int nwinner = 0; 														//wer gewinnt (1=player1, 2=player2, 3=unentschieden)
    
    bool bError ();
    void drawfield (void); 													//zeichnet ein feld
    void drawspace (void);												 	//rückt das feld 20 mal ein
    void checkforwinner (void); 											//prüft wer der gewinner ist
    void saywinner(void); 													//ausgabegewinner
    
    int main(int argc, char** argv) 
    {
    
        char cselector = 'X';
    
            do {
    
    			//X oder O setzen 
                if (nplayerturn == 1)
                {
                    cselector = 'X';
                }
                else
                {
                    cselector = 'O';
                }
    
    			//vorherigen Konsolenoutput löschen | Spielfeld Zeichnen
    			system("clear");
    
                drawfield();
    
    			do{				
    			//Eingabeaufforderung
                std::cout << "Spieler " << nplayerturn << " geben Sie bitte eine Feldnummer ein: " << std::endl;
                std::cin >> iselectedfield;
    			}while(bError());
    
    			//Feld ändern - X oder O
                cfield[--iselectedfield] = cselector;
    
    			// vorherigen Konseloutput löschen | Feld Aktualisieren
    			system("clear");
    
                drawfield();
    
    			//Prüfen ob es einen Gewinner gibt & diesen verkünden
                checkforwinner();
    
                saywinner();
    
    			//Nächster Spieler ist dran
                nplayerturn++;
    
                if (nplayerturn > 2)
                {
                nplayerturn = 1;
                }
    
            } while ( !bgameover);
    }
    
    bool bError (void)
    {
    	bool berror = false;
    	//int ibackupselectedfield;
    
    	//Ist die Eingegeben Zahl zw. 1-9?
    	if (iselectedfield < 1 || iselectedfield > 9) 
    	{
    		berror = true;
    		cout << "Ungültige Eingabe" << endl;	
    	}
    
    	else if (cfield[--iselectedfield] == 'X' || cfield[--iselectedfield] == 'O')
    	{	
    		berror = true;
    		cout << "Ungültige Eingabe" << endl;
    	}
    
    	return berror;
    }
    
    // Spielfeld Einrücken um 20 spaces
    void drawspace (void)
    {
        for (int i = 0; i <= 20; i++)
        {
            cout << " ";
        }
    }
    
    //Spielfeld zeichne
    void drawfield ( void )
    {
    drawspace();
    cout << cfield[0]  << "|"  << cfield[1]  << "|" <<  cfield[2] << endl;
    drawspace();
    cout << "-" << "+" << "-" << "+" << "-" << endl;
    drawspace();
    cout << cfield[3]  << "|"  << cfield[4]  << "|" <<  cfield[5] << endl;
    drawspace();
    cout << "-" << "+" << "-" << "+" << "-" << endl;
    drawspace();
    cout << cfield[6]  << "|"  << cfield[7]  << "|" <<  cfield[8] << endl;
    }
    
    //Prüfen Wer gewinnt 
    void checkforwinner (void)
    {
    	//oben
    	if ( cfield[0] ==  cfield[1] && cfield[1] == cfield[2] && cfield[2] == cfield[0])
    	{
    			nwinner = nplayerturn;
    			bgameover = true;
    	}
    	//mitte
    	else if (cfield[3] ==  cfield[4] && cfield[4] == cfield[5] && cfield[5] == cfield[3])
    	{
    			nwinner = nplayerturn;
    			bgameover = true;
    	}
    	//unten
    	else if (cfield[6] ==  cfield[7] && cfield[7] == cfield[8] && cfield[8] == cfield[6])
    	{
    			nwinner = nplayerturn;
    			bgameover = true;
    	}
    
    	//links
    	else if (cfield[0] ==  cfield[3] && cfield[3] == cfield[6] && cfield[6] == cfield[0])
    	{
    			nwinner = nplayerturn;
    			bgameover = true;
    	}
    	//mitte
    	else if (cfield[1] ==  cfield[4] && cfield[4] == cfield[7] && cfield[7] == cfield[1])
    	{
    			nwinner = nplayerturn;
    			bgameover = true;
    	}
    	//rechts
    	else if ( cfield[2] ==  cfield[5] && cfield[5] == cfield[8] && cfield[8] == cfield[2])
    	{
    			nwinner = nplayerturn;
    			bgameover = true;
    	}
    
    	//Schräg von links oben
    	else if (cfield[0] ==  cfield[4] && cfield[4] == cfield[8] && cfield[8] == cfield[0])
    	{
    			nwinner = nplayerturn;
    			bgameover = true;
    	}
    	//Schräg von rechts oben
    	else if ( cfield[2] ==  cfield[4] && cfield[4] == cfield[6] && cfield[6] == cfield[0])
    	{
    			nwinner = nplayerturn;
    			bgameover = true;
    	}
    
    	//unentschieden
    	else if ((cfield[0] !='1' && cfield[1] != '2' && cfield[2] !='3') &&
    			 (cfield[3] !='4' && cfield[4] != '5' && cfield[5] !='6') &&
    		     (cfield[6] !='7' && cfield[7] != '8' && cfield[8] !='9'))
    	{
    			nwinner = 3;
    			bgameover = true;
    	}
    
    }
    
    //verkündet den Gewinner
    void saywinner (void)
    {
    	if (nwinner == 1)
    	{
    		std::cout << "Glückwunsch, der Gewinner ist Spieler " << nplayerturn << std::endl;
    	}
    	else	if (nwinner == 2)
    	{
    		std::cout << "Glückwunsch, der Gewinner ist Spieler " << nplayerturn << std::endl;
    	}
    	else	if (nwinner == 3)
    	{
    		std::cout << "Schade es steht unentschieden" << std::endl;
    	}
    
    }
    

    Das Spiel funktioniert allerdings: wenn ich z.B.: 3 eingebe ändert sich das Feld 2 O.o.



  • Ein kleines Update: Ich benutzte jetzt Code::Blocks mit gcc compiler und es funktioniert toll mit einer Ausnahme: system("clear"); funktioniert nicht mehr :/. Irgendwelche Lösungen?


  • Mod

    Kuwiano schrieb:

    Ein kleines Update: Ich benutzte jetzt Code::Blocks mit gcc compiler und es funktioniert toll mit einer Ausnahme: system("clear"); funktioniert nicht mehr :/. Irgendwelche Lösungen?

    Definiere "funktioniert nicht mehr".



  • Nach dem ich jetzt mal das Programm gestartet habe (außerhalb Code::Blocks) funktz wider dafür hab ich 1 Problem (hoffentlich das Letzte! Gebe ich einen Char ein ("a") dann hängt sich das Programm auf und gibt Hundert mal de selbe Line aus (Bitte Geben Sie eine Zahl ein: ). Hört erst auf wenn Ich das Terminal schließe.



  • Das liegt daran, weil ein falsches Zeichen (keine Zahl wie int ja erwartet) eingegeben wurde und bei cin nun der Fehlerstatus verhängt ist. Das kannst du so lösen:

    #include <limits>
    if( !(std::cin >> variable) ) {
    	std::cin.clear(); //fehlerstatus zurücksetzen
    	std::cin.ignore(std::numeric_limits<int>::max(), '\n'); //fehlerhafte Zeichen überspringen
        continue; //oder sowas in der richtung
    }
    

    Dann sollte alles weitergehen.



  • Hey!

    Vielen Dank jetzt funktioniert alles allerdings durchschaue ich den letzten Teil nicht ganz 😞 --> und ich will das verstehen was ich programmiere :D.

    std::cin.ignore(std::numeric_limits<int>::max(), '\n'); //fehlerhafte Zeichen überspringen
    

    Was bringt das ganze/was heißt std::numeric_limits<int>::max(), ?

    Danke für eure Hilfe



  • numeric_limits<DATENTYP>::max()/min() gibt die jeweilige größtmögliche/kleinstmögliche Zahl für den Datentyp an. Was std::cin.ignore() macht, erfährst du hier.

    mfg



  • Ok cin.ignore() hab ich verstanden und auch die Überprüfung ist logisch allerdings verwirrt mich das Dritte:

    std::cin.ignore(std::numeric_limits<int>::max(), '\n'); //fehlerhafte Zeichen überspringen
    

    Soweit ich das verstehen könnte ich auch genauso gut:

    iselectedfield = 11;
    

    damit wäre der Fehler doch genauso ausgewiesen?!? Oder verstehe ich da etwas falsch?



  • Wenn du eine Variable vom Typ int hast und sie vom Standardeingabemedium eingeben lässt, werden die eingegeben Zeichen im Puffer gespeichert. Wenn also statt einer Zahl ein Buchstabe o.ä. eingegeben wird, dann hängen die Zeichen im Speicher rum. Du kannst dann solange den Fehlerstatus mit clear() auf 0 setzen wie du willst - durch die Zeichen, die immer noch da sind, wird er jedes mal aufs neue verhängt. Wenn du allerdings mit ignore() jedes fehlerhafte Zeichen aus dem Puffer "verwirfst", dann sind keine fehlerhaften Zeichen mehr im Puffer und der Fehlerstatus wird erfolgreich dauerhaft auf 0 gesetzt - jetzt kann wieder eingegeben werden.
    Wenn ich was falsches gesagt habt korrigiert mich bitte, ich kenn mich da nicht so gut aus.



  • Ok, also funktioniert das so: das alles was in der Klammer steht heißt dann nur das in den Puffer der größt mögliche wert reingeschrieben wird was bei der Überprüfung wieder auffällt. Hab ich das jetzt richtig verstanden?



  • OK, wieder 1 Problem bei der Namen Eingabe. Es wird 1 Buchstabe erkannt und dann heißt der Player hald kpieler1 statt Kuwiano, der Zweite Player wird garnicht erkannt oder verändert hier der Code:

    char player1[] = "Spieler1";                                            //Name für Spieler 1
    char player2[] = "Spieler2";                                            //Name für Spieler 2
    
    void Playername(void)                                                   //Spieler Name Abfragen
    {
        std::cout << "Spieler 1 gib deinen Namen ein: ";
        std::cin >> player1[11];
    
        std::cout << "Spieler 2 gib deinen Namen ein: ";
        std::cin >> player2[11];
    }
    


  • Da ich keine Lust habe, dir das jetzt mit den C-Strings zu erklären (dafür gibt es genug andere Posts) empfehle ich dir nur, std::string zu verwenden.



  • Hallo, wiedereinmal!

    Ich möchte jetzt einen Timer in mein Spiel einbauen (Wenn ein Spieler dran ist zählt er von 10 runter --> Beendet den Spielzug). Ich habe mal mit for schleifen und sleep(); probiert allerdings ohne Erfolg. Gibt es eine Möglichkeit das zu machen?



  • Guck mal in #include <ctime> rein ...

    Zeit zeit = Zeit::jetzt()
    Gib 10 aus 
    while (Zeit::jetzt() < zeit + 10 Sekunden)
    {
       // guck ob spieler was eingegeben hat (cronio.h) oder so ... 
       // wenn nicht: 
        /// wenn Zeit::jetzt() > zeit+9 Sekunde n gib 1 aus,
        /// sonst wenn Zeit::jetzt() > zeit+8 Sekunde n gib 2 aus,
        /// sonst wenn Zeit::jetzt() > zeit+7 Sekunde n gib 3 aus,
        /// sonst wenn Zeit::jetzt() > zeit+6 Sekunde n gib 4 aus,
        /// sonst wenn Zeit::jetzt() > zeit+5 Sekunde n gib 5 aus,
        /// sonst wenn Zeit::jetzt() > zeit+4 Sekunde n gib 6 aus,
        /// sonst wenn Zeit::jetzt() > zeit+3 Sekunde n gib 7 aus,
        /// sonst wenn Zeit::jetzt() > zeit+2 Sekunde n gib 8 aus,
        /// sonst wenn Zeit::jetzt() > zeit+1 Sekunde n gib 9 aus,
        ///  - du musst dir auch merken welche Zeit du schon ausgegeben hast ... damit der nicht die Konsole vollspammt
    
    }
    


  • Und wie kann ich mit conio.h prüfen ob der Spieler etwas eingegeben hat ohne dass das Programm stehen bleibt?



  • dafür guckst du in die FAQ dieses Forums, da gibts nen Post zu genau sowas ... das ganze ist dann aber nimmer platformunabhängig aber das dürfte dir ja eh egal sein. Mhh finde den Beitrag gerade nicht ... vielleicht hilft dir ein Moderator weiter :| insgesamt ist es nicht ganz trivial zu schauen ob schon user input anliegt ... die streams können zwar peek'en aber wenn nix drin ist, blockieren die dann bis was kommt ... mag mich aber auch irren, ist bei mir schon lange her 😉


Anmelden zum Antworten