pentanol - 1 year ago 129
C Question

# Snake Game with C

The following code for a snake game written in C language.
We want in this case to begin with a snake composed of 4 stars in its initial case
(****) and that the snake goes right automatically when the game begin. I made my trial in this code but I see that the snake begins under the form of 3 stars and when I press any one of the direction buttons it turns to a 4 stars snake. How can this problem be solved?

``````#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
bool gameOver;
bool hit = false;
const width = 50;
const height = 20;
int x,y,fruitX,fruitY,score;
int tailX[200],tailY[200];
int ntail=3;
char snake[200];
typedef enum  {STOP = 0,LEFT,RIGHT,UP,DOWN} Direction;
Direction Dir;
int a;
printf("\n\n\n\n\n\n");
printf("                              THE SNAKE GAME                      \n\n\n");
printf("                              1)   NEW GAME                       \n");
printf("                              2GAME WITH BORDERS                 \n");
printf("                              3.QUIT THE GAME                 \n\n");
scanf("%d", &a);
}
// This function is used to initialize(reset the game when it begins
void setup(){
// This function will be used to print the snake in each of its different cases inside its fame
gameOver = false;
Dir = STOP;
x= width/2;
y= height/2;
fruitX = rand()%width;
fruitY = rand()%height;
score = 0;
}
void draw(){
// This is used to take inputs when we press on any key on the keyboard and send it to the logic function to be interpreted
// This is used to
system("cls");
printf("Score:%d",score);
printf("\n");
int i;
for(i= 0 ;i<width+1;i++){ // first row
printf("=");
}
printf("\n");
int p;
for(p= 0 ;p<height;p++){
int q;
for(q= 0 ;q<width;q++){
if(q==0 || q==width-1){ // first last elt
printf("!");
}
if(p == y && q == x){//head coordinates
printf("*");

}else if(p == fruitY && q == fruitX){
printf("#");
}else{
int k=0;
bool print = false;
for(k=0;k<ntail;k++){
if(tailX[k]==q && tailY[k]==p){
printf("*");
print = true;
}
}
if(!print){printf(" ");}
}
}
printf("\n");
}

int j;
for(j= 0 ;j<width+1;j++){
printf("=");
}

}
void input(){
// The logic function
if(_kbhit()){
switch(_getch()){
case '4':
Dir = LEFT;
hit= true;
break;
case '8':
Dir = UP;
hit= true;
break;
case '6':
Dir = RIGHT;
hit= true;
break;
case '2':
Dir = DOWN;
hit= true;
break;
case 'x':
gameOver = true;
break;
}
}else if(!hit){
x++;
}
}
void logic(){
// main function

int lastX = tailX[0]; // The one before 0
int lastY = tailY[0];
int last2X, last2Y;
tailX[0]=x;
tailY[0]=y;
int i=0;
for(i=1; i<ntail;i++){
last2X = tailX[i];// 2 takes place of 1
last2Y = tailY[i];
tailX[i]=lastX; // 1 takes place of 0
tailY[i]=lastY;
lastX = last2X; // 1 takes place of 1
lastY = last2Y;
}
switch(Dir){
case UP:
y--;
break;
case DOWN:
y++;
break;
case LEFT:
x--;
break;
case RIGHT:
x++;
break;

}
if(x<0 || width<x || y<0 || height<y){
gameOver = true;
system("cls");
printf("#******#######################****# GAME OVER #***#######################******#");
}
if(x==fruitX && y==fruitY){
ntail++;
score+=10;
fruitX = rand()%width;
fruitY = rand()%height;
}
}
int main(){

setup();
draw();
while(!gameOver){// each time we repeat a new picture will new drawn and we will see the snake in its new state
draw();
input();
logic();
}

return 0;
}
``````

I made my trial in this code but I see that the snake begins under the form of 3 stars

According to `tailX[0]=x; tailY[0]=y;` you use `tailX[0]` and `tailY[0]` for position of the head. You initialize `int ntail=3;` and iterate from 1 to less then 3 (`for(i=1; i<ntail;i++`), so your tail has a length of 2. In sum your snake is at the beginning 3 elements long.

when I press any one of the direction buttons it turns to a 4 stars snake

After you have pressed a button for the first time `DIR != STOP`, and you increment or dcrement either `x` or `y` after you set `tailX` and `tailY`. Now either `x != tail[0]` or `y != tail[0]` and your snake has a total length of 4.

My solution would be to move the else case where you increment `x` from your function `input` and put it into your function `logic`:

``````void input(){
if(_kbhit()){
switch(_getch()){
case '4': Dir = LEFT;  break;
case '8': Dir = UP;    break;
case '6': Dir = RIGHT; break;
case '2': Dir = DOWN;  break;
case 'x': gameOver = true; break;
}
}
// from here ---->
}

void logic(){
for(int i=ntail-1; i>0;i--){
tailX[i]=tailX[i-1];
tailY[i]=lastY[i-1];
}
tailX[0]=x;
tailY[0]=y;
switch(Dir){
case UP:    y--; break;
case DOWN:  y++; break;
case LEFT:  x--; break;
case RIGHT: x++; break;

case STOP:  x++; break; // <----- to here
}
...
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download