Exit Funktion für 4 Gewinnt Spiel



  • hi leute

    habe hier ein 4gewinnt spiel.

    ich wollte das man während des spieles jederzeit durch das drücken z.b von Q zurück ins menü gelangt.

    Kriege das irgendwie nicht hin.

    Hat jemand ein Tipp oder ne Idee?

    hier der Code:

    //-----------------------------------------------------------------------------
    // INCLUDES
    //-----------------------------------------------------------------------------
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <assert.h>
    #include <windows.h>
    #include <conio.h>
    #include <iostream.h>
    
    const unsigned short player1 = 14;
    const unsigned short player2 = 10;
    const unsigned short text = 15;
    const unsigned short bannerf1 = 15;
    const unsigned short bannerf2 = 14;
    
    //-----------------------------------------------------------------------------
    // TYPEN
    //-----------------------------------------------------------------------------
    
    enum BoardCell                /// Belegungsarten einer Spielbrettzelle
    {
       NO_PIECE,                /// Kein Spielstein
       PLAYER1,                /// Spielstein von Spieler 1
       PLAYER2                /// Spielstein von Spieler 2
    };
    
    //-----------------------------------------------------------------------------
    // KONSTANTEN (Konfiguration des Spieles)
    //-----------------------------------------------------------------------------
    
    const int PLAYFIELD_WIDTH  = 7;     /// Breite des Spielfeldes
    const int PLAYFIELD_HEIGHT = 6;    /// Höhe des Spielfeldes
    const int WIN_COUNT        = 4;   /// Anzahl der konsekutiven Steine für eine Gewinnsituation
    
    //-----------------------------------------------------------------------------
    // GLOBALE VARIABLEN
    //-----------------------------------------------------------------------------
    
    BoardCell board[PLAYFIELD_HEIGHT][PLAYFIELD_WIDTH]; /// Spielbrett
    int numFreeCells[PLAYFIELD_WIDTH];                 /// Anzahl der freien Zellen in einer Spalte
    
    //-----------------------------------------------------------------------------
    // FUNKTIONEN
    //-----------------------------------------------------------------------------
    
    void color(unsigned short color)
    {
        HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(hcon,color);
    }
    
    void initBoard()
    {
    
      for ( int column = 0; column < PLAYFIELD_WIDTH; column ++ ) // Über die Spalten iterieren
      {
      for ( int row = 0; row < PLAYFIELD_HEIGHT; row ++ )   // Über die Zeilen iterieren
        {
         board[row][column] = NO_PIECE;       // Inhalt der Spielfeldzelle zurücksetzen
        }
         numFreeCells[column] = PLAYFIELD_HEIGHT;    // Anzahl der freien Zellen pro Spalte initialisieren
       }
     }
    
    //-----------------------------------------------------------------------------
    
    void printBoard()
    {
        for ( int row = 0; row < PLAYFIELD_HEIGHT; row ++ )   // Über die Zeilen iterieren
        {
        for ( int column = 0; column < PLAYFIELD_WIDTH; column ++ )   // Über die Spalten iterieren
            {
    
                if (board[row][column] == PLAYER1)          // Inhalt der Zelle ausgeben
                {
                    color(player1);
                    cout << "X";
                    color(text);
                }
                else if (board[row][column] == PLAYER2)
                {
                    color(player2);
                    cout << "O";
                    color(text);
                }
                else
                    cout << " ";
    
            }
    
            cout << endl;                     // Nächste zeile
        }
    
        for (int column = 0; column < PLAYFIELD_WIDTH; column ++ )     // Unteren Spielfeldrand ausgeben
        {
            cout << "-";
        }
        cout << endl;
    
        for (int column = 0; column < PLAYFIELD_WIDTH; column ++ )  // Spaltennummern ausgeben
        {
            cout << column;
        }
        cout << endl << endl;
    }
    
    //-----------------------------------------------------------------------------
    
    BoardCell getCell( int row, int column )
    {
    
        if (row >= 0 && row < PLAYFIELD_HEIGHT && column >= 0 && column < PLAYFIELD_WIDTH)
            return board[row][column];
        else
            return NO_PIECE;
    }
    
    //-----------------------------------------------------------------------------
    
    int countPieces(int row, int column, int dx, int dy, BoardCell player)
    {
    
      assert(row>=0 && row < PLAYFIELD_HEIGHT && column>=0 && column < PLAYFIELD_WIDTH); // Stelle sicher, dass Referenzposition innerhalb des Spielfeldes liegt
    
      if (getCell(row,column) == player)
      {
    
        int count = 1;       // Zähler initialisieren (mindestens 1 Stein)
    
        int sy1=row;              // Scankoordinaten
        int sx1=column;
    
        while ( getCell(sy1+dy,sx1+dx) == player )   // Erhöhe Zähler, solange von Referenzposition row,column ausgehend
        {                                           // in Richtung dy,dx weitere Steine von Spieler player folgen
    
          sy1+=dy;          // Scankoordinaten aktualisieren
          sx1+=dx;
    
          count++;         // Weiterzählen
        }
    
        int sy2=row;           // Scankoordinaten
        int sx2=column;
    
        while ( getCell(sy2-dy,sx2-dx) == player )       // Erhöhe Zähler, solange von Referenzposition row,column ausgehend
            {                                            // in Richtung -dy,-dx weitere Steine von Spieler player folgen
    
          sy2-=dy;    // Scankoordinaten aktualisieren
          sx2-=dx;
    
          count++;        // Weiterzählen
        }
    
        return count;      // Zähler zurückgeben
    
      }
      else
        return 0;
    
    }
    
    //-----------------------------------------------------------------------------
    
    bool nInARow( int row, int column, BoardCell player, int n)
    {
        assert(row >= 0 && row < 6 && column >= 0 && column < 7);
        assert(board[row][column] == player);
    
        if (countPieces(row,column,1,0,player)>=n) return true;     // Horizontaler Fall
    
        if (countPieces(row,column,0,1,player)>=n) return true;    // Vertikaler Fall
    
        if (countPieces(row,column,1,1,player)>=n) return true;    // Hauptdiagonale "\"
    
        if (countPieces(row,column,-1,1,player)>=n) return true;  // Nebendiagonale "/"
    
        return false;       // Keiner der Fälle ist eingetreten => keine Gewinnsituation
    }
    
    //-----------------------------------------------------------------------------
    
    bool boardIsFull()
    {
        for ( int column = 0; column < PLAYFIELD_WIDTH; column ++ )
        {
            if ( numFreeCells[column] > 0 ) return false;  // Falls mindestens eine nicht volle Spalte gefunden wird
            }   // so ist das Brett nicht leer
    
        return true;      // Spielbrett voll
    }
    
    void banner()
    {
           //Banner
    
            color(text);
         cout<<""<<endl;   
         cout<<" °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°"<<endl;
         color(bannerf2);
         cout<<" .............................................................................."<<endl;
         cout<<" ..##............######...########.##......##.####.##....##.##....##.########.."<<endl;
         cout<<" ..##....##.....##....##..##.......##..##..##..##..###...##.###...##....##....."<<endl;
         cout<<" ..##....##.....##........##.......##..##..##..##..####..##.####..##....##....."<<endl;
         cout<<" ..##....##.....##...####.######...##..##..##..##..##.##.##.##.##.##....##....."<<endl;
         cout<<" ..#########....##....##..##.......##..##..##..##..##..####.##..####....##....."<<endl;
         cout<<" ........##.....##....##..##.......##..##..##..##..##...###.##...###....##....."<<endl;
         cout<<" ........##......######...########..###..###..####.##....##.##....##....##....."<<endl;
         cout<<" .............................................................................."<<endl;
         color(text);
         cout<<" °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°";
         color(bannerf2);
         cout<<" by GSGT Games ";
         color(text);
         cout<<" °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°"<<endl;
         color(bannerf1);
    
    }
    
    void anleitung()
    {
         system("cls");
         banner();
    
        cout << "" << endl;
        cout << "" << endl;
        cout<<"\t\t\t\t *************"<<endl;
        cout<<"\t\t\t\t *";
        cout<<" Anleitung ";
        cout<<"*"<<endl;
        cout<<"\t\t\t\t *************"<<endl;
    
       cout<<""<<endl;  
       cout<<""<<endl;
       cout<<""<<endl;
       cout<<"  Ziel des Spieles ist es, als erster 4 Steine seiner Farbe in eine"<<endl;
       cout<<"  Reihe zu bekommen."<<endl;
       cout<<""<<endl;
       cout<<"  Die Steinfarben sind f\x81r Spieler 1";
       color(player1);
       cout<<" (GELB)";
       color(text);
       cout<<" und Spieler 2";
       color(player2);
       cout<<" (GR\x9aN)"<<endl;
       color(text);
       cout<<""<<endl;
       cout<<"  Es wird abwechselnd je 1 Stein der eigenen Farbe"<<endl;
       cout<<"  in die Felder fallen gelassen."<<endl;
       cout<<""<<endl;
       cout<<"  Dies kann man tun mit den Tasten 0,1,2,3,4,5,6. "<<endl;
       cout<<"  Wobei 0 f\x81r die ganz linke Spalte sowie 6 f\x81r ganz rechte Spalte steht."<<endl;
       cout<<"  Durch Strategie und Taktik versucht man nun, mit den eigenen Steinen"<<endl;
       cout<<"  eine 4er-Reihe zu bilden."<<endl;
       cout<<""<<endl;
       cout<<"  Die Reihen k\x94nnen entweder"<<endl;
       cout<<"  -senkrecht"<<endl;
       cout<<"  -waagerecht"<<endl;
       cout<<"  -diagonal"<<endl;
       cout<<"  angeordnet sein."<<endl;
       cout<<""<<endl;
       cout<<"  Dabei darf man aber nie den Gegner aus den Augen lassen,"<<endl;
       cout<<"  denn wenn er eine Zwickm\x81hle bildet, kann bald alles zu sp\x84t sein!"<<endl;
       cout<<"  Man muss also gleichzeitig verhindern, dass er zuvor eine"<<endl;
       cout<<"  4er-Reihe zustande bringt."<<endl;
       cout<<""<<endl;
       cout<<""<<endl;
       cout<<""<<endl;
       cout<<"                Beliebige Taste dr\201cken um zum Men\201 zugelangen"<<endl;
         getch();
    
         system("cls");
    }
    
    int spiel(void)
    {
        char taste;
    
        banner();
    
        initBoard();          // Initialisiere das Spielbrett und gebe es aus
        printBoard();
    
        BoardCell player = PLAYER1;    // Aktueller Spieler
    
        while ( true )
        {
    
            int column;    // Fordere Spieler zur Eingabe eines Spielzuges auf
    
            if (player == PLAYER1) 
    { 
    color(player1);
    cout << " Spieler 1:" << endl;
    color(text);
    }else 
    { 
    color(player2);
    cout << " Spieler 2:" << endl;
    color(text);
    }
    
            int res = scanf("%d", &column);
    
            while ( res != 1 || column < 0 || column >= PLAYFIELD_WIDTH || numFreeCells[column] == 0 )        // Wiederhole, falls Eingabe ungültig
               {      // (kein Integer eingegeben  oder  ungültige Spaltennummer  oder  Spalte bereits voll)
                if ( res != 1 )
                    fflush(stdin);
                cout << "Ung\201ltig. Nochmal : ";
                res = scanf("%d", &column);
            }
    
            numFreeCells[column] --;             // Aktualisiere den Zustand des Spielbrettes
            int row = numFreeCells[column];
            board[row][column] = player;
    
            system("cls");
            banner();
            printBoard();                 // Gebe das Spielbrett aus
    
            if ( nInARow(row, column, player,WIN_COUNT) )  // Beende das Spiel, falls eine Gewinnsituation aufgetreten ist oder das
                  {                         // Spielbrett voll ist
                printf(" Spieler %d hat gewonnen!\n", player);
                getch();
                break;
            }
            else if ( boardIsFull() )
            {
                printf("Unentschieden!\n");
                getch();
                break;
            }
    
            player = (player == PLAYER1) ? PLAYER2 : PLAYER1;             // der nächste Spieler ist an der Reihe
    
        }
    }
    
    //-----------------------------------------------------------------------------
    // MAIN
    //-----------------------------------------------------------------------------
    
    int main()           /// Hauptprogramm
    {
        char taste;
    
        menue:
    
        banner();
    
        cout << "" << endl;
        cout << "" << endl;
        cout<<"\t\t\t\t *************"<<endl;
        cout<<"\t\t\t\t *";
        cout<<"    Men\201 ";
        cout<<"  *"<<endl;
        cout<<"\t\t\t\t *************"<<endl;
    
        cout << "" << endl;
        cout << "" << endl;
        cout << "" << endl;
        cout << " (S)piel starten" << endl;
         cout << "" << endl;
        cout << " (A)nleitung" << endl;
         cout << "" << endl;
        cout << " (B)eenden" << endl;
    
        taste = getch();
    
        switch(taste)
        {
            case 'S':
            case 's':
                 system("cls");
                 spiel();
                 system("cls");
                 goto menue;
    
            break;
    
            case 'A':
            case 'a':
                 anleitung();
                 system("cls");
                 goto menue;
            break;
    
            case 'B':
            case 'b':
                 return 0;
    
            default:
                 system("cls");
                 goto menue;
        }
    
        return 0;
    }
    


  • Vielleicht mit GetAsyncKeyState?



  • hmm gute frage. kenne mich damit eigentlich so gut wie gar nicht aus.

    Habe c++ erst seit 2-3monate in der schule.davor noch nie was mit gemacht


  • Administrator

    Ich hoffe mal, dass dein Lehrer dir nicht solches C++ beigebracht hat 😮

    Eine Tastenabfrage ist in C++ grundsätzlich nicht möglich. Über die WinAPI, welche du bereits zum Teil verwendest, kann man aber eben GetAsyncKeyState verwenden:
    http://msdn.microsoft.com/en-us/library/ms646293.aspx

    Du könntest es aber auch einfacher machen und zum Beispiel beim Abfragen der Kolonne eine negative Zahl als Abbruch deuten 😉

    Grüssli



  • ja die seite hatte ich vorhin auch gegooglet. aber leider weiss ich damit nicht viel anzufangen


  • Administrator

    Harald44 schrieb:

    ja die seite hatte ich vorhin auch gegooglet. aber leider weiss ich damit nicht viel anzufangen

    Dann frag was du nicht verstehst. Oder vielleicht hilft dir dieses Beispielprogramm:

    #include <windows.h>
    
    int main()
    {
      while(!GetAsyncKeyState(0x41));
    
      return 0;
    }
    

    Das Programm läuft, bis jemand die Taste A drückt. Sowas ist zwar eher eine schlecht Methode, da es Polling ist und dadurch schnell zu einem Busy Waiting mutieren kann, wenn man nicht aufpasst (im Beispielcode ist es der Fall):
    http://de.wikipedia.org/wiki/Aktives_Warten
    http://en.wikipedia.org/wiki/Busy_waiting

    Aber da du Anfänger bist, will ich mal nicht komplexere Methoden vorschlagen. Du solltest sowieso wohl zuerst ein sinnvolles C++ Buch kaufen und vernünftiges C++ lernen ...

    Grüssli


Anmelden zum Antworten