TicTacToe



  • Guten Morgen,

    Ich wollte mich erkundigen ob es möglich ist die Funktion Check, also die Abfrage ob jemand gewonnen hat
    zu vereinfachen. Oder ist es so bereits schon gut?

    Das Programm:

    #include <iostream>
    using namespace std;
    
    char Feld [3][3];
    bool Round = false;
    int EingabeX, EingabeY;
    
    void Spielfeld (void);
    void Check (void);
    void Eingabe (void);
    
    struct SpielerData{
        string Name;
        int AnzRunden = 0;
        bool Gewonnen = false;
    }Spieler[2];
    
    int main()
    {
        for (int a=0; a<3; a++)
        {
            for (int b=0; b<3; b++)
            {
                Feld[a][b]='.';
            }
        }
        Spielfeld();
    
        cout<<"Waehlen sie ihren Namen";
        cout<<endl <<"Spieler 1: ";
        cin>>Spieler[0].Name;
        cout<<endl <<"Spieler 2: ";
        cin>>Spieler[1].Name;
        cout<<endl <<endl <<endl <<Spieler[0].Name <<" - <X>" <<endl <<Spieler[1].Name <<" - <O>" <<endl <<"Gebe zuerst X dann Y ein um eine Stelle zu markieren. - z.B erst 2 dann 1 fuer die zweite Stelle" <<endl <<endl;
        system("pause");
        system("cls");
    
    
        do{
            if(Spieler[0].AnzRunden == 5) {
                Spielfeld();
                cout<<endl <<endl <<"Es hat niemand gewonnen!" <<endl <<endl;
                return 0;
            }
            else {
                if (Round == false) {
                    cout << Spieler[0].Name << " ist am Zug." << endl << endl;
                    Spielfeld();
                    cout << endl << endl << ">";
                    cin >> EingabeX;
                    cout << endl << ">";
                    cin >> EingabeY;
                } else {
                    cout << Spieler[1].Name << " ist am Zug." << endl << endl;
                    Spielfeld();
                    cout << endl << endl << ">";
                    cin >> EingabeX;
                    cout << endl << ">";
                    cin >> EingabeY;
                }
                Eingabe();
                Check();
                system("cls");
            }
        } while(Spieler[0].Gewonnen == false || Spieler[1].Gewonnen == false);
    
        if(Spieler[0].Gewonnen == true) {
            Spielfeld();
            cout<<endl <<endl <<Spieler[0].Name <<" hat gewonnen!" <<endl <<Spieler[0].Name <<" hat " <<Spieler[0].AnzRunden <<" Runden gebraucht um zu gewinnen" <<endl <<endl <<endl;
        }
        else {
            Spielfeld();
            cout<<endl <<endl <<Spieler[1].Name <<" hat gewonnen!" <<endl <<Spieler[1].Name <<" hat " <<Spieler[1].AnzRunden <<" Runden gebraucht um zu gewinnen" <<endl <<endl <<endl;
        }
    }
    
    void Spielfeld (void){
        for (int a=0; a<3; a++)
        {
            for (int b=0; b<3; b++)
            {
                cout<<Feld[a][b] <<" | ";
            }
            cout<<endl;
        }
    }
    
    void Eingabe (void)
    {
        EingabeX -= 1;
        EingabeY -= 1;
        if(Feld[EingabeY][EingabeX] == 'X' || Feld[EingabeY][EingabeX] == 'O') {
            cout<<endl <<endl <<"Sie können nicht auf ein bereits bestehendes Feld eine Eingabe ausführen." <<endl <<endl;
            system("pause");
        } else {
            if (Round == false) {
                Feld[EingabeY][EingabeX] = 'X';
                Spieler[0].AnzRunden++;
                Round=true;
            } else {
                Feld[EingabeY][EingabeX] = 'O';
                Spieler[1].AnzRunden++;
                Round=false;
            }
        }
    }
    
    void Check (void)
    {
        if(Feld[0][0] == 'X' && Feld[0][1] == 'X' && Feld[0][2] == 'X') { Spieler[0].Gewonnen = true; }
        else if(Feld[1][0] == 'X' && Feld[1][1] == 'X' && Feld[1][2] == 'X') { Spieler[0].Gewonnen = true; }
        else if(Feld[2][0] == 'X' && Feld[2][1] == 'X' && Feld[2][2] == 'X') { Spieler[0].Gewonnen = true; }
        else if(Feld[0][0] == 'X' && Feld[1][0] == 'X' && Feld[2][0] == 'X') { Spieler[0].Gewonnen = true; }
        else if(Feld[0][1] == 'X' && Feld[1][1] == 'X' && Feld[2][1] == 'X') { Spieler[0].Gewonnen = true; }
        else if(Feld[0][2] == 'X' && Feld[1][2] == 'X' && Feld[1][2] == 'X') { Spieler[0].Gewonnen = true; }
        else if(Feld[0][0] == 'X' && Feld[1][1] == 'X' && Feld[2][2] == 'X') { Spieler[0].Gewonnen = true; }
        else if(Feld[2][0] == 'X' && Feld[1][1] == 'X' && Feld[0][2] == 'X') { Spieler[0].Gewonnen = true; }
        else {
            if (Feld[0][0] == 'O' && Feld[0][1] == 'O' && Feld[0][2] == 'O') { Spieler[1].Gewonnen = true; }
            else if (Feld[1][0] == 'O' && Feld[1][1] == 'O' && Feld[1][2] == 'O') { Spieler[1].Gewonnen = true; }
            else if (Feld[2][0] == 'O' && Feld[2][1] == 'O' && Feld[2][2] == 'O') { Spieler[1].Gewonnen = true; }
            else if (Feld[0][0] == 'O' && Feld[1][0] == 'O' && Feld[2][0] == 'O') { Spieler[1].Gewonnen = true; }
            else if (Feld[0][1] == 'O' && Feld[1][1] == 'O' && Feld[2][1] == 'O') { Spieler[1].Gewonnen = true; }
            else if (Feld[0][2] == 'O' && Feld[1][2] == 'O' && Feld[1][2] == 'O') { Spieler[1].Gewonnen = true; }
            else if (Feld[0][0] == 'O' && Feld[1][1] == 'O' && Feld[2][2] == 'O') { Spieler[1].Gewonnen = true; }
            else if (Feld[2][0] == 'O' && Feld[1][1] == 'O' && Feld[0][2] == 'O') { Spieler[1].Gewonnen = true; }
        }
    }
    


  • @Ventex sagte in TicTacToe:

    Ich wollte mich erkundigen ob es möglich ist die Funktion Check, also die Abfrage ob jemand gewonnen hat
    zu vereinfachen.

    Du kennst doch offensichtlich Schleifen. Warum verwendest du keine?
    Du kennst doch offensichtlich Funktionen. Warum Kopierst du den Code und ersetzt 'X' durch 'Y' und Spieler[0] durch Spiler[1]?



  • Bitte verwende keine globalen Variablen!!!!!! (Ein Fall, wo mehrere Ausrufezeichen gerechtfertigt sind.)

    All deine Funktionen sollten also das Feld als Parameter übergeben bekommen.
    Und ja, die Funktion ist viel zu kompliziert. Hast du dich bei auch nur einem Index vertan, wirst du ewig brauchen, um den Fehler zu finden.

    Zunächst einmal kannst du X und O als Parameter nehmen. Dann hast du schon nur noch halb so viel Code.
    Und dann kannst du Schleifen benutzen. Damit wird es auch ohne Probleme möglich, TTT auf anderen Größen als 3x3 zu spielen, also z.B. 4x4, auch wenn das bei diesem Spiel wenig Sinn ergibt.

    Funktionen dürfen auch was zurückgeben. Sollten sogar. Deine check-Funktion könnte also z.B. nur einen Spieler testen und dann true/false zurückgeben, ob dieser Spieler gewonnen hat. Nachdem Spieler "X" gesetzt hat, brauchst du nicht zu testen, ob Spieler "O" gewonnen hat. Also genereller Rat: wenn möglich, manipuliere in deiner Funktion nicht irgendwelche Werte (hier: Spieler[...].Gewonnen), sondern lass solche Werte lieber unverändert und gib stattdessen das Ergebnis zurück. Gerade bei so einer Funktion wie "check", die auch "has_won" (oder ähnlich) heißen könnte.

    Noch was:
    Sowas hier: if(Spieler[0].Gewonnen == true) {
    solltest du verkürzen zu if(Spieler[0].Gewonnen) {
    (das ist schon ein Bool - daran ändert der Vergleich nichts)
    Und das == false könntest du durch ein "nicht" ersetzen.

    Und noch was: Welche Sprache soll das sein? C++ wegen iostream-include? C wegen "void" bei Funktionen ohne Parameter?



  • Du solltest auf jeden Fall noch eine Gültigkeitsprüfung für die Eingaben einbauen. Wenn jemand die Koordinaten 7 und 10 eingibt fliegt dir dein Spiel um die Ohren. Außerdem verliert ein Spieler seinen Zug, wenn er ein Feld benennt, das schon besetzt ist. Und ich würde das Spielende dadurch überprüfen, dass kein freies Feld mehr verfügbar ist.


Log in to reply