4
\$\begingroup\$

Is there any way to improve it?

#include <iostream>
#include <windows.h>
#include"MMSystem.h"
#include <conio.h>
#include <fstream>
#include <ctime>
#include <string>
#include <string.h>

using namespace std;

/****************************************************/

/**<Stores Player's Name and Score>*/
struct player
{
    string name;
    int score;
};
/****************************************************/
const int mx1=1,mx2=36,my1=1,my2=20;
int D=3;
int x=(mx2+mx1)/2;
int y=(my2+my1)/2;
bool running=true;
player current;
const int Total_Players=10;
unsigned int z=0;
player high[Total_Players+1];
char MUSIC[100];


/****************************************************/
/**< Function to go to any (x,y) cordinates on console screen */
void gotoxy(int x,int y)
{
    /**< A predefined data type(struct) of windows.h */
    COORD point;
    point.X=x;
    point.Y=y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),point);
}
/***************************************************/
/**< Prints Highscore >**/
void score_print()
{
    system("CLS");
    running=true;
    gotoxy(30,1);
    cout<<"HIGH-SCORES";
    for(int i=0;i<Total_Players;i++)
    {
        gotoxy(20,3+i+i);
        cout<<i+1<<".";
        gotoxy(28,3+i+i);
        cout<<high[i].name;
        gotoxy(52,3+i+i);
        cout<<high[i].score<<endl;
    }
    gotoxy(20,(2*Total_Players)+3);
    cout<<"Press Enter to go to main menu";
    while(running)
    {
        if(getch()==13)
            running=false;
    }

}
/****************************************************/
/**< class of game */
class game
{
    /**< Variables used */
    char FOOD;
    int food;
    int X[100],Y[100],X1[100],Y1[100];
    char BODY[100];
    int XF,YF;
    int flag;
    int temp;
    /****************************************************/
    /**< Function Prints the Map Boundaries */
    void printmap()
    {
        char B;
        B=218;
        gotoxy(mx1,my1);
        cout<<B;
        B=191;
        gotoxy(mx2,my1);
        cout<<B;
        B=217;
        gotoxy(mx2,my2);
        cout<<B;
        B=192;
        gotoxy(mx1,my2);
        cout<<B;
        for(int i=mx1+1;i<my2;i++)
        {
            B=179;
            gotoxy(mx1,i);
            cout<<B;
            gotoxy(mx2,i);
            cout<<B;
        }
        for(int i=my1+1;i<mx2;i++)
        {
             B=196;
             gotoxy(i,my1);
             cout<<B;
             gotoxy(i,my2);
             cout<<B;
        }
        gotoxy(mx2+5,5);
        cout<<"PRESS Q TO QUIT";
        gotoxy(mx2+5,7);
        cout<<"PRESS ENTER TO PAUSE";
    }

