For
more information ... http://en.wikipedia.org/wiki/Linked_list
Now implement snake class methods:
The constructor
snake::snake()
{
start = NULL; // start node point to
null
current = NULL; // same
newtail = NULL; // same
console_handle=GetStdHandle(
STD_OUTPUT_HANDLE ); // getting console
handle
foodx=12; // starting food positions
foody=14;
}
The drawwall method this will draw boundary for our snake game
void snake::drawWall()
{
/*
for drawing wall you can use variables to store wall starting and ending
position
*/
// draw left column
cur_cord.X=0;
for(int y=0;y<=30;y++)
{
cur_cord.Y=y;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << '#';
}
// draw top row
cur_cord.Y=0;
for(int x=0;x<=30;x++)
{
cur_cord.X=x;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << '#';
}
// draw right column
cur_cord.X=30;
for(int y=0;y<=30;y++)
{
cur_cord.Y=y;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << '#';
}
// draw bottom row
cur_cord.Y=30;
for(int x=0;x<=30;x++)
{
cur_cord.X=x;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << '#';
}
}
Draw the food for our snake
void snake::drawfood(int x)
{
tail *tmp;
tmp=start->next;
if(x==1) // draw new food
{
foodx=rand()%20+7; // rand number
between 2 to 27
foody=rand()%20+7;
/*check
if food not created on snake body
so we will loop
through all snake node and check
if snake body pos meet with food
position
if yes the generate
new position else continue
*/
while(tmp->next!=NULL)
{
if(foodx ==
tmp->x && foody == tmp->y)
{
drawfood(1);
}
tmp=tmp->next;
}
}
}
Increasing snake length
. when snake eat food its length should increase . For this
We have insert method
void snake :: insert(int x , int y)
{
//
check if start is null
if(start == NULL)
{
newtail = new tail;
newtail->x=x;
newtail->y=y;
newtail->next=NULL;
newtail->prev=NULL;
start=newtail;
current=newtail;
}
else // insert new node
to start node
{
newtail = new tail;
newtail->x=x;
newtail->y=y;
newtail->next=NULL;
newtail->prev=current;
current->next=newtail;
current=newtail;
}
}
This method just append a
new tailposition structure to the tailpos structure.
Here ‘start’ varaible points to node1
where as ‘current’ variable points to node3 i.e the last node.
After appending the
new node.
After appending the new node the
‘current’ variable points to newely created last node i.e node4.
Now the best part how
to move snake ? So the tails follow the head.
You know in game
tails follow the head every where it goes.
So first Question how
to move snake head?
Ans : Simple we have
to print snake head at new cordinate at console every cycle.
We can increment the current X,Y
position of console. To move snake in specified direction.
Q: How to make tail follow the head ?
Ans
: The tailpos structure which keep position of every part of snake. We just
have to move value of head to its tail and value of first tail should move to
next tail till last and increment position of head . In simple way remove value
of last tail put previous tail value in it .
This way position of snake parts is shifted
The code to move:
void snake::move()
{
tail *tmp,*cur; //
cur no use
tmp =current; //
point tmp to last node
//cur
=start->next;
while(tmp->prev!=NULL)
{
tmp->x=tmp->prev->x;
// copy val from revious to last
tmp->y=tmp->prev->y;
tmp=tmp->prev; // set tmp to previous node
}
/*
check for the value
of d in order to change its direction
*/
if(d==1)
start->y--;
if(d==2)
start->y++;
if(d==3)
start->x--;
if(d==4)
start->x++;
}
The move method is
called every cycle.
Collision Detection:
To check collision we
can simpily compare snake head posiotion with
1)
Its
tail
2)
Wall
3)
Food
Code to collision:
bool
snake::collision()
{
tail *tmp;
tmp=start->next;
//check collision with
itself
while(tmp->next!=NULL)
{
if(start->x ==
tmp->x && start->y == tmp->y)
return true;
tmp=tmp->next;
}
//check collision with food
if(start->x == foodx
&& start->y == foody)
{
insert(foodx,foody);
drawfood(1); // draw food at new position
}
//check collision with
wall
//collision top
for(int
x=0;x<=30;x++)
{
if(start->x
== x && start->y == 0)
{
return
true;
}
}
//collision left
for(int
y=0;y<=30;y++)
{
if(start->x == 0 && start->y == y)
{
return
true;
}
}
//collision right
for(int
y=0;y<=30;y++)
{
if(start->x == 30
&& start->y == y)
{
return
true;
}
}
//collision bottom
for(int
x=0;x<=30;x++)
{
if(start->x == x && start->y == 30)
{
return
true;
}
}
return false;
}
Rendering the game:
void snake::draw()
{
drawWall(); // draw
wall
tail *tmp;
tmp=start;
while(tmp!=NULL)
{
cur_cord.X=tmp->x;
cur_cord.Y=tmp->y;
SetConsoleCursorPosition(console_handle,cur_cord);
//cout <<
"*" << cur_cord.X <<"-" << cur_cord.Y
;
cout <<
"#"; // print any value you want
tmp=tmp->next;
}
//draw the food
cur_cord.X=foodx;
cur_cord.Y=foody;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << "?"; // print any
value you want
}
This method prints wall , snake , food
at the console.
The game loop:
The game loop which
is repeated every time to draw snake,take input and process , and detect
collision
int main()
{
snake ob; // snake object
ob.insert(10,5); //
insert snake body
ob.insert(10,4); //
insert snake body
ob.insert(10,3);
ob.insert(10,2);
//ob.draw();
int dir=1; // initial
direction
while(1) // main loop
{
ob.draw(); // draw
food snake wall
Sleep(100); // wait
after draw better to use a timer
system("CLS");
// clearthe screen
if(ob.collision())// check for
collision
{
cout << " you died
";
break;
}
if(kbhit())// check if keyboard key
is pressed
{
switch(getch())
{
case 'w':d=1;
break;
case 's':d=2;
break;
case 'a':d=3;
break;
case 'd':d=4;
break;
case 'm':ob.insert(10,7);
break;
}
}
ob.move();
// move the snake
}
// to wait for user
input
getch();
return 0;
}
I have used W,A,S,D key to control .
This is just the core of the game
there is no welcome screen nor end screen . and there is score .
You can implement these your self.
The main problem in
the game screen flicker every time. This problem can be elminated which I will
discuss in Next Part. OR implement it your self thats easy.
I am sorry because The post is not formatted nor any synatx hilighter. I I am just getting started with blog.Maybe I will update it later
Here is the complete code copy and paste it