TicTacToe feld Zeichnen !leider klapt es nicht!



  • Hallo Leute!

    Habe vollgendess kleines Programm zu Übung erstellt, leider gibts Probleme bei der
    zeichnung des Feldes!

    hier der Code:

    #include <iostream>
    #include <stdlib.h>
    #include <conio.h>
    #include <windows.h>
    
    using namespace std;
    
    class Spielfeld
    {
        private:
            char feld[2][2];
            char feld_inhalt;
            string spieler1;
            string spieler2;
            bool spielzug;
        public:
            Spielfeld();
            void feld_schreiben(int rechts,int runter,char inhalt);
            void feld_zeichnen(void);
            int feld_kontrolle(void);
            void spieler_anlegen(void);
            void stein_f(bool);
            bool stein(void);
            ~Spielfeld();
    }; 
    
    void gotoxy(short x, short y);
    
    //Classen schnittstellenfunktionen 
    Spielfeld::Spielfeld()
    {
    
    }  
    Spielfeld::~Spielfeld()
    {
    
    }      
    
    void Spielfeld::feld_schreiben(int rechts,int runter,char inhalt )
    {
        feld[rechts][rechts]=inhalt;     
    }
    void Spielfeld::feld_zeichnen(void)
    {
      system("cls");
      gotoxy(30,4);
      cout<<"Tic Tac Toe";
      if (spielzug)
        {
            gotoxy(10,10);cout << spieler1;
        }
      else
        {
            gotoxy(60,10);cout << spieler2;
        }    
      gotoxy(20,6);cout <<"Geben Sie Die Position so an";
      gotoxy(20,7);cout <<"Die Zahl und dann Den Buchstaben";
      gotoxy(26,8);cout <<"Beispiel >> 1A";
      gotoxy(27,10);cout<< " =============== ";
      gotoxy(27,11);cout<< "|   | 1 | 2 | 3 |";
      gotoxy(27,12);cout<< "|===============|";
      gotoxy(27,13);cout<< "| A | "<<feld[0][0]<<" | "<<feld[1][0]<<" | "<<feld[2][0]<<" |";
      gotoxy(27,14);cout<<"|===============|";
      gotoxy(27,15);cout<<"| B | "<<feld[0][1]<<" | "<<feld[1][1]<<" | "<<feld[2][1]<<" |";
      gotoxy(27,16);cout<<"|===============|";
      gotoxy(27,17);cout<<"| C | "<<feld[0][2]<<" | "<<feld[1][2]<<" | "<<feld[2][2]<<" |";
      gotoxy(27,18);cout<<"|===============|";
      gotoxy(30,20);
    } 
    
    void Spielfeld::spieler_anlegen(void)
    {
        gotoxy(25,4);cout << "Willkommen zum Spiel Tic Tac Toe";
        gotoxy(25,6);cout << "Spieler1 bitte geben sie ihren namen ein";
        gotoxy(30,7);cin >> spieler1;
        system("cls");
        gotoxy(25,4);cout << "Willkommen zum Spiel Tic Tac Toe";
        gotoxy(25,6);cout << "Spieler2 bitte geben sie ihren namen ein";
        gotoxy(30,7);cin >> spieler2;    
    }
    bool Spielfeld::stein()
    {
        return spielzug;
    }   
    void Spielfeld::stein_f(bool) 
    {
        if (spielzug)
        {
            spielzug=false;
        }
        else
        {
            spielzug=true;
        }
    }         
    
    //Funktion zum Zeichen x in Zeile y springt!
    void gotoxy(short x, short y)
    {
    HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos;
    pos.X=x-1;
    pos.Y=y-1;
    SetConsoleCursorPosition(hCon, pos);
    }
    
    int main(int argc, char *argv[])
    {
        bool wahr=true;
        Spielfeld Sfeld1;
    
        Sfeld1.spieler_anlegen();
        for (int m=0;m<3;m++)
        {
            for (int n=0;n<3;n++)
            {
              Sfeld1.feld_schreiben(m,n,' ');
            }
        }  
        Sfeld1.feld_zeichnen();
        int rechts,runter;
        bool c;
        Sfeld1.stein_f(false);
        do
        {
            gotoxy(30,21);cin>>rechts;gotoxy(31,21);;cin>>runter;
            getch();
            c=Sfeld1.stein();
            if (c==true)
            {
                Sfeld1.feld_schreiben(rechts,runter,'X');
                Sfeld1.stein_f(true);
            }
            else
            {
                Sfeld1.feld_schreiben(rechts,runter,'O');
                Sfeld1.stein_f(false);
            }
            system("cls");        
            Sfeld1.feld_zeichnen();
        }while ('q'!= getch());
    
      system("PAUSE");	
      return 0;
    }
    

    Es wäre noch anzumerken das man die kordinaten des feldes anstatt 1A
    00 angeben muss da ich da noch keine abfrage gemacht habe!

    man muss also auf die indexe von dem feld zugreifen also von 0 - 2 anstatt 1-3
    0 - 2 anstatt A-C

    Also wer mir Helfen kann, der tue das Bitte 🤡 wäre echt klasse!

    Gruß Tobias



  • das feld wird doch richtig angezeigt? (zumindest bei mir)

    aber es gibt ein anderes problem...
    der 2. spieler kann keine werte eingeben.... wenn er irgendeine taste drückt, dann ändert sich nur das feld vom gegner... bsp.:

    der 1. spieler gibt als feld 1A ein:

    in das feld wird ein Kreis gezeichnet.
    der 2. spieler drückt eine taste:
    in das feld wird ein Kreuz gezeichnet.

    irgendwo in der abfrage ist der wurm drin...

    ich habe versucht den fehler zufinden, aber ohne kommentare ist es recht schwer und im mom habe ich keine lust... sorry.

    ich finde es auch nicht gut, dass du nur eine klasse hast...
    warum machst du nicht mehrere?
    eine klasse spieler, eine spielfeld... ich finde, dass es das programm leserlicher und besser verständlich machen würde....



  • hi

    Du solltest auf jeden fall eine validierung der eingaben machen (überprüfen ob die eingaben annehmbar sind (1-3 und von A-C)) und du musst die Eingaben umwandeln!

    Beim aufruf

    Sfeld1.feld_schreiben(rechts,runter,'X');
    // richtiger aber nicht perfekt
    Sfeld1.feld_schreiben(rechts-1,runter-65,'X');
    

    Besser wäre es wenn der Benutzer nur 1A eingeben müsste und du dass dann in ein Cstring übernehmen würdest und danach erste die eingaben auseinader teilen würdest.

    ich hoffe diese info hilft dir
    mfg _kleiner helfer



  • Ja das stimmt schon aber fange grade an mit dem Programmieren!
    also erstmal danke !
    Also mein Prob ist das wenn ich zum Beispiel 10 als kordinate angebe, werden mehrere felder als gefüllt ausgegeben und auch bei 20!

    Naja egal wenn es keiner, findet , das prob, dann schreibe ich das programm noch mal mit mehreren Klassen und Freund Klassen, aber das behebt ja auch nicht das Problem mit dem feld zeichnen bzw dem zeichen mit den eingefühlten werten!

    Sorry für den schlechten code werde mir in zukunft meh mühe geben! 😃

    Aber Trotzdem DAnke für die Kritik(ist nämlich gut zu wissen wo man dran arbeiten muss! 🤡 )
    Gruss Tobias



  • zu kleiner helfer:

    Also das ist ja schon klar, will halt erstmal den einen Wurm raus haben bevor ich mir den nächsten einfang (auch wen der dann ganz allein ist 😃 )

    Das Problem was ich habe liegt eher bei dem Array und der werte zuweisung nehme ich an!

    Gruß Tobias



  • tobiS schrieb:

    void Spielfeld::feld_schreiben(int rechts,int runter,char inhalt )
    {
        feld[rechts][rechts]=inhalt;    
    }
    

    was ist das denn? warum übergibt man recht und runter, wenn dann nur rechts benötigt wird?

    hier ist doch der fehlerteufel am werk 😉

    by the way:

    warum hast du eine funktion namens feld_kontrolle gemacht, wenn die nie benötigt wird und nicht man implementiert wird?

    //edit:
    bitte bessere namen vergeben:

    bool stein() hätte besser den namen bool getSpielzug() verdient, da sie nur die variable Spielzug zurück gibt... nur so am rande, damit man sich als "laie" im sourcecode zurecht findet...

    //noachwas:

    stein_f, was macht die?(mir ist es klar, aber wenn man den namen liest, dann weiß man es nicht sofort, dann muss man zuerst nachgucken...)

    auch hier wäre es besser gewesen sie void setSpielzug(bool) zu nennen, dann weiß man sofort, was die funktion macht und welchen wert Spielzug hat...

    Tipp:
    es ist immer gut, funktionen, die elemente einer klasse verändern, getElement oder setElement zu nennen.... (Element steht natürlich für den namen des Elements 😉 )

    //Fazit:

    ich glaube, es wäre besser nochmal ganz von vorne anzufangen mit dem programm.... man müsste hier soviel umändern, dass es mehr arbeit wäre... sorry.
    und wenn das problem dann immer noch besteht, dann frag nochmal nach...

    und nicht vergessen:
    viele kommentare und "gescheite" namen... sie sind nicht nur für andere leute wichtig, sondern auch für dich, damit du dich am nächsten tag oder nächste woche besser zurecht findest...



  • habe mir nochmal deinen code angesehen und habe die meisten fehler entdeckt... ich hoffe, dass es nun klappt... habe es nicht getestet:

    #include <iostream>
    #include <stdlib.h>
    #include <conio.h>
    #include <windows.h>
    
    using namespace std;
    void clrscr();
    void gotoxy(short, short);
    
    class Spielfeld
    {
        private:
            char feld[3][3];        //DAS FELD WAR ZU KLEIN!!!
            //char feld_inhalt;   wird nie benutzt... -> also weg damit...
            string spieler1;
            string spieler2;
            bool spielzug;
        public:
            Spielfeld();
            void feld_schreiben(int rechts,int runter,char inhalt);
            void feld_zeichnen(void);
            //int feld_kontrolle(void);    wird nicht benötigt!!!
            void spieler_anlegen(void);
            void stein_f(bool);   //bitte andere namen das nächste mal zb.: void setSpielzug(bool);
            bool stein(void); //s.o.  zb.: bool getSpielzug();  (void in der klammer ist nicht notwendig(ist geschmackssache))
            ~Spielfeld();
    };
    
    //Classen schnittstellenfunktionen
    Spielfeld::Spielfeld()
    {
       //hier könnte man zum beispiel die spieler_anlegen funktion aufrufen... mit dem this zeiger... also:    this->spieler_anlegen();
    //und man könnte Spielzug einen Wert zuweisen...
    }  
    Spielfeld::~Spielfeld()
    {
    
    }      
    
    void Spielfeld::feld_schreiben(int rechts,int runter,char inhalt )
    {
        feld[runter][rechts]=inhalt;                //hier hattest du dich bestimmt vertippt!
    }
    void Spielfeld::feld_zeichnen(void)
    {
      clrscr();
      gotoxy(30,4);
      cout<<"Tic Tac Toe";
      if (spielzug)
        {
            gotoxy(10,10);cout << spieler1;
        }
      else
        {
            gotoxy(60,10);cout << spieler2;
        }    
      gotoxy(20,6);cout <<"Geben Sie Die Position so an";
      gotoxy(20,7);cout <<"Die Zahl und dann Den Buchstaben";
      gotoxy(26,8);cout <<"Beispiel >> 1A";
      gotoxy(27,10);cout<< " =============== ";
      gotoxy(27,11);cout<< "|   | 1 | 2 | 3 |";              //du hast die felder falsch durch nummeriert!
      gotoxy(27,12);cout<< "|===============|";
      gotoxy(27,13);cout<< "| A | "<<feld[0][0]<<" | "<<feld[0][1]<<" | "<<feld[0][2]<<" |";
      gotoxy(27,14);cout<< "|===============|";
      gotoxy(27,15);cout<< "| B | "<<feld[1][0]<<" | "<<feld[1][1]<<" | "<<feld[1][2]<<" |";
      gotoxy(27,16);cout<< "|===============|";
      gotoxy(27,17);cout<< "| C | "<<feld[2][0]<<" | "<<feld[2][1]<<" | "<<feld[2][2]<<" |";
      gotoxy(27,18);cout<< "|===============|";
      gotoxy(30,20);
    }
    
    void Spielfeld::spieler_anlegen(void)
    {
        gotoxy(25,4);cout << "Willkommen zum Spiel Tic Tac Toe";
        gotoxy(25,6);cout << "Spieler1 bitte geben sie ihren namen ein";
        gotoxy(30,7);cin >> spieler1;
        clrscr();
        gotoxy(25,4);cout << "Willkommen zum Spiel Tic Tac Toe";
        gotoxy(25,6);cout << "Spieler2 bitte geben sie ihren namen ein";
        gotoxy(30,7);cin >> spieler2;    
    }
    bool Spielfeld::stein()        //siehe oben kommentar
    {
        return spielzug;
    }  
    void Spielfeld::stein_f(bool)
    {
        if (spielzug)
        {
            spielzug=false;
        }
        else
        {
            spielzug=true;
        }
    }        
    
    int main(int argc, char *argv[])
    {
        //bool wahr=true;     wird auch nicht benötigt!
        Spielfeld Sfeld1;
    
        Sfeld1.spieler_anlegen();
        for (int m=0;m<3;m++)
        {
            for (int n=0;n<3;n++)
            {
              Sfeld1.feld_schreiben(m,n,' ');
            }
        }  
        Sfeld1.feld_zeichnen();
        char eingabe;
        int rechts,runter;
        bool c; //ungünstiger name... ersterSpieler wäre besser... (leserlicher)
        Sfeld1.stein_f(false);
        do
        {
            cout << "Naechster Spieler";        //Damit man auch weiß, wan man dran ist, da mna immer nach der eingabe wieder ENTER drücken muss...
            gotoxy(30,21);cin>>rechts;cin>>eingabe;    //nun klappt es auch mit den buchstaben; du hattest es in der falschen reihenfolge eingelesen!
            switch(eingabe)
            {
                     case 'A':
                         runter = 0;                //zum "übersetzen" der buchstaben!
                         break;
                     case 'B':
                         runter = 1;
                         break;
                     case 'C':
                         runter = 2;
                         break;
    
            }    
            c=Sfeld1.stein();
            if (c==true)
            {
                Sfeld1.feld_schreiben(rechts-1,runter,'X'); // nun kann man ganz normal die zahlen eingeben, sowie es in deinem bsp steht...
                Sfeld1.stein_f(true);
            }
            else
            {
                Sfeld1.feld_schreiben(rechts-1,runter,'O');
                Sfeld1.stein_f(false);
            }
            //clrscr(); wird schon in feld_zeichnen() aufgerufen!  
            cout << "Naechster Spieler!";    
            Sfeld1.feld_zeichnen();
        }while ('q'!= getch());
    
      cin.get(); cin.get();             //mag das system nicht so... darum cin.get();
      return 0;
    }
              //ist ein bisschen übersichtlicher, wenn man sie ganz unten stehen hat, anstatt mitten im sorcecode.. (ist meine meinung)
    void clrscr()    //anderes clear screen...
    {
      COORD coordScreen = { 0, 0 };
      DWORD cCharsWritten;
      CONSOLE_SCREEN_BUFFER_INFO csbi;
      DWORD dwConSize;
      HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    
      GetConsoleScreenBufferInfo(hConsole, &csbi);
      dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
      FillConsoleOutputCharacter(hConsole, TEXT(' '),
                                 dwConSize,
                                 coordScreen,
                                 &cCharsWritten);
      GetConsoleScreenBufferInfo(hConsole, &csbi);
      FillConsoleOutputAttribute(hConsole,
                                 csbi.wAttributes,
                                 dwConSize,
                                 coordScreen,
                                 &cCharsWritten);
      SetConsoleCursorPosition(hConsole, coordScreen);
    }
    
    //Funktion zum Zeichen x in Zeile y springt!
    void gotoxy(short x, short y)
    {
    HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos;
    pos.X=x-1;
    pos.Y=y-1;
    SetConsoleCursorPosition(hCon, pos);
    }
    

    nun habe ich mich lange genug mit deinem programm beschäftigt... wenn aber noch fragen sind, dann immer menn her damit 👍



  • SChönen Dank!

    Also das mit dem kommentieren , da gebe ich dir recht muss mich mehr dahinter setzen!
    dann noch danke für anderen Tips , bin halt grad erst angefangen mit dem Programmieren und muss noch ne menge lernen! 🤡

    Zum Glück gibt es so Leute wie dich, die einem unter die arme greifen!

    Danke

    Gruß Tobias



  • Hallo

    ich bin auch neu hier und hab das mal ausprobiert aber irgendtwie kommen bei mir 4 Fehler. Es geht zweimal um den den binären operator "<<" und zweimal um ">>". Die Fehler sind in der Zeile 52,56,77 und 81. Kann mir vielleicht jemand sagen wieso das so ist weil bei anderen funktioniert es ja. Leider bin ich noch ganz neu in C++ und bin halt noch am lernen. Schon mal danke im Voraus.



  • wie ist den die genaue fehlerbeschreibung?

    es fällt nämlich auf, dass in den zeilen mit den 2 strings spieler1 und spieler2 gearbeitet wird... vielleicht ist da irgendwo das problem...



  • Die genaue Fehler-Beschreibung lautet:

    c:\programme\microsoft visual studio\myprojects\11051717\code.cpp(52) : error C2679: Binaerer Operator '<<' : Kein Operator definiert, der einen rechtsseitigen Operator vom Typ 'class std::basic_string<char,struct std::char_traits<char>,class std::a
    llocator<char> >' akzeptiert (oder keine geeignete Konvertierung moeglich)
    c:\programme\microsoft visual studio\myprojects\11051717\code.cpp(56) : error C2679: Binaerer Operator '<<' : Kein Operator definiert, der einen rechtsseitigen Operator vom Typ 'class std::basic_string<char,struct std::char_traits<char>,class std::a
    llocator<char> >' akzeptiert (oder keine geeignete Konvertierung moeglich)
    c:\programme\microsoft visual studio\myprojects\11051717\code.cpp(77) : error C2679: Binaerer Operator '>>' : Kein Operator definiert, der einen rechtsseitigen Operator vom Typ 'class std::basic_string<char,struct std::char_traits<char>,class std::a
    llocator<char> >' akzeptiert (oder keine geeignete Konvertierung moeglich)
    c:\programme\microsoft visual studio\myprojects\11051717\code.cpp(81) : error C2679: Binaerer Operator '>>' : Kein Operator definiert, der einen rechtsseitigen Operator vom Typ 'class std::basic_string<char,struct std::char_traits<char>,class std::a
    llocator<char> >' akzeptiert (oder keine geeignete Konvertierung moeglich)
    Fehler beim Ausführen von cl.exe.

    code.obj - 4 Fehler, 0 Warnung(en)

    Die Fehler kommen wenn ich beide Quelltexte kompilliere.



  • Hi
    für Steve O.

    #include <string>
    

    das solte das problem beheben

    mfg spjoe



  • Juhu es funktioniert. Danke. Aber wieso ist das so.


Anmelden zum Antworten