    /****************************************************/
    /**< Function to read key press' */
    void keypress(int &x,int &y)
    {
    /**<
         W      UP
        A+D LEFT+RIGHT
         S     DOWN
     */
        int M=getch();
        if(M==224)
            M=getch();
        /**< UP  */
        if((M==72||M==119)&&y!=1)
        {
            y=-1;
            x=0;
        }
        /**< DOWN */
        if((M==80||M==115)&&y!=-1)
        {
            y=1;
            x=0;
        }
        /**< RIGHT */
        if((M==77||M==100)&&x!=-1)
        {
            x=1;
            y=0;
        }
        /**< LEFT */
        if((M==75||M==97)&&x!=1)
        {
            x=-1;
            y=0;
        }
        /**< Q - TO QUIT */
        if(M==113)
        {
            running=false;
        }
        /**< I - FOR INSANE DIFFICULTY */
        if(M==105)
        {
            /**< TOGGLE ON */
            if(flag==0)
            {
                temp=D;
                D=50;
                flag=1;
            }
            /**< TOGGLE OFF */
            else if(flag==1)
            {
                D=temp;
                flag=0;
            }
        }
        /**< ENTER - TO PAUSE */
        if(M==13)
        {
            system("CLS");
            gotoxy(25,5);
            cout<<"PAUSED";
            gotoxy(25,7);
            system("PAUSE");
            system("CLS");
        }
    }
    /****************************************************/
    /**< Function randomises food spawn location, updates score, increases snake length if food is eaten etc */
    void Food(int x,int y)
    {
        /**< if food eaten( Head of snake meets food) */
        if(XF==x&&YF==y)
        {
            F:
            /**< get random coord. */
            XF=rand()%(mx2-1)+(mx1+1);
            YF=rand()%(my2-1)+(my1+1);
            /**< to stop spawn on boundary */
            if(XF==mx1||XF==mx2||YF==my1||YF==my2)
                goto F;
            /**< to stop spawn on snake's body */
            for(int i=0;i<100;i++)
            {
                if(X[i]==XF&&Y[i]==YF)
                    goto F;
            }
            /**< increase score */
            food++;
            /**< add body piece */
            BODY[food-1]='o';
            X[food]=X[food-1];
            Y[food]=Y[food-1]+1;

        }
        /**< print the food */
        gotoxy(XF,YF);
        cout<<FOOD;
        gotoxy(mx2+5,9);
        cout<<"Score: "<<food;
    }
/****************************************************/
/**< Function to update high-score >**/
void update_highscore()
{
    fstream myfile;
    getline(cin,current.name);
    current.score=food;
    while(current.name.length()<z)
    {
        current.name+=" ";
    }
    for(int i=0;i<Total_Players;i++)
    {
        if(current.score>=high[i].score)
        {
            for(int j=Total_Players-1;j>=i;j--)
            {
                high[j+1] = high[j];
            }
            high[i] =  current;
            break;
        }
    }
    myfile.open("bin\\score.txt");
    if(myfile.is_open())
    {
        for(int i=0;i<Total_Players;i++)
        {
            myfile<<" "<<i+1<<","<<high[i].name<<","<<high[i].score<<endl;
        }
        myfile.close();
    }
}

public:
    game()
    {
        FOOD=153;
        food=3;
        XF=YF=10;
        flag=0;
        temp=D;
        /**< initialization of all values for body and its coordinates */
        for(int i=0;i<100;i++)
        {
            BODY[i]=' ';
            X1[i]=0;
            Y1[i]=-1;
            X[i]=x;
            Y[i]=y+i;
        }
    }
    /*****************************************************/
    /**< moves the snake's body and basically runs the game physics */
    void body_move_print()
    {
        food=3;
        system("CLS");
        if(D==3)
            D=500;
        gotoxy(x,y);
        int i=0;
        int k=0;
        BODY[0]=BODY[1]=BODY[2]='o';
        running=true;
        /**< running snake */
        while(running)
        {
            printmap();
            Sleep(D);
            if(kbhit())
            {
                keypress(X1[0],Y1[0]);
            }
            gotoxy(0,0);
            for(i=0;i<=food;i++)
            {
                X[i]+=X1[i];
                Y[i]+=Y1[i];
                gotoxy(X[i],Y[i]);
                cout<<BODY[i];
            }
            for(i=3;i<food;i++)
            {
                if(X[0]==X[i]&&Y[0]==Y[i])
                {
                    k=10;
                    break;
                }
            }
            for(i=food;i>0;i--)
            {
                X1[i]=X1[i-1];
                Y1[i]=Y1[i-1];
            }
            Food(X[0],Y[0]);
            if(X[0]==mx1||X[0]==mx2||Y[0]==my1||Y[0]==my2||k==10)
            {
                running=false;
                i=600;
                while(i<1100)
                {
                    Beep(i,50);
                    i+=150;
                }
            }
        }
        /**< game over */
        for(i=0;i<10;i++)
        {
            if(kbhit())
            {
                if(getch()==13)
                    break;
            }
            Sleep(100);
            system("CLS");
            gotoxy(30,20-i);
            cout<<"GAMEOVER!!";
            gotoxy(30,20-i+1);
            cout<<"SCORE: "<<food;
        }
        system("CLS");
        gotoxy(30,20-i);
        cout<<"GAMEOVER!!";
        gotoxy(30,20-i+1);
        cout<<"SCORE: "<<food;
        gotoxy(30,20-i+2);
        cout<<"NAME:";
        update_highscore();
        gotoxy(30,20-i+3);
        system("PAUSE");
        score_print();
    }
};

/****************************************************/
/**< sets difficulty level */
void diff()
{
    system("CLS");
    int L;
    D=3;
    char D_=221;
    int i=1,j=1;
    for(i=0;i<D;i++)
    {
        gotoxy(33+i,9);
        cout<<D_;
        gotoxy(33,11);
        cout<<"-";
        gotoxy(41,11);
        cout<<"+";
        cout<<"\n\n     LEFT or RIGHT ARROWS to increase or decrease difficulty. Enter to select";
    }
    while(j)
    {

        if(kbhit())
        {
            L=getch();
            if(L==224)
                L=getch();
            if(L==77&&D<=8)
                D++;
            else if(L==75&&D>1)
                D--;
            else if(L==13)
            {
                D=800-D*75;
                break;
            }
            system("CLS");
            for(i=0;i<D;i++)
            {
                gotoxy(33+i,9);
                cout<<D_;
                gotoxy(33,11);
                cout<<"-";
                gotoxy(41,11);
                cout<<"+";
                cout<<"\n\n     LEFT or RIGHT ARROWS to increase or decrease difficulty. Enter to select";
            }
        }
    }

}

