Snake game help

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

36 Replies - 1525 Views - Last Post: 23 June 2013 - 06:53 PM Rate Topic: -----

#16 lewm  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 160
  • Joined: 29-March 13

Re: Snake game help

Posted 17 June 2013 - 04:25 PM

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <math.h>
#include <string.h>
#include <conio.h>
#include <time.h>

void gotoxy(int x, int y);
void grid(int hx, int hy, int tx, int ty,int mx1,int mx2,int mx3,int mx4,int mx5,int mx6,
                                         int my1,int my2,int my3,int my4,int my5,int my6);

int main(void)
{
    int hx=1, tx=1, mx1=1, mx2=1, mx3=1, mx4=1, mx5=1, mx6=1;
    int hy=2, ty=2, my1=2, my2=2, my3=2, my4=2, my5=2, my6=2;
    int direction=6, x=2, y=2;
    int z=15, i=0;
    char key;

    while(TRUE)
    {
        while(!kbhit())
        {
            tx=mx6; ty=my6;
            mx6=mx5; my6=my5;
            mx5=mx4; my5=my4;
            mx4=mx3; my4=my3;
            mx3=mx2; my3=my2;
            mx2=mx1; my2=my1;
            mx1=hx; my1=hy;
            hx=x; hy=y;
            grid(hx, hy, tx, ty, mx1, mx2, mx3, mx4, mx5, mx6, my1, my2, my3, my4, my5, my6);
            if(direction==6)
            {
                x=x+2;
                if(x>=21)
                    x=2;
            }
            else
            if(direction==4)
            {
                x=x-2;
                if(x<=1)
                    x=20;
            }
            else
            if(direction==8)
            {
                y--;
                if(y<=1)
                    y=11;
            }
            else
            if(direction==5)
            {
                y++;
                if(y>=12)
                    y=2;
            }
            do
            {
                i++;
            }while(i<100000000);
            i=0;
        }
        key=getch();
        
        if(kbhit())///SOLVED///
            getch();
            
        if(key=='6' && direction!=4)
            direction=6;
        else
        if(key=='4' && direction!=6)
            direction=4;
        else
        if(key=='8' && direction!=5)
            direction=8;
        else
        if(key=='5' && direction!=8)
            direction=5;
    }
    return 0;
}

void grid(int hx, int hy, int tx, int ty,int mx1,int mx2,int mx3,int mx4,int mx5,int mx6,
                                         int my1,int my2,int my3,int my4,int my5,int my6)
{
    gotoxy(1,1);
    printf("* * * * * * * * * * *   6 = RIGHT\n"
           "*                   *   4 = LEFT\n"
           "*                   *   8 = UP\n"
           "*                   *   5 = DOWN\n"
           "*                   *\n"
           "*                   *\n"
           "*                   *\n"
           "*                   *\n"
           "*                   *\n"
           "*                   *\n"
           "*                   *\n"
           "* * * * * * * * * * *");
    gotoxy(hx,hy); puts("*");
    gotoxy(tx,ty); puts("*");
    gotoxy(mx1,my1); puts("*");
    gotoxy(mx2,my2); puts("*");
    gotoxy(mx3,my3); puts("*");
    gotoxy(mx4,my4); puts("*");
    gotoxy(mx5,my5); puts("*");
    gotoxy(mx6,my6); puts("*");


    return;
}

void gotoxy( int x, int y )
{
    COORD c;

      c.X = x - 1 ;
      c.Y = y - 1 ;

      SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), c );
      return;
}

This post has been edited by lewm: 17 June 2013 - 04:27 PM

Was This Post Helpful? 0
  • +
  • -

#17 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3631
  • View blog
  • Posts: 11,327
  • Joined: 05-May 12

Re: Snake game help

Posted 17 June 2013 - 04:40 PM

What the fudge is line 61-64 for? A busy wait is worse than calling sleep(). That code will peg the CPU and kill your laptop's battery, while sleep() will at least let other processes run in another process needs the CPU, or let the CPU go on minimal power if not.

Anyway, since you are already using the Windows APIs for setting console cursor, you might as well use the GetAsyncKeyState() to determine what key is being pressed at that instant in time rather than fighting with the input buffer.
http://msdn.microsof...3(v=vs.85).aspx
Was This Post Helpful? 2
  • +
  • -

#18 lewm  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 160
  • Joined: 29-March 13

Re: Snake game help

Posted 17 June 2013 - 04:46 PM

View PostSkydiver, on 17 June 2013 - 04:40 PM, said:

