Thursday, 14 March 2013

SNAKE game using concept of Linked list - Graphics in C

This is tutorial for  creating a game using graphics in c.
If you know some concept of linked list then it will be very easy to understand. This is not standard way to create this particular. But, I have made this program to implement concept of Linked list !!
This is logical right?  when you need to increase length of snake in the game you can just add one item to the linked list !! this is it.
Thi
Download source code from here
If you you are working on windows 7.then you will need DosBox to run this program.

Structures :


struct loc
{
int x,y;
};

struct snake
{
struct loc sloc;
struct snake *link;
char dir;
};

struct game_data
{
int score;
int no_food;

};
struct game_data gd={0,0};

struct limit
{
int lx1,ly1,lx2,ly2;
};
struct limit l={96,96,404,404};


struct food
{
struct loc floc;
};



  • Structure "loc" have 2 integer variables to save x and y coordinates.
  • Structure "snake" is basically a linked list , new node of this structure will be created when snake will increase in length.
  • "game_data" will store score and number of food consumed by snake
  • "limit" defines the boundary of rectangle in which snake can move. crossing this limits will result in game over.
  • "food" contains coordinates of food to be displayed
  



Functions :

  • "draw" : This function will draw whole screen. which includes,
    1. Rectangular Boundary limits
    2. snake
    3. food
    draw(struct snake *head,struct food *f)
    {
    
    struct snake *temp;
    temp=head;
    
    rectangle(96,96,404,404);
    rectangle(98,98,402,402);
    rectangle(100,100,400,400);
    setfillstyle(9,13);
    bar(temp->sloc.x-6,temp->sloc.y-6,temp->sloc.x+6,temp->sloc.y+6);
    temp=temp->link;
    setfillstyle(9,2);
    while(temp->link!=NULL)
    {
    
    bar(temp->sloc.x-5,temp->sloc.y-5,temp->sloc.x+5,temp->sloc.y+5);
    temp=temp->link;
    }
    
    bar(temp->sloc.x-5,temp->sloc.y-5,temp->sloc.x+5,temp->sloc.y+5);
    
    circle(f->floc.x-2,f->floc.y-2,5);
    circle(f->floc.x+2,f->floc.y+2,5);
    circle(f->floc.x-2,f->floc.y+2,5);
    circle(f->floc.x+2,f->floc.y-2,5);
    
    delay(20);
    while(!kbhit()){goto e;}
    key=getche();
    e:
    
          cleardevice();
    
    }
    
  • "gameover": This function will draw screen when game is over, it includes score and number of food consumed.
  • gameover(void)
    {
    cleardevice();
    outtextxy(100,100,"----------------- GAME OVER ----------------------");
    
    printf("\n\n\n\n\n\n\n\n");
    printf("\t\t# Score      - %d",gd.score);
    printf("\n\t\t# No of food - %d", gd.no_food);
    s1:
    sound(300);delay(300);sound(450);delay(150);sound(500);delay(150);
    sound(300);delay(200);sound(450);delay(100);sound(450);delay(200);
    while(!kbhit()){goto s1;}
    nosound();
    
          exit(0);
    }
    
  • "game" : This is main logic of our snake game. It does following tasks in sequence within a while loop.
    (while loop checks whether 'p' (for pause) is pressed or not.)
    1. checking condition whether snake hits boundary. if it hits boundary then call "gameover" function
    2. check whether snake consumes food or not.
      if it consumes food then generate new food at new location, increase score and food count.
      and create new node of snake structure to increase the length of snake.
    3. check whether any key is pressed to change direction of snake. according to that set the direction of snakes head.
    4. update direction and location of all node of snake body.
    void game(struct snake *head,struct food *f)
    {
         struct snake *temp,pre,nxt;
         temp=head;
    
         while(key!='p')
         {
    if(head->sloc.x==l.lx1||head->sloc.x==l.ly2||head->sloc.y==l.ly1||head->sloc.y==l.ly2)
    {gameover();}
    
    
    
    if(head->sloc.x>=f->floc.x-5&&head->sloc.x<=f->floc.x+5&&head->sloc.y>=f->floc.y-5&&head->sloc.y<=f->floc.y+5)
    {
    temp=head;
    sound(420);
    
    f->floc.x=150+random(245);
    f->floc.y=150+random(245);
    gd.score+=100;
    gd.no_food+=1;
    n=n+1;
    
    
    while(temp->link!=NULL){temp=temp->link;}
    temp->link=(struct snake *)malloc(sizeof(struct snake));
    temp->link->link=NULL;
    temp->link->sloc.x= temp->sloc.x;
    temp->link->sloc.y= temp->sloc.y;
    temp->link->dir=temp->dir;
    n=0;
    
    
      }
    
    switch(key) //this key varible is set in draw() function
    {
     case 'a': if(head->dir!='d'){head->dir='a';  head->sloc.x-=2; } else {key=head->dir;} break;
     case 'w': if(head->dir!='s'){head->dir='w';  head->sloc.y-=2; } else {key=head->dir;} break;
     case 'd': if(head->dir!='a'){head->dir='d';  head->sloc.x+=2; } else {key=head->dir;} break;
     case 's': if(head->dir!='w'){head->dir='s';  head->sloc.y+=2; } else {key=head->dir;} break;
    
    }
          draw(head,f);
          nosound();
          temp=head;
          pre=*temp;
    
          while(temp->link!=NULL)
    {
    nxt.sloc.x=temp->link->sloc.x;
    nxt.sloc.y=temp->link->sloc.y;
    nxt.dir=temp->link->dir;
    temp->link->sloc.x=pre.sloc.x;
    temp->link->sloc.y=pre.sloc.y;
    temp->link->dir=pre.dir;
    temp=temp->link;
    pre=nxt;
    }
       }
    
    }
    
Now you can download the source code of the game and run on your own pc.
make changes and try to modify this game.
If you have any query please leave a comment.






6 comments:

  1. Hi viral, really nice tut.. Thanx.

    ReplyDelete
  2. it is saying sound(), random() not defined

    ReplyDelete
  3. it is saying sound(), random() not defined

    ReplyDelete
  4. random and sound will not work on codeblocks but they should work fine on turboc++.Use beep() instead of sound() and rand()%point instead of random(point)

    ReplyDelete
  5. is it working? and if its work, working with linked list?!

    ReplyDelete
    Replies
    1. Yes, it is working and it uses linkedlist for creating snake

      Delete