Friday, April 8, 2011

Snake Game


Remember Playing Snake Game on Nokia 3310!!!!

Here is something for you:

Snake game that runs on LEDs. It was fun playing with it...


This is my circuit diagram. It uses 8051 family microcontroller, 16*8 LEDs, 4 switches for up down, left, right operations and a simple LED Driver.



And here is PCB Layout in Express PCB.


And yeah.... dear code. I used C this time considering complexity of the system.



#include<reg51.h>

unsigned char display_data[] = {255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
unsigned char const rows[] = {0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
unsigned char const add[] = {128,64,32,16,8,4,2,1,128};
unsigned int positions[] = {0,16,32,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned char length = 3;
unsigned int food,nextFood;

unsigned char direction = 0 ;
unsigned char lastSpeed=10,speed = 10;

void delay(void);
void initialise(void);
void timer1 (void);
void timer0 (void);

bit levelStarted = 0;
bit gameOver = 0;

void main(void){
unsigned char i = 0;
initialise();

while(1){

if(P3 == 0xfd && (direction != 2)){
direction = 0;
levelStarted = 1;
}
if(P3 == 0xfb&& (direction != 3)){
direction = 1;
levelStarted = 1;
}
if(P3 == 0xf7&& (direction != 0)){
direction = 2;
levelStarted = 1;
}
if(P3 == 0xfe&& (direction != 1)){
direction = 3;
levelStarted = 1;
}

for(i=0;i<8;i++){
P0 = rows[i];
P1 = 255 - display_data[i];
P2 = 255 - display_data[i+8];
delay();
}
}
}

void delay(void){
unsigned char i = 0;
unsigned char j = 0;
unsigned char K = 0;
for(i=0;i<2;i++){
for(j=0;j<5;j++){
for(K=0;K<5;K++){
}
}
}
}


void initialise(void){
IE = 0x8a;
TMOD = 0x11;
TH1 = 128;
TH0 = 0;
TR1 = 1;
TR0 = 1;
}


void timer0 (void) interrupt 1{
nextFood ++;
TH0 = nextFood/13;
nextFood = nextFood % 128;
}


void timer1 (void) interrupt 3{
unsigned char row;// = start_position / 16;
unsigned char col;// = start_position % 16;
unsigned char i;// = start_position % 16;
if(--speed == 0){
speed = lastSpeed;

if (levelStarted == 1 ){

if (positions[length-1] == food){
length++;
positions[length-1] = food;
food = nextFood;
}  else {
for(i=1;i<length;i++){
positions[i-1] = positions[i];
}
}


row = positions[length-1]/16;
col = positions[length-1]%16;

if (direction == 0){
if(row == 7){
positions[length-1] = positions[length-2] % 16;
} else {
positions[length-1] = positions[length-2] + 16;
}
}

if (direction == 1){
if(col == 15){
positions[length-1] = positions[length-2] - 15;
} else {
positions[length-1] = positions[length-2] + 1;
}
}

if (direction == 2){
if(row == 0){
positions[length-1] = positions[length-2] + (16*7);
} else {
positions[length-1] = positions[length-2] - 16;
}
}

if (direction == 3){
if(col == 0){
positions[length-1] = positions[length-2] + 15;
} else {
positions[length-1] = positions[length-2] - 1;
}
}
}


if(length == 16){   // level change triggerred
length = 3;
levelStarted = 0;
positions[0] = 0;
positions[1] = 16;
positions[2] = 32;
lastSpeed--;
speed = lastSpeed;
direction = 0;
}

//detect gameover
for(row=0;row<length;row++){
for(col=0;col<length;col++){
if(col!=row){
if(positions[row] == positions[col]){
gameOver = 1;
}
}
}
}



for (i=0;i<16;i++){
display_data[i] = 255;
}

for (i=0;i<length;i++){
row = positions[i]/16;
col = positions[i]%16;
display_data[col] = display_data[col] & (255-add[row]);
}

if(levelStarted == 1){
row = food/16;
col = food%16;
display_data[col] = display_data[col] & (255-add[row]);
} else {
food = nextFood;
}

if(gameOver == 1){
for (i=0;i<16;i++){
display_data[i] = 0;
}
}
  }
}