Das Gute, Alte Snake ^^



  • N290 schrieb:

    Wenn du damit meine meinst ok 🙂
    Aber wenn du die Version von MGOS meinst....
    Zeig du wie manns besser macht! 😉

    Wurde doch schon geklärt 😉
    - Nicht immer alle Segmente verschieben sondern die Runden zählen und dann so was machen:

    DrawBlock(hwnd, old_pos[round % len], COLOR_GROUND);
    

    - Wenn die Schlange die Richtung 'w' hat darf sie im nächsten Schritt nicht die Richtung 's' haben. Das sollte man überprüfen.
    - Für die repräsentation der Schlange würde sich COORD ( http://msdn.microsoft.com/en-us/library/ms682119 ) anbieten.
    - Für ein so eindeutiges C-Stil Programm sollte man printf statt std::cout nutzen.
    - Globale Variablen sind pfui! (Und wenn man sie mal brauchen sollte dann bitte static)
    - Die momentane Struktur bietet keine Möglichkeit verschiedene Wände zu implementieren. (Auch nicht das "auf der anderen Seite der Karte wieder raus kommen")
    - Nach "if" einrücken 😉

    if (foo)
      bar()
    

    - Am besten gleich noch englische Bezeichner nehmen.
    - Über das schließen der Konsole gibts nen FAQ Eintrag ( http://www.c-plusplus.net/forum/111042 ) man siehe dort Lösung 3.

    Das wars erstmal, nur Kleinigkeiten aber die gehören halt dazu 😃



  • Hier, ich habe einige Sachen geändert:
    1. Nur wenige Globale Variable
    2. englische Bezeichnungen
    3. Ringspeicher
    4. Möglichkeit für zusätzliche Wände
    5. {} und einfache If eingerückt

    #include <iostream>  
    #include <windows.h> 
    #include <conio.h>   
    
    using namespace std;
    
    void gotoxy(int x,int y);
    void setfood(void);
    
    bool board[40][20];
    int fx, fy;
    
    int main()
    {
        int snake[1000][2];
        int length = 1;
        int head = 1;
        int tail = 0;
        int hx = 1;
        int hy = 2;
        int hor = 1;
        int ver = 0;
        char key;
        int i,j;
        snake[tail][0] = hx;
        snake[tail][1] = hy;
        bool gameover = false;
        system("cls");
        for (i = 0; i < 40; i++)
        {
            gotoxy(i,0);
            cout << "+";
            gotoxy(i,19);
            cout << "+";
            board[i][0] = 1;
            board[i][19] = 1;
            for (j = 1; j < 19; j++)
            {
                if (i == 0 || i == 39)
                {
                   gotoxy(i,j);
                   cout << "+";
                   gotoxy(i,j);
                   cout << "+";
                   board[i][j] = 1;
                }
                else
                    board[i][j] = 0;
            }
        }
        setfood();
        while (!gameover)
        {
              if (kbhit())
              {
                    key = getch();
                    switch (key)
                    {
                        case 'd':
                             hor = 1;
                             ver = 0;
                             break;
                        case 'a':
                             hor = -1;
                             ver = 0;
                             break;
                        case 's':
                             hor = 0;
                             ver = 1;
                             break;
                        case 'w':
                             hor = 0;
                             ver = -1;
                             break;
                    }
              }
              hx += hor;
              hy += ver;
              if (board[hx][hy])
                   gameover = true;
              else 
              {
                   gotoxy(hx,hy);
                   cout << "O";
                   board[hx][hy] = 1;
                   snake[head][0] = hx;
                   snake[head][1] = hy;
                   head++;
                   if (head >= 1000)
                      head = 0;
                   if (hx == fx && hy == fy)
                   {
                          setfood();
                          length++;
                   }
                   else
                   {
                       board[snake[tail][0]][snake[tail][1]] = 0;
                       gotoxy(snake[tail][0],snake[tail][1]);
                       cout << " ";
                       tail++;
                       if (tail >= 1000)
                           tail = 0;
                   }
              }
              Sleep(100);
        }
        system("cls");
        cout << "Game Over!" << endl << endl
             << "Score: " << length << endl << endl
             << "Press ENTER to quit... ";
        getchar();
    }
    void gotoxy(int x,int y)
    { 
       COORD cur={x,y}; 
       SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cur); 
    }
    void setfood(void)
    {
         srand(time(NULL));
         do
         {
             fx =(rand()%38)+1; 
             fy =(rand()%18)+1;
         } while(board[fx][fy]);
         gotoxy(fx,fy);
         cout << "*";
    }
    

    Auf cout habe ich nicht verzichtet, zwar ist vieles eindeutig C-Stil, aber das braucht wieder zusätzlich Bibliotheken, wenn man sowieso iostream braucht (wen's stört, der kann's ändern).

    Das mit der gegensätzigen Richtung ist auch im Original drin, dann beist sich eben die Schlange selbst → Game Over.



  • Ich würde als Erstes:

    1. anstelle von cout direkt eine Konsolenfunktion für die Ausgabe benutzen

    2. anstelle board zu verwalten (soweit ich das überblicke, wird dieses Array nur zur Kollisionsüberprüfung benötigt), direkt via Konsolenfunktion auslesen, ob/was an der entsprechenden Stelle steht

    3. srand gehört ein einziges Mal ausgeführt, deshalb raus da und einmal zu Beginn von main aufrufen



  • @MGDOS schöner Code!
    Danke für Posten!
    🙂

    @cooky Ok.... das hab ich jetzt nicht erwartet 😉



  • Belli schrieb:

    Ich würde als Erstes:

    1. anstelle von cout direkt eine Konsolenfunktion für die Ausgabe benutzen

    2. anstelle board zu verwalten (soweit ich das überblicke, wird dieses Array nur zur Kollisionsüberprüfung benötigt), direkt via Konsolenfunktion auslesen, ob/was an der entsprechenden Stelle steht

    3. srand gehört ein einziges Mal ausgeführt, deshalb raus da und einmal zu Beginn von main aufrufen

    1. Stimmt wir sind ja hier im Windows Forum, das wäre natürlich optimal.
    2. Hm.. ich würde das so lassen 😃
    3. 👍 Gar nicht gesehen.

    @MGOS
    In Snake darf man die Richtung aber einfach nicht umkehren. Diese "falsche" Eingabe muss also ignoriert werden und darf nicht mit Spielende bestraft werden. Das gehört bei Snake halt einfach dazu 😉

    Zudem brauchst Du für printf keine extra header. <iostream> raus und <stdio.h> rein. Aber wie gesagt, direkte API Ausgabe ist natürlich die beste Lösung.

    Edit:
    bool ist auch C++, das muss raus 😃
    Zudem sind immer noch globale Variablen am Start -> könnte man aber problemlos als Parameter übergeben.



  • cooky451 schrieb:

    Belli schrieb:

    2. anstelle board zu verwalten (soweit ich das überblicke, wird dieses Array nur zur Kollisionsüberprüfung benötigt), direkt via Konsolenfunktion auslesen, ob/was an der entsprechenden Stelle steht

    2. Hm.. ich würde das so lassen 😃

    Zudem sind immer noch globale Variablen am Start -> könnte man aber problemlos als Parameter übergeben.

    Die wären auf diese Weise überflüssig ...



  • Das mit srand kann ich in main() machen - stimmt
    Das mit der Richtungsumkehrung ändere ich wenn ihr wollt auch noch.

    Das Array hab ich deswegen genommen, da man mit ihm z. B. auch 'versteckte' Hindernisse einbauen kann.
    printf("") könnte ich auch nehmen, aber wenn man das Programm irgendwo einbauen möchte (in C++ Code), braucht man wieder beide Header.

    Wartet, ich lade heute Mittag eine Überarbeitung hoch.



  • So...
    Veränderungen:

    1. Keine globalen Variablen
    2. printf statt cout
    3. srand in main()
    4. Richtungsumkehrung wird verhindert
    5. Console schließt mit FCIB()

    #include <stdio.h> 
    #include <time.h> 
    #include <windows.h> 
    #include <conio.h>   
    
    void gotoxy(int x,int y);
    void setfood(bool board[40][20], int* fx, int* fy);
    
    int main()
    {
        srand(time(NULL));
        bool board[40][20];
        int snake[1000][2];
        int length = 1;
        int head = 1;
        int tail = 0;
        int hx = 1;
        int hy = 2;
        int hor = 1;
        int ver = 0;
        int fx, fy;
        char key;
        int i,j;
        snake[tail][0] = hx;
        snake[tail][1] = hy;
        bool gameover = false;
        system("cls");
        for (i = 0; i < 40; i++)
        {
            gotoxy(i,0);
            printf("+");
            gotoxy(i,19);
            printf("+");
            board[i][0] = 1;
            board[i][19] = 1;
            for (j = 1; j < 19; j++)
            {
                if (i == 0 || i == 39)
                {
                   gotoxy(i,j);
                   printf("+");
                   gotoxy(i,j);
                   printf("+");
                   board[i][j] = 1;
                }
                else
                    board[i][j] = 0;
            }
        }
        setfood(board,&fx,&fy);
        while (!gameover)
        {
              if (kbhit())
              {
                    key = getch();
                    switch (key)
                    {
                        case 'd':
                             if (hor == 0)
                             {
                                hor = 1;
                                ver = 0;
                             }
                             break;
                        case 'a':
                             if (hor == 0)
                             {
                                hor = -1;
                                ver = 0;
                             }
                             break;
                        case 's':
                             if (ver == 0)
                             {
                                hor = 0;
                                ver = 1;
                             }
                             break;
                        case 'w':
                             if (ver == 0)
                             {
                                hor = 0;
                                ver = -1;
                             }
                             break;
                    }
              }
              hx += hor;
              hy += ver;
              if (board[hx][hy])
                   gameover = true;
              else 
              {
                   gotoxy(hx,hy);
                   printf("O");
                   board[hx][hy] = 1;
                   snake[head][0] = hx;
                   snake[head][1] = hy;
                   head++;
                   if (head >= 1000)
                      head = 0;
                   if (hx == fx && hy == fy)
                   {
                          setfood(board,&fx,&fy);
                          length++;
                   }
                   else
                   {
                       board[snake[tail][0]][snake[tail][1]] = 0;
                       gotoxy(snake[tail][0],snake[tail][1]);
                       printf(" ");
                       tail++;
                       if (tail >= 1000)
                           tail = 0;
                   }
              }
              Sleep(100);
        }
        system("cls");
        printf("Game Over! \n\n");
        printf("Score: %d\n\n",length);
        printf("Press ENTER to quit... ");
        FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); 
        getchar();
    }
    void gotoxy(int x,int y)
    { 
       COORD cur={x,y}; 
       SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cur); 
    }
    void setfood(bool board[40][20], int* fx, int* fy)
    {
         do
         {
             *fx =(rand()%38)+1; 
             *fy =(rand()%18)+1;
         } while(board[*fx][*fy]);
         gotoxy(*fx,*fy);
         printf("*");
    }
    

    und btw: da iostream jetzt fehlt, brauche ich ctime und cstdio!



  • MGOS schrieb:

    und btw: da iostream jetzt fehlt, brauche ich ctime und cstdio!

    Wie wärs mit stdio.h und time.h ? 😃



  • Ich habe ebenfalls mal ein Snake-Spiel in der DOS-Box entwickelt. Wer daran interessiert ist, kann es sich hier herunterladen.

    Wenn jemand den Quellcode haben möchte, soll er mir eine E-Mail an miguel-gonzalez@gmx.de schicken.



  • Mit was hast du die farben gemacht?

    Gutes Spiel!



  • Farben sind ganz einfach - Funktion textcolor() machen mit Windows.h

    #include <stdio.h> 
    #include <windows.h> 
    
    void textcolor( WORD color )           //Funktion fuer Farbe 
    { 
        SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), color ); 
    } 
    int main() 
    { 
      int farbe;
      for (farbe = 0; farbe <= 255;farbe++){
        textcolor(farbe); 
        printf("\n Diese farbe ist: %x", farbe); 
    }
        system("Pause");
        return(0); 
    }
    


  • Ahhh 😃
    Von dem Forum kann man mal was lernen 🙂


Anmelden zum Antworten