Code:
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
// Directions of the Snake
#define GO_UP 1
#define GO_DOWN 2
#define GO_RIGHT -1
#define GO_LEFT -2
//Arrow keys' code
#define BT_UP 0x48 // button UP has code 0x48
#define BT_DOWN 0x50
#define BT_RIGHT 0x4d
#define BT_LEFT 0x4b
//Limits
#define TOP_LIM 3
#define BOT_LIM 20 //Bottom limit
#define LEFT_LIM 1
#define RIGHT_LIM 40
#define len 3 //At the beginning, the Snake has 3 dots.
//Declarations
typedef struct coord
{
int x;
int y;
} Point;
Point Snake[100]={LEFT_LIM+1,TOP_LIM+1,LEFT_LIM+1,TOP_LIM+1,LEFT_LIM+1,TOP_LIM+1}; //Define the Snake
int intNew_len = len;
int intHead = len-1; //its head is the 3th dot
int intTail = 0; //its tail is the first dot
int intDir = GO_RIGHT; //At the beginning, the Snake's direction is to the RIGHT.
int intScore = 0; //Eating one food, gaining one score, 10 scores for 1 level.
int intLevel = 1; //if level+1,the speed will increase.
int intAmount = 10; //if score > amount, level+1, amount+10
int intSpeed = 300; //speed of the Snake, less -> faster, more -> slower
char chrPress = BT_RIGHT; //pressed button;
// Prototypes
void drawYard(void); // Draw playing yard
int onSnake(Point point); // Check whether a point is on the Snake
void setLevel(void); // Increase level
void scoreCount(void); // Count score
void drawFood(void); // Generate food
void eatFood(void); // Snake eats food
void drawSnake(void); // Draw beginning Snake
void newHeadTail(void); // After each move, the tail and head's positions are changed
void moveSnake(char c); // Make the Snake run
int checkStatus(int tempX,int tempY); // Check whether the Snake dies or not
void refreshSnake(void); // Snake after re-play
void refreshScore(void); // Score after re-play
void Dead(void); // when the Snake dies
char quitGame(void); // say good bye
void main()
{
clrscr();
drawYard();
randomize();
drawFood();
drawSnake();
while(1)
{
play:
while (!kbhit()) //While no key pressed
{
moveSnake(chrPress);
if (checkStatus(Snake[intHead].x,Snake[intHead].y)==1)
{
Dead();
chrPress=BT_RIGHT;
intDir = GO_RIGHT;//When re-play,the snake runs to the right
}
delay(intSpeed);
}
chrPress= getch();
if(chrPress==0xd)
{
chrPress= quitGame();
if(chrPress=='N') goto play;
else if(chrPress=='Y')
{
clrscr();
printf("Bye! Bye!");
delay(500);
exit(1);}
}
}
}
void drawYard() //Draw playing yard
{
register int i;
//Trade mark
gotoxy(LEFT_LIM,TOP_LIM-2);
printf("Created by Chau Nguyen Thanh Vu~ T06-3546 K12T01");
// Ve ÉÍÍÍÍÍÍÍÍÍ»
gotoxy(LEFT_LIM, TOP_LIM); // (10,5)
printf("%c",201); // Top left corner É
for(i=LEFT_LIM+1; i<RIGHT_LIM; i++)
{
gotoxy(i,TOP_LIM);
printf("%c",205); //Top horizonal line Í
}
printf("%c",187); // Top right corner »
//Ve ÈÍÍÍÍÍÍÍÍÍͼ
gotoxy(LEFT_LIM, BOT_LIM); //(10,40)
printf("%c",200); // Bottom left corner È
for(i=LEFT_LIM+1; i<RIGHT_LIM; i++)
printf("%c",205); // Bottom horizonal line Í
printf("%c",188); //Bottom right corner ¼
for(i=TOP_LIM+1; i<BOT_LIM; i++)
{
gotoxy(LEFT_LIM,i);
printf("%c",186); // Left vertical line º
}
for(i=TOP_LIM+1; i<BOT_LIM; i++)
{
gotoxy(RIGHT_LIM,i);
printf("%c",186); // Right vertical line º
}
//Instructions
gotoxy(RIGHT_LIM+2,TOP_LIM);
printf("Press any ARROW key to play");
gotoxy(RIGHT_LIM+2,TOP_LIM+2);
printf("Press ENTER to exit \n");
gotoxy(RIGHT_LIM+2,TOP_LIM+6);
printf("Speed: %3.d milisecs/step",intSpeed);
//Title
gotoxy(LEFT_LIM+5,TOP_LIM);
printf(" Level %d ",intLevel);
gotoxy(LEFT_LIM+25,TOP_LIM);
printf(" Score %d ",intScore);
}
int onSnake(Point point)// Check whether a point is on the Snake
{
register int i;
for(i=0;i<intNew_len-1;i++)
if( (point.x == Snake[i].x)&&(point.y == Snake[i].y) )
return 1;
return 0;
}
void setLevel()
{
intScore++;
if ( (intScore>=intAmount)&&
(intLevel<7) ) //Max level is 7, the Snake run crazily.
{
intAmount+= 10;
intLevel++;
intSpeed -= 49 ; //Decrease delay time, increase speed
}
if (intLevel == 7)
{
gotoxy(LEFT_LIM+14,TOP_LIM);
printf("(Max)");
}
gotoxy(LEFT_LIM+25,TOP_LIM);
printf(" Score: %d ",intScore);
gotoxy(LEFT_LIM+5,TOP_LIM);
printf(" Level %d ",intLevel);
gotoxy(RIGHT_LIM+2,TOP_LIM+6);
printf("Speed: %3.d milisecs/step",intSpeed);
}
Point food = Snake[intHead];
void drawFood()
{
while( (onSnake(food) != 0)||(food.x == 0) )
/* If food appears on the snake's body,
it must be re-generated until it appears
somewhere else */
{
food.x = LEFT_LIM+2+random(RIGHT_LIM - LEFT_LIM-3);
food.y = TOP_LIM+2+random(BOT_LIM - TOP_LIM-3);
}
gotoxy(food.x,food.y);
textcolor(CYAN);
cprintf("*");
return;
}
void eatFood()
{
intNew_len++;
intHead++;
Snake[intHead].x = food.x;
Snake[intHead].y = food.y;
gotoxy(food.x,food.y);
textcolor(WHITE);
cprintf("@");
food = Snake[intHead-1]; // Put food on the snake's body, so that
// the drawFood() function can run
setLevel();
drawFood();
return;
}
void drawSnake() //At the beginning, the snake is a POINT.
{
gotoxy(LEFT_LIM+1,TOP_LIM+1);
printf("@");
gotoxy(LEFT_LIM,TOP_LIM);
}
void newHeadTail() /* After each move, the intHead and the tail's positions
are changed. */
{
register int i;
for(i=0;i<intNew_len-1;i++)
Snake[i]= Snake[i+1];
}
char chrLast_button; //the last button pressed
void moveSnake(char chrButton)
{
int arrow_pressed=0;
while( arrow_pressed!=1 )
{
if(
(chrButton==BT_UP)||
(chrButton==BT_DOWN)||
(chrButton==BT_LEFT)||
(chrButton==BT_RIGHT)
)
{
gotoxy(Snake[intTail].x,Snake[intTail].y); //Erase the tail
textcolor(BLACK);
cprintf(" ");
newHeadTail();
switch (chrButton)
{
case BT_UP:
if( (intDir!=GO_DOWN)) /* While the Snake is going DOWN,
it cannot go UP. */
{
if ( (Snake[intHead].y-1 == food.y)&&
(Snake[intHead].x == food.x) )
{
Snake[intHead].y -=1;
eatFood();
}
Snake[intHead].y -=1;
intDir = GO_UP;
}
else Snake[intHead].y +=1;
break;
case BT_DOWN:
if( (intDir!=GO_UP) )
{
if ( (Snake[intHead].y+1 == food.y)&&
(Snake[intHead].x == food.x) )
{
Snake[intHead].y +=1;
eatFood();
}
Snake[intHead].y +=1;
intDir = GO_DOWN;
}
else Snake[intHead].y -=1;
break;
case BT_LEFT:
if( (intDir!=GO_RIGHT) )
{
if ( (Snake[intHead].x-1 == food.x)&&
(Snake[intHead].y == food.y) )
{
Snake[intHead].x -=1;
eatFood();
}
Snake[intHead].x -=1;
intDir = GO_LEFT;
}
else Snake[intHead].x +=1;
break;
case BT_RIGHT:
if( (intDir!=GO_LEFT) )
{
if ( (Snake[intHead].x+1 == food.x)&&
(Snake[intHead].y == food.y) )
{
Snake[intHead].x +=1;
eatFood();
}
Snake[intHead].x +=1;
intDir = GO_RIGHT;
}
else Snake[intHead].x -=1;
break;
}
chrLast_button = chrButton; //Remember the last ARROW key
gotoxy(Snake[intHead].x,Snake[intHead].y); //Draw intHead
textcolor(WHITE);
cprintf("@");
gotoxy(LEFT_LIM,TOP_LIM);
arrow_pressed=1;
}
else chrButton = chrLast_button; /* If the pressed key is not ARROW key,
the snake uses the last ARROW key */
}
}
int checkStatus(int tempX,int tempY)
{
if( (tempX <= LEFT_LIM)||
(tempX >= RIGHT_LIM) ||
(tempY <= TOP_LIM) ||
(tempY >= BOT_LIM) )
return 1; //The snake dies if it hits the wall.
else if( onSnake(Snake[intHead])==1) return 1; //It dies if bite itself
else return 0;
}
void refreshSnake()
{
register int i;
intNew_len = 3;
intHead = 2;
intTail = 0;
intSpeed = 300;
for(i=0;i<intNew_len;i++) //Return the Snake to the beginning
{
Snake[i].x = LEFT_LIM+1;
Snake[i].y = TOP_LIM+1;
}
}
void refreshScore()
{
intLevel = 1;
intScore = 0;
intAmount = 10;
}
void Dead()
{
char chrAns;
gotoxy(LEFT_LIM+2,BOT_LIM+2);
printf("You are lose. Play Again?(Y/N)");
do {
chrAns = toupper(getch());
}
while (chrAns != 'N' && chrAns != 'Y');
if (chrAns=='N')
{
clrscr();
printf("Bye Bye!");
delay(500);
exit(1);
}
else
{
Snake[intHead].x=LEFT_LIM+1;
Snake[intHead].y=TOP_LIM+1;
refreshScore();
refreshSnake();
clrscr();
drawYard();
drawFood();
drawSnake();
return ;
}
}
char quitGame()
{
char chrAns;
gotoxy(LEFT_LIM+2, BOT_LIM+2);
printf("Are you sure?(Y/N)");
do
{
chrAns = toupper(getch());
}
while (chrAns!= 'Y' && chrAns!='N');
gotoxy(LEFT_LIM+2, BOT_LIM+2);
printf(" ");
return chrAns;
}