What the fudge is line 61-64 for? A busy wait is worse than calling sleep(). That code will peg the CPU and kill your laptop's battery, while sleep() will at least let other processes run in another process needs the CPU, or let the CPU go on minimal power if not.

Anyway, since you are already using the Windows APIs for setting console cursor, you might as well use the GetAsyncKeyState() to determine what key is being pressed at that instant in time rather than fighting with the input buffer.
http://msdn.microsof...3(v=vs.85).aspx

Thank you, i just changed back to Sleep i got some bad advice in relation to my original question.
int main(void)
{
    int hx=1, tx=1, mx1=1, mx2=1, mx3=1, mx4=1, mx5=1, mx6=1;
    int hy=2, ty=2, my1=2, my2=2, my3=2, my4=2, my5=2, my6=2;
    int direction=6, x=2, y=2;
    int z=15, i=0;
    char key;

    while(TRUE)
    {
        while(!kbhit())
        {
            tx=mx6; ty=my6;
            mx6=mx5; my6=my5;
            mx5=mx4; my5=my4;
            mx4=mx3; my4=my3;
            mx3=mx2; my3=my2;
            mx2=mx1; my2=my1;
            mx1=hx; my1=hy;
            hx=x; hy=y;
            grid(hx, hy, tx, ty, mx1, mx2, mx3, mx4, mx5, mx6, my1, my2, my3, my4, my5, my6);
            if(direction==6)
            {
                x=x+2;
                if(x>=21)
                    x=2;
            }
            else
            if(direction==4)
            {
                x=x-2;
                if(x<=1)
                    x=20;
            }
            else
            if(direction==8)
            {
                y--;
                if(y<=1)
                    y=11;
            }
            else
            if(direction==5)
            {
                y++;
                if(y>=12)
                    y=2;
            }
           Sleep(300);
        }
        key=getch();
        if(kbhit())
            getch();
        if(key=='6' && direction!=4)
            direction=6;
        else
        if(key=='4' && direction!=6)
            direction=4;
        else
        if(key=='8' && direction!=5)
            direction=8;
        else
        if(key=='5' && direction!=8)
            direction=5;
    }
    return 0;
}

Was This Post Helpful? 0
  • +
  • -

#19 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3631
  • View blog
  • Posts: 11,327
  • Joined: 05-May 12

Re: Snake game help

Posted 17 June 2013 - 04:53 PM

No. You got good advice from tlhIn`toq with regards to Sleep() as well. As he said, when you put a thread to sleep, it stops doing work, including potentially crippling the handling of input messages.

In the good old days of essentially single threaded single CPU console programs that was a non-issue, but in today's multitasking environments you have to make better choices about how you deal with IO.
Was This Post Helpful? 0
  • +
  • -

#20 lewm  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 160
  • Joined: 29-March 13

Re: Snake game help

Posted 17 June 2013 - 05:00 PM

View PostSkydiver, on 17 June 2013 - 04:53 PM, said:

No. You got good advice from tlhIn`toq with regards to Sleep() as well. As he said, when you put a thread to sleep, it stops doing work, including potentially crippling the handling of input messages.

In the good old days of essentially single threaded single CPU console programs that was a non-issue, but in today's multitasking environments you have to make better choices about how you deal with IO.

No he gave me lots of very good advice on how to improve lots of things and i am very greatful.
But in direct relation to my ORIGINAL question i was led to believe that sleep() was part of the problem with the code.
Sorry tlhIn`toq if my last post came across wrong, you have put me on a much better track to completing this game REV. 2 is underway. :)

This post has been edited by lewm: 17 June 2013 - 05:06 PM

Was This Post Helpful? 0
  • +
  • -

#21 lewm  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 160
  • Joined: 29-March 13

Re: Snake game help

Posted 23 June 2013 - 03:28 PM

Ok so i took tlhIn`toq's advice and re-wrote it:
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <math.h>
#include <string.h>
#include <conio.h>

void gotoxy(int xx, int yy);
void grid(void);
void initialize_snake(void);
void draw_snake(void);
int move_snake(int direction);

const int up=8, down=5, left=4, right=6;
int i=0, snake_length=8;
int direction=6, life=1;

struct snake_body
{
    int row,col;
}snake[100];

struct snake_head
{
    int x,y;
}head[1];

int main(void)
{
    grid();
    initialize_snake();
    while(life)
    {
        direction=move_snake(direction);
    }
    puts("You are dead");
    return 0;
}