/****************************************************/
/**< high score table maker>*/
void score()
{
    fstream myfile;
    string X[Total_Players];
    myfile.open("bin\\score.txt");
    if(myfile.is_open())
    {
        while(!myfile.eof())
        {

            for(int i=0;i<Total_Players;i++)
            {
                getline(myfile,X[i],',');
                getline(myfile,high[i].name,',');
                myfile>>high[i].score;

            }
        }
        myfile.close();
    }
    for(int i=0;i<Total_Players;i++)
    {
        if(z<high[i].name.length())
        {
            z=high[i].name.length();
        }
    }
}
/****************************************************/
/**< Sound System >**/
/**< 1. Plays the music >**/
void sound_play()
{
    /**< This line plays the background music on a loop >**/
    PlaySound(MUSIC, NULL, SND_ASYNC|SND_FILENAME|SND_LOOP);
}

/**< Lets you choose the song >**/
void music_select()
{
    int L=0,y=5;
    running=true;
    system("CLS");
    gotoxy(30,3);
    cout<<"/**Song List**/";
    gotoxy(23,5);
    cout<<"1. What does the fox say - Ylvis";
    gotoxy(23,7);
    cout<<"2. Where my baes at - Miranda Sings";
    gotoxy(23,9);
    cout<<"3. Assassin's Creed Unity Theme";
    gotoxy(10,11);
    cout<<"*UP or DOWN to Navigate. ENTER to select. BACKSPACE to go back.*";
    gotoxy(20,y);
    cout<<"->";
    while(running)
    {
        if(kbhit())
        {
            L=getch();
            if(L==224)
                L=getch();
            if(L==72)
            {
                if(y==5)
                    y=9;
                else
                    y=y-2;
            }
            else if(L==80)
            {
                if(y==9)
                    y=5;
                else
                    y=y+2;
            }
            else if(L==13)
            {
                if(y==5)
                {
                    strcpy(MUSIC,"What_Does_The_Fox_Say.wav");
                    sound_play();
                }
                else if(y==7)
                {
                    strcpy(MUSIC,"bin\\Where_My_Baes_At.wav");
                    sound_play();
                }
                else if(y==9)
                {
                       strcpy(MUSIC,"bin\\Assassin's_Creed_Unity_Theme.wav");
                       sound_play();
                }
            }
            else if(L==8)
            {
                running=false;
            }
            system("CLS");
            gotoxy(30,3);
            cout<<"/**Song List**/";
            gotoxy(23,5);
            cout<<"1. What does the fox say - Ylvis";
            gotoxy(23,7);
            cout<<"2. Where my baes at - Miranda Sings";
            gotoxy(23,9);
            cout<<"3. Assassin's Creed Unity Theme";
            gotoxy(10,11);
            cout<<"*UP or DOWN to Navigate. ENTER to select. BACKSPACE to go back.*";
            gotoxy(20,y);
            cout<<"->";
        }

    }
}

/****************************************************/
/**< main menu of game */
void menu()
{
    start:
    int L=0,y=7;
    running=true;
    system("CLS");
    gotoxy(30,5);
    cout<<"/****SNAKE****/";
    gotoxy(30,7);
    cout<<"*Start Game";
    gotoxy(30,9);
    cout<<"*Difficulty";
    gotoxy(30,11);
    cout<<"*Songs";
    gotoxy(30,13);
    cout<<"*High-score";
    gotoxy(30,15);
    cout<<"*Exit";
    gotoxy(15,17);
    cout<<"Press UP or DOWN to navigate and ENTER to select";
    gotoxy(30,19);
    cout<<"/*HELP*/";
    gotoxy(15,21);
    cout<<"*Use ARROW KEYS or W,A,S,D to move the snake.";
    gotoxy(15,22);
    cout<<"*Q to pause.";
    gotoxy(15,23);
    cout<<"*ENTER to exit into menu.";
    gotoxy(27,y);
    cout<<"->";
    while(running)
    {
        if(kbhit())
        {
            L=getch();
            if(L==224)
                L=getch();
            if(L==72)
            {
                if(y==7)
                    y=15;
                else
                    y=y-2;
            }
            else if(L==80)
            {
                if(y==15)
                    y=7;
                else
                    y=y+2;
            }
            else if(L==13)
            {
                if(y==7)
                    running=false;
                else if(y==9)
                {
                    diff();
                    goto start;
                }
                else if(y==11)
                {
                    music_select();
                    goto start;
                }
                else if(y==13)
                {
                    score_print();
                    goto start;
                }
                else if(y==15)
                {
                    system("CLS");
                    exit(0);
                }
            }
            system("CLS");
            gotoxy(30,5);
            cout<<"/****SNAKE****/";
            gotoxy(30,7);
            cout<<"*Start Game";
            gotoxy(30,9);
            cout<<"*Difficulty";
            gotoxy(30,11);
            cout<<"*Songs";
            gotoxy(30,13);
            cout<<"*High-score";
            gotoxy(30,15);
            cout<<"*Exit";
            gotoxy(15,17);
            cout<<"Press UP or DOWN to navigate and ENTER to select";
            gotoxy(30,19);
            cout<<"/*HELP*/";
            gotoxy(15,21);
            cout<<"*Use ARROW KEYS or W,A,S,D to move the snake.";
            gotoxy(15,22);
            cout<<"*Q to pause.";
            gotoxy(15,23);
            cout<<"*ENTER to exit into menu.";
            gotoxy(27,y);
            cout<<"->";
        }
    }
}

