pentanol pentanol - 3 months ago 22
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;
void menu(){
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");
printf(" Please enter your choice: ");
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(){
menu();

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;
}

Answer

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    
        }
   ...
}