int move_snake(direction)
{
    char a[1];
    int key=0;

    do
    {
        while(!kbhit() && life)
        {
            draw_snake();
            Sleep(300);
            gotoxy(snake[0].row,snake[0].col);
            puts(" ");
            if(direction==right)
            {
                head[0].x+=2;
                if(head[0].x>23)
                    head[0].x=1;
            }
            else
            if(direction==down)
            {
                head[0].y++;
                if(head[0].y>12)
                    head[0].y=1;
            }
            else
            if(direction==left)
            {
                head[0].x-=2;
                if(head[0].x<1)
                    head[0].x=23;
            }
            else
            if(direction==up)
            {
                head[0].y--;
                if(head[0].y<1)
                    head[0].y=12;
            }
            for(i=0; i<snake_length-1; i++) ///Update snake var///
            {
                snake[i].row=snake[i+1].row; snake[i].col=snake[i+1].col;
            }
            snake[i].row=head[0].x; snake[i].col=head[0].y;
            gotoxy(0,14);
            for(i=0; i<snake_length-1; i++)  ///Check to see if snake hits itself///
            {
                if(snake[snake_length-1].row == snake[i].row && snake[snake_length-1].col == snake[i].col)
                {
                    life=0;
                    return;
                }
            }
        }
        a[0]=getch();
        key=atoi(a);
        if(kbhit()) ///Check to see if 2 keys have been pressed/// 
            getch();///in quick succesion and remove last pressed///
        if(key == left && direction == right) ///Stop snake moving directly back on itself///
            key=0;
        else
        if(key == right && direction == left)
            key=0;
        else
        if(key == up && direction == down)
            key=0;
        else
        if(key == down && direction == up)
            key=0;
    }while(key != 6 && key != 5 && key != 4 && key != 8);
    return(key);
}

void draw_snake(void)
{
    for(i=0; i<snake_length; i++)
    {
        gotoxy(snake[i].row, snake[i].col);
        puts("*");
    }
    return;
}

void initialize_snake(void)
{
    int x=1;

    for(i=0; i<snake_length; i++)
    {
        snake[i].row=x; snake[i].col=1;
        x+=2;
        head[0].x=snake[i].row; head[0].y=snake[i].col;
    }
}

void grid(void)
{
    printf("|-----------------------|\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|-----------------------|");
    return;
}

void gotoxy( int xx, int yy )
{
    COORD c;

      c.X = xx;
      c.Y = yy;

      SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), c );
      return;
}
Is there anything else i can improve up to as far as i have got?

This post has been edited by lewm: 23 June 2013 - 03:39 PM

Was This Post Helpful? 0
  • +
  • -

#22 jimblumberg  Icon User is offline

  • member icon


Reputation: 4158
  • View blog
  • Posts: 12,952
  • Joined: 25-December 09

Re: Snake game help

Posted 23 June 2013 - 03:52 PM