/****************************************************/

int main()
{
    /**<Initializing the song for first run >**/
    strcpy(MUSIC,"bin\\What_Does_The_Fox_Say.wav");
    sound_play();

    start:
    score();
    menu();
    srand(time(0));
    game GAME;
    GAME.body_move_print();
    goto start;
    getch();
    return 0;
}
\$\endgroup\$
  • \$\begingroup\$ Also, there's (almost) always room for improvement. Is there anything specific you're looking for? Your current statement isn't wrong, but performance/memory/maintainability improvements aren't the same and improving one can make the other worse. \$\endgroup\$ – Mast Jun 16 '15 at 9:04
  • 1
    \$\begingroup\$ Thanks for telling me @Mast . Yeah .. I did find a problem in the performance. It lags a little if I'm not running it straight out of the IDE \$\endgroup\$ – Devang Jayachandran Jun 16 '15 at 9:06
  • 2
    \$\begingroup\$ I'll update the question as soon as possible \$\endgroup\$ – Devang Jayachandran Jun 16 '15 at 9:06
  • \$\begingroup\$ @DevangJayachandran: As a side not. By placing the code here you are also placing it under the CC license (see the link at the bottom of the page). The cost of us doing a review is that you let everybody use your code. \$\endgroup\$ – Martin York Jun 16 '15 at 14:53
  • \$\begingroup\$ I don't mind that. :P \$\endgroup\$ – Devang Jayachandran Jun 16 '15 at 15:15
3
\$\begingroup\$

There are many improvements that could be applied to this code. As it stands, it has several issues or "code smells":

  • Use of global data: You are using C++, which supports Object-Oriented programming, and you also already make use of classes in your program, so why declare a bunch of global data when all that could very easily be properly scoped into classes or functions?

  • Very weak names for global variables: To further aggravate the issue of the globals, some are declared with ludicrous names, such as x, y and D. Those will not only clash with other names you might want to declare, but also convey no meaning or information. The more visible is the scope of a variable, the better and more descriptive its name should be. Loop counter variables are commonly named i, j and k because they have tiny scopes (and for historical reasons, also).

  • Magic numbers: Your code is swamped with magic numbers, which makes it very hard to understand and create a mental model of the thing.

  • Using namespace: Very questionable practice to say the least. Read more about it here.

  • Use of goto: In main(), where a simple for(;;) or while would do. That goto also threads over the declaration of GAME, which is a usage style full or caveats and not well known by most programmers. A 'traditional' loop would be much clearer. There are other instances too that seem to exist because you've failed to better divide the code into functions.

  • Lack of spacing makes it very hard to read: Compare this:

    if(X[0]==mx1||X[0]==mx2||Y[0]==my1||Y[0]==my2||k==10)
    

    To a more spaced equivalent:

    if (X[0] == mx1 || X[0] == mx2 || Y[0] == my1 || Y[0] == my2 || k == 10)
    

My opinion, but I think the issues mentioned above makes it hard to review the code in more detail. So my suggestion would be that you first fix those issues and then post a followup question to get more reviews. Bet of luck to you.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ There is no goto above game.. That's making it public \$\endgroup\$ – Devang Jayachandran Jun 17 '15 at 15:48
  • 1
    \$\begingroup\$ @DevangJayachandran There is a goto that jumps over the initialization of an instance of the game class inside 'main'. That's what I meant. \$\endgroup\$ – glampert Jun 17 '15 at 15:54
  • \$\begingroup\$ Where exactly do u mean? \$\endgroup\$ – Devang Jayachandran Jun 17 '15 at 15:58
  • \$\begingroup\$ Aah! Works fine in mingw \$\endgroup\$ – Devang Jayachandran Jun 17 '15 at 15:59
  • 1
    \$\begingroup\$ @DevangJayachandran GOTO is still considered harmful. Even when not considering all other points against it, it's not idiomatic C++. \$\endgroup\$ – Mast Jun 18 '15 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.