Basic Concept: Here we join different lines to look like
continuous snake.Each line is stored in different node of linked
list.When the last line (Head of snake) has co-ordinates similar to pixel
(food) size of the snake increases,score increases and co-ordinates of
food changes according to rand(). When the snake touches any boundary
i.e (end of screen) or touches himself . The game gets over.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <graphics.h>
#include <process.h>
#include <dos.h>
void create(char);
void check();
void out();
char prevKey = 'd', pre = 'd', getKey = 'a';
struct node {
char ch;
int x1, y1, len, flag;
struct node *next;
};
struct node *start, *t, *temp, *temp2;
int flagOut, foodx, foody, max = 100, score = 0;
void main() {
int gd = DETECT, gm = 0, i,j;
flagOut = 0;
foodx = rand() % 620;
foody = rand() % 460;
initgraph(&gd, &gm, "c:\\turboc3\\bgi"); //according to your compiler change the url.
start = (struct node *) malloc(sizeof (struct node));
start->next = NULL;
start->x1 = 150;
start->y1 = 200;
start->ch = 'd';
start->len = max;
start->flag = 1;
while (1) {
clrscr();
if (kbhit()) {
getKey = getch();
if (prevKey != getKey && getKey == 'w' || getKey == 'a' || getKey == 's' || getKey == 'd') {
if (prevKey == 'w' && getKey != 's' || prevKey == 's' && getKey != 'w' || prevKey == 'a' && getKey != 'd' || prevKey == 'd' && getKey != 'a') {
create(getKey);
prevKey = getKey;
}
}
}
for(i=-1;i<=1;i++)
{
for(j=-1;j<=1;j++)
{
putpixel(foodx+i, foody+j, 4);
}
}
check();
out();
t = start;
do {
if (t->ch == 'd') {
setcolor(4);
line(t->x1, t->y1, t->x1 - t->len, t->y1);
if (t->flag)
t->x1++;
if (t->x1 >= 640)
flagOut = 1;
}
if (t->ch == 'w') {
setcolor(4);
line(t->x1, t->y1, t->x1, t->y1 + t->len);
if (t->flag)
t->y1--;
if (t->y1 <= 0)
flagOut = 1;
}
if (t->ch == 'a') {
setcolor(4);
line(t->x1, t->y1, t->x1 + t->len, t->y1);
if (t->flag)
t->x1--;
if (t->x1 <= 0)
flagOut = 1;
}
if (t->ch == 's') {
setcolor(4);
line(t->x1, t->y1, t->x1, t->y1 - t->len);
if (t->flag)
t->y1++;
if (t->y1 >= 480)
flagOut = 1;
}
if (flagOut == 1) {
printf("Game Over\nScore=%d", score);
delay(2000);
exit(1);
}
t = t->next;
} while (t);
delay(20);
}//while close
}
void create(char v) {
t = temp = start;
while (t) {
t->flag = 0;
temp = t;
t = t->next;
}
temp2 = (struct node *) malloc(sizeof (struct node));
temp->next = temp2;
temp2->next = NULL;
temp2->flag = 1;
temp2->x1 = temp->x1;
temp2->y1 = temp->y1;
temp2->ch = v;
temp2->len = -1;
}
void check() {
t = start;
if (t->next != NULL)
t->len--;
if (t->len <= 0) {
start = t->next;
free(t);
}
t = start;
do {
temp = t;
t = t->next;
} while (t);
if (temp->len < max)
temp->len++;
if (temp->x1 > foodx - 2 && temp->x1 < foodx + 2 && temp->y1 > foody - 2 && temp->y1 < foody + 2) {
max = max + max / 10;
foodx = rand() % 620;
foody = rand() % 460;
score = score + score / 10 + 10;
}
}
void out() {
t = temp2 = start;
while (t) {
temp = temp2;
temp2 = t;
t = t->next;
}
t = start;
while (t->next) {
if (temp2->ch == 'w' && t->ch != 's' && t->ch != 'w' || temp2->ch == 'a' && t->ch != 'd' && t->ch != 'a' || temp2->ch == 's' && t->ch != 'w' && t->ch != 's' || temp2->ch == 'd' && t->ch != 'a' && t->ch != 'd') {
if (temp2->x1 == t->x1) {
if (t->ch == 'w') {
if (temp2->y1 >= t->y1 && temp2->y1 <= (t->y1 + t->len))
flagOut = 1;
}
if (t->ch == 's') {
if (temp2->y1 <= t->y1 && temp2->y1 >= (t->y1 - t->len))
flagOut = 1;
}
}
if (temp2->y1 == t->y1) {
if (t->ch == 'a') {
if (temp2->x1 >= t->x1 && temp2->x1 <= (t->x1 + t->len))
flagOut = 1;
}
if (t->ch == 'd') {
if (temp2->x1 <= t->x1 && temp2->x1 >= (t->x1 - t->len))
flagOut = 1;
}
}
}
if (temp2->y1 == t->y1 && temp2->x1 == t->x1)
flagOut = 0;
t = t->next;
}
}
Explanation: Yup program is quite difficult to understand ,lets start with it.
Why we require linked list?
values of each line of snake is stored respective node.When we change direction of snake a new is created.
Starting with linked list structure,which contains char ch int x1, y1, len, flag struct node *next.Lets see the use of each element.
ch will contain the values 'a' or 's' or 'd' or 'w' i.e direction of that single line.
x1 and y1 will save the starting x and y co-ordinate respectively from which line starts.
len will save the current length of that particular line.
flag will indicate the line is increasing or constant.we will see in detail.
*next will save the address of next node in linked list.
Other variables: flagOut which is initialized to 0 indicates snake is alive and 1 indicates game over.
foodx,foody where to print food.
start = (struct node *) malloc(sizeof (struct node));//allocating memory
start->next = NULL; //as only 1 node is there
start->x1 = 150; //initialized starting point
start->y1 = 200;
start->ch = 'd'; //initialized the direction
start->len = max; //initialized to max
start->flag = 1; //indicates the line should move in direction initialized above
while (1) //so that loop goes in infinite loop
kbhit() this is called whenever any key is pressed
getKey = getch(); //using getch() we take the input i.e which key has been pressed
if (prevKey != getKey && getKey == 'w' || getKey == 'a' || getKey == 's' || getKey == 'd')
prevKey stores the previous direction and getKey stores current so ,if prevKey==getKey then the direction is same so no new linked list should be created and further if both are different then i have checked that the key pressed is legal key i.e a,s,d or w.
if (prevKey == 'w' && getKey != 's' || prevKey == 's' && getKey != 'w' || prevKey == 'a' && getKey != 'd' || prevKey == 'd' && getKey != 'a')
If snake is going up so if some one presses down it should not go as only way is it can go right or left.Similarly other cases.
prevKey = getKey; //this will become our prevous keystroke.
for(i=-1;i<=1;i++)
{
for(j=-1;j<=1;j++)
{
putpixel(foodx+i, foody+j, 4); //prints the pixel at +- 1 postion.
}
}
if (t->ch == 'd') {
line(t->x1, t->y1, t->x1 - t->len, t->y1); //lines of co-ordinate and from where to where it should be printed
if (t->flag) //if direction has been changed then the current line should diminished at a point
t->x1++;
if (t->x1 >= 640) // check if snake crosses a boundary
flagOut = 1; //indicates game over
}
similar other 3 groups codes will work
create() will be called when valid key is pressed to change the direction of snake.
So we create new linked list initialized it with the point where direction has to be changed. Length of this line will start from -1 and will increase up-to max.
check() performs two task.
1)If the line which was decreasing has become 0 or not if it has become 0 then free the list.
2)Checks if the snake has eat the food(snake has passed from plotted pixel).If so then generate new pixel position and increment the score.
t = temp2 = start;
while (t) {
temp = temp2;
temp2 = t;
t = t->next;
}
Through this code we can traverse the linked list and reached the head of snake.So temp2 becomes the head of snake.The whole code in out() is to check if any side of snake is touching each other.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <graphics.h>
#include <process.h>
#include <dos.h>
void create(char);
void check();
void out();
char prevKey = 'd', pre = 'd', getKey = 'a';
struct node {
char ch;
int x1, y1, len, flag;
struct node *next;
};
struct node *start, *t, *temp, *temp2;
int flagOut, foodx, foody, max = 100, score = 0;
void main() {
int gd = DETECT, gm = 0, i,j;
flagOut = 0;
foodx = rand() % 620;
foody = rand() % 460;
initgraph(&gd, &gm, "c:\\turboc3\\bgi"); //according to your compiler change the url.
start = (struct node *) malloc(sizeof (struct node));
start->next = NULL;
start->x1 = 150;
start->y1 = 200;
start->ch = 'd';
start->len = max;
start->flag = 1;
while (1) {
clrscr();
if (kbhit()) {
getKey = getch();
if (prevKey != getKey && getKey == 'w' || getKey == 'a' || getKey == 's' || getKey == 'd') {
if (prevKey == 'w' && getKey != 's' || prevKey == 's' && getKey != 'w' || prevKey == 'a' && getKey != 'd' || prevKey == 'd' && getKey != 'a') {
create(getKey);
prevKey = getKey;
}
}
}
for(i=-1;i<=1;i++)
{
for(j=-1;j<=1;j++)
{
putpixel(foodx+i, foody+j, 4);
}
}
check();
out();
t = start;
do {
if (t->ch == 'd') {
setcolor(4);
line(t->x1, t->y1, t->x1 - t->len, t->y1);
if (t->flag)
t->x1++;
if (t->x1 >= 640)
flagOut = 1;
}
if (t->ch == 'w') {
setcolor(4);
line(t->x1, t->y1, t->x1, t->y1 + t->len);
if (t->flag)
t->y1--;
if (t->y1 <= 0)
flagOut = 1;
}
if (t->ch == 'a') {
setcolor(4);
line(t->x1, t->y1, t->x1 + t->len, t->y1);
if (t->flag)
t->x1--;
if (t->x1 <= 0)
flagOut = 1;
}
if (t->ch == 's') {
setcolor(4);
line(t->x1, t->y1, t->x1, t->y1 - t->len);
if (t->flag)
t->y1++;
if (t->y1 >= 480)
flagOut = 1;
}
if (flagOut == 1) {
printf("Game Over\nScore=%d", score);
delay(2000);
exit(1);
}
t = t->next;
} while (t);
delay(20);
}//while close
}
void create(char v) {
t = temp = start;
while (t) {
t->flag = 0;
temp = t;
t = t->next;
}
temp2 = (struct node *) malloc(sizeof (struct node));
temp->next = temp2;
temp2->next = NULL;
temp2->flag = 1;
temp2->x1 = temp->x1;
temp2->y1 = temp->y1;
temp2->ch = v;
temp2->len = -1;
}
void check() {
t = start;
if (t->next != NULL)
t->len--;
if (t->len <= 0) {
start = t->next;
free(t);
}
t = start;
do {
temp = t;
t = t->next;
} while (t);
if (temp->len < max)
temp->len++;
if (temp->x1 > foodx - 2 && temp->x1 < foodx + 2 && temp->y1 > foody - 2 && temp->y1 < foody + 2) {
max = max + max / 10;
foodx = rand() % 620;
foody = rand() % 460;
score = score + score / 10 + 10;
}
}
void out() {
t = temp2 = start;
while (t) {
temp = temp2;
temp2 = t;
t = t->next;
}
t = start;
while (t->next) {
if (temp2->ch == 'w' && t->ch != 's' && t->ch != 'w' || temp2->ch == 'a' && t->ch != 'd' && t->ch != 'a' || temp2->ch == 's' && t->ch != 'w' && t->ch != 's' || temp2->ch == 'd' && t->ch != 'a' && t->ch != 'd') {
if (temp2->x1 == t->x1) {
if (t->ch == 'w') {
if (temp2->y1 >= t->y1 && temp2->y1 <= (t->y1 + t->len))
flagOut = 1;
}
if (t->ch == 's') {
if (temp2->y1 <= t->y1 && temp2->y1 >= (t->y1 - t->len))
flagOut = 1;
}
}
if (temp2->y1 == t->y1) {
if (t->ch == 'a') {
if (temp2->x1 >= t->x1 && temp2->x1 <= (t->x1 + t->len))
flagOut = 1;
}
if (t->ch == 'd') {
if (temp2->x1 <= t->x1 && temp2->x1 >= (t->x1 - t->len))
flagOut = 1;
}
}
}
if (temp2->y1 == t->y1 && temp2->x1 == t->x1)
flagOut = 0;
t = t->next;
}
}
Explanation: Yup program is quite difficult to understand ,lets start with it.
Why we require linked list?
values of each line of snake is stored respective node.When we change direction of snake a new is created.
Starting with linked list structure,which contains char ch int x1, y1, len, flag struct node *next.Lets see the use of each element.
ch will contain the values 'a' or 's' or 'd' or 'w' i.e direction of that single line.
x1 and y1 will save the starting x and y co-ordinate respectively from which line starts.
len will save the current length of that particular line.
flag will indicate the line is increasing or constant.we will see in detail.
*next will save the address of next node in linked list.
Other variables: flagOut which is initialized to 0 indicates snake is alive and 1 indicates game over.
foodx,foody where to print food.
start = (struct node *) malloc(sizeof (struct node));//allocating memory
start->next = NULL; //as only 1 node is there
start->x1 = 150; //initialized starting point
start->y1 = 200;
start->ch = 'd'; //initialized the direction
start->len = max; //initialized to max
start->flag = 1; //indicates the line should move in direction initialized above
while (1) //so that loop goes in infinite loop
kbhit() this is called whenever any key is pressed
getKey = getch(); //using getch() we take the input i.e which key has been pressed
if (prevKey != getKey && getKey == 'w' || getKey == 'a' || getKey == 's' || getKey == 'd')
prevKey stores the previous direction and getKey stores current so ,if prevKey==getKey then the direction is same so no new linked list should be created and further if both are different then i have checked that the key pressed is legal key i.e a,s,d or w.
if (prevKey == 'w' && getKey != 's' || prevKey == 's' && getKey != 'w' || prevKey == 'a' && getKey != 'd' || prevKey == 'd' && getKey != 'a')
If snake is going up so if some one presses down it should not go as only way is it can go right or left.Similarly other cases.
prevKey = getKey; //this will become our prevous keystroke.
for(i=-1;i<=1;i++)
{
for(j=-1;j<=1;j++)
{
putpixel(foodx+i, foody+j, 4); //prints the pixel at +- 1 postion.
}
}
if (t->ch == 'd') {
line(t->x1, t->y1, t->x1 - t->len, t->y1); //lines of co-ordinate and from where to where it should be printed
if (t->flag) //if direction has been changed then the current line should diminished at a point
t->x1++;
if (t->x1 >= 640) // check if snake crosses a boundary
flagOut = 1; //indicates game over
}
similar other 3 groups codes will work
create() will be called when valid key is pressed to change the direction of snake.
So we create new linked list initialized it with the point where direction has to be changed. Length of this line will start from -1 and will increase up-to max.
check() performs two task.

2)Checks if the snake has eat the food(snake has passed from plotted pixel).If so then generate new pixel position and increment the score.
t = temp2 = start;

temp = temp2;
temp2 = t;
t = t->next;

Through this code we can traverse the linked list and reached the head of snake.So temp2 becomes the head of snake.The whole code in out() is to check if any side of snake is touching each other.
No comments:
Post a Comment