Look at the following snippet:
int move_snake(direction)
{
    char a[1];
    int key=0;
...
        a[0]=getch();
        key=atoi(a);


The atoi function requires a C-string not an array of char. Why are you even using an array in the first place? You do realize that characters are numbers, correct? Do you realize that getch() returns an int not a char?

I also recommend a more meaningful name for this variable.


Jim

This post has been edited by jimblumberg: 23 June 2013 - 03:55 PM

Was This Post Helpful? 1
  • +
  • -

#23 lewm  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 160
  • Joined: 29-March 13

Re: Snake game help

Posted 23 June 2013 - 04:04 PM

Ok i changed it to
int move_snake(direction)
{
    int key=0;
...
        key=getch();
And it stopped working it didnt change direction, when i checked the value of key after pressing 5 it came back with the value 53 and not 5.?

This post has been edited by lewm: 23 June 2013 - 04:06 PM

Was This Post Helpful? 0
  • +
  • -

#24 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3631
  • View blog
  • Posts: 11,327
  • Joined: 05-May 12

Re: Snake game help

Posted 23 June 2013 - 04:07 PM

And if you look at the ASCII table ( http://www.asciitable.com/ ) you will discover that the number 53 is the ASCII code for the character '5'.
Was This Post Helpful? 1
  • +
  • -

#25 lewm  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 160
  • Joined: 29-March 13

Re: Snake game help

Posted 23 June 2013 - 04:11 PM

View PostSkydiver, on 23 June 2013 - 04:07 PM, said:

And if you look at the ASCII table ( http://www.asciitable.com/ ) you will discover that the number 53 is the ASCII code for the character '5'.

Ok how do i change the "ASCII 53" into an "int 5" so i can return it for use in the calling function?
Was This Post Helpful? 0
  • +
  • -

#26 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3631
  • View blog
  • Posts: 11,327
  • Joined: 05-May 12

Re: Snake game help

Posted 23 June 2013 - 04:13 PM

Why bother changing it? Just change your constants on line 14.

But if you really much change it, try substracting the ASCII code value for '0' from it.
Was This Post Helpful? 1
  • +
  • -

#27 jimblumberg  Icon User is offline

  • member icon


Reputation: 4158
  • View blog
  • Posts: 12,952
  • Joined: 25-December 09

Re: Snake game help

Posted 23 June 2013 - 04:15 PM

Did you look at the link you were provided? Do you notice anything "interesting" about the "numbers"? Like maybe they are all consecutive? Maybe you can use that feature? For example what happens when you subtract '0' from 53?

Jim
Was This Post Helpful? 1
  • +
  • -

#28 lewm  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 160
  • Joined: 29-March 13

Re: Snake game help

Posted 23 June 2013 - 04:40 PM

I did look at the link '0'=48 - '5'=53 = 5 :)
So it now looks like this:
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <math.h>
#include <string.h>
#include <conio.h>

void gotoxy(int xx, int yy);
void grid(void);
void initialize_snake(void);
void draw_snake(void);
char move_snake(int direction);

const char up='8', down='5', left='4', right='6';
int i=0, snake_length=8, life=1;
char direction='6';

struct snake_body
{
    int row,col;
}snake[100];

struct snake_head
{
    int x,y;
}head[1];

int main(void)
{
    grid();
    initialize_snake();
    while(life)
    {
        direction=move_snake(direction);
    }
    puts("You are dead");
    return 0;
}

char move_snake(direction)
{
    int key_pressed=0;

    do
    {
        while(!kbhit() && life)
        {
            draw_snake();
            Sleep(300);
            gotoxy(snake[0].row,snake[0].col);
            puts(" ");
            if(direction==right)
            {
                head[0].x+=2;
                if(head[0].x>23)
                    head[0].x=1;
            }
            else
            if(direction==down)
            {
                head[0].y++;
                if(head[0].y>12)
                    head[0].y=1;
            }
            else
            if(direction==left)
            {
                head[0].x-=2;
                if(head[0].x<1)
                    head[0].x=23;
            }
            else
            if(direction==up)
            {
                head[0].y--;
                if(head[0].y<1)
                    head[0].y=12;
            }
            for(i=0; i<snake_length-1; i++)
            {
                snake[i].row=snake[i+1].row; snake[i].col=snake[i+1].col;
            }
            snake[i].row=head[0].x; snake[i].col=head[0].y;
            gotoxy(0,14);
            for(i=0; i<snake_length-1; i++)
            {
                if(snake[snake_length-1].row == snake[i].row && snake[snake_length-1].col == snake[i].col)
                {
                    life=0;
                    return;
                }
            }
        }
        key_pressed=getch();
        if(kbhit())
            getch();
        if(key_pressed == left && direction == right)
            key_pressed=0;
        else
        if(key_pressed == right && direction == left)
            key_pressed=0;
        else
        if(key_pressed == up && direction == down)
            key_pressed=0;
        else
        if(key_pressed == down && direction == up)
            key_pressed=0;
    }while(key_pressed != '6' && key_pressed != '5' && key_pressed != '4' && key_pressed != '8');
    return(key_pressed);
}

void draw_snake(void)
{
    for(i=0; i<snake_length; i++)
    {
        gotoxy(snake[i].row, snake[i].col);
        puts("*");
    }
    return;
}

void initialize_snake(void)
{
    int x=1;

    for(i=0; i<snake_length; i++)
    {
        snake[i].row=x; snake[i].col=1;
        x+=2;
        head[0].x=snake[i].row; head[0].y=snake[i].col;
    }
    return;
}

void grid(void)
{
    printf("|-----------------------|\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|                       |\n"
           "|-----------------------|");
    return;
}

void gotoxy( int xx, int yy )
{
    COORD c;

      c.X = xx;
      c.Y = yy;

      SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), c );
      return;
}

Was This Post Helpful? 0
  • +
  • -

#29 lewm  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 160
  • Joined: 29-March 13

Re: Snake game help

Posted 23 June 2013 - 05:51 PM

Would someone point me in the right direction to using arrowkeys instead of numpad please?
Was This Post Helpful? 0
  • +
  • -

#30 lewm  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 160
  • Joined: 29-March 13

Re: Snake game help

Posted 23 June 2013 - 06:04 PM

Hi, can you retrieve an arrow key input using getch()? I have tried:
int a;
    a=getch();
    printf("%d", a);
    getch();
But i get the same output no matter what arrow key i press, 224.

This post has been edited by lewm: 23 June 2013 - 06:05 PM

Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3