跳到主要內容

LED Tetris




Here is the implementations of code for LED Tetris game.


#include "config.h"
#include <stdio.h>


void write_data(unsigned char,unsigned char); //Writing data to the MAX7219 chip to display different 8x8 LED patterns


unsigned int led_element[8][8];  //Global variables 2D array for static tetris blocks

unsigned int decimal_value=0;

unsigned int row_cancel=0; //stores the current number of rows cancelled

unsigned int button_pressed=0;  unsigned int step_fallen=0 ;

//unsigned int random_total;

unsigned int block_type;

unsigned char x_button=3 ; //Global variables x for the coordinates of the temp falling block
                    //Declaring x corrdinate of temp falling block allows you to modify its coordinate everywhere, in any scope

unsigned int rotation_index = 0;

unsigned int rotation_button_pressed = 2;

unsigned int score=0;

unsigned int n;
unsigned int first_digit;
unsigned int second_digit;


void bingo(); //If 8 LEDs in a row are ON, then this ON-LED row will be cancelled


void block_clear(); //to switch off all the 64 LEDs

void bin_hex();

void block_falling();


void random_block_generator();


void x_button_control();

void block_rotation(unsigned int);

void down_after_bingo(unsigned int);

void digit_check();

void dec_bin(unsigned int);

void _7_seg_display_test();


int main(void)
{

SPCR |= (1<<SPE) | (1<<MSTR) ;
DDRB |= (1<<pin_MOSI) | (1<<pin_SCK) | (1<<pin_SS) ;
DDRC = 0B00001111;
DDRD = 0B11111100;

write_data(decode,0x00);
write_data(intensity,0x01);
write_data(scan_limit,0x07);
write_data(shutdown,0x01);
write_data(display_test,0x00);




block_clear();

while(1)

//_7_seg_display_test();


block_falling();



}//End of While(1)
}//End of main()


void block_falling()
{

unsigned int i;

random_block_generator();

x_button=3;
//block_type=5;
rotation_index=0;
rotation_button_pressed = 2;

switch(block_type)
{

case 1: //block 田
for(i=0;i<=6;i++)
{

    x_button_control(); //Left or Right movement control
block_rotation(block_type);
led_element[i][x_button]=1;    led_element[i][x_button+1]=1; //x is a Global variable
led_element[i+1][x_button]=1;  led_element[i+1][x_button+1]=1;
bin_hex();

_delay_ms(300);

if((led_element[i+2][x_button]==1)||(led_element[i+2][x_button+1]==1))
goto finish;
else
step_fallen++;

if(i<6) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0;    led_element[i][x_button+1]=0; //x is a Global variable
led_element[i+1][x_button]=0;  led_element[i+1][x_button+1]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();

}//end of for loop i
break; //end of Case 1


case 2://block L
for(i=0;i<=6;i++)
{
switch(rotation_index)
{
case 0:
    x_button_control(); //Left or Right movement control
block_rotation(block_type);
led_element[i][x_button]=1;    led_element[i+1][x_button]=1;
led_element[i+2][x_button]=1;  led_element[i+2][x_button+1]=1;
bin_hex();

_delay_ms(300);

if((led_element[i+3][x_button]==1)||(led_element[i+3][x_button+1]==1))
goto finish;
else
step_fallen++;

if(i<5) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0;    led_element[i+1][x_button]=0;
led_element[i+2][x_button]=0;  led_element[i+2][x_button+1]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break;  //End of rotation_index=0

/////////////////////////////////////////////////////////////////
case 1: //Case 1 of Rotation Index

x_button_control(); //Left or Right movement control
block_rotation(block_type);
led_element[i][x_button+1]=1;    led_element[i+1][x_button+1]=1;
led_element[i+1][x_button]=1;  led_element[i+1][x_button-1]=1;
bin_hex();

_delay_ms(300);

if((led_element[i+2][x_button+1]==1)||(led_element[i+2][x_button]==1)||(led_element[i+2][x_button-1]==1))
goto finish;
else
step_fallen++;

if(i<6) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0;    led_element[i+1][x_button]=0;
led_element[i+2][x_button]=0;  led_element[i+2][x_button+1]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break;  //End of rotation_index=1
///////////////////////////////////////////////////////////////

case 2:  //Case 2 of Rotation Index

x_button_control(); //Left or Right movement control
block_rotation(block_type);
led_element[i][x_button]=1;    led_element[i][x_button-1]=1;
led_element[i+1][x_button]=1;  led_element[i+2][x_button]=1;
bin_hex();

_delay_ms(300);

if((led_element[i+3][x_button]==1)||(led_element[i+1][x_button-1]==1))
goto finish;
else
step_fallen++;

if(i<5) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0;    led_element[i][x_button-1]=0;
led_element[i+1][x_button]=0;  led_element[i+2][x_button]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break;  //End of rotation_index=2
/////////////////////////////////////////////////////////////////

case 3:

x_button_control(); //Left or Right movement control
block_rotation(block_type);
led_element[i+1][x_button+1]=1;    led_element[i+1][x_button]=1;
led_element[i+1][x_button-1]=1;  led_element[i+2][x_button-1]=1;
bin_hex();

_delay_ms(300);

if((led_element[i+2][x_button+1]==1)||(led_element[i+2][x_button]==1)||(led_element[i+3][x_button-1]==1))
goto finish;
else
step_fallen++;

if(i<6) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i+1][x_button+1]=0;    led_element[i+1][x_button]=0;
led_element[i+1][x_button-1]=0;  led_element[i+2][x_button-1]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break;  //End of rotation_index=3

}//end of Switching rotation index
}//end of for loop i
break; //end of Case 2 of Block Type

//////////////////////////////////////////////////////////////////////////////////////////////

case 3:  //block .
for(i=0;i<=7;i++)
{
    x_button_control(); //Left or Right movement control
block_rotation(block_type);
led_element[i][x_button]=1;
bin_hex();

_delay_ms(300);

if(led_element[i+1][x_button]==1)
goto finish;
else
step_fallen++;

if(i<7) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0; 

}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();

}//end of for loop i
break; //end of Case 3
///////////////////////////////////////////////////////////////////////////////////////////////

case 4:  //block -|
for(i=0;i<=6;i++)
{
switch(rotation_index)
{
case 0:  // Rotation Index = 0
    x_button_control(); //Left or Right movement control
block_rotation(block_type);
if(i<=5)
{
led_element[i][x_button]=1;      led_element[i+1][x_button]=1;
led_element[i+1][x_button+1]=1;  led_element[i+2][x_button]=1;
}
bin_hex();

_delay_ms(300);


if((led_element[i+3][x_button]==1)||(led_element[i+2][x_button+1]==1))
goto finish;
else
step_fallen++;


if(i<5) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0;      led_element[i+1][x_button]=0;
led_element[i+1][x_button+1]=0;  led_element[i+2][x_button]=0;

}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break;  //End of Rotation Index = 0
//////////////////////////////////////////////////////////////////////////////////

case 1:
x_button_control(); //Left or Right movement control
block_rotation(block_type);
led_element[i][x_button]=1;      led_element[i+1][x_button+1]=1;
led_element[i+1][x_button]=1;  led_element[i+1][x_button-1]=1;
bin_hex();

_delay_ms(300);


if((led_element[i+2][x_button+1]==1)||(led_element[i+2][x_button]==1)||(led_element[i+2][x_button-1]==1))
goto finish;
else
step_fallen++;


if(i<6) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0;      led_element[i+1][x_button+1]=0;
led_element[i+1][x_button]=0;  led_element[i+1][x_button-1]=0;

}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break; //End of Rotation Index = 1
///////////////////////////////////////////////////////////////////////////////////////////////////

case 2:  //Rotation Index = 2
x_button_control(); //Left or Right movement control
block_rotation(block_type);
if(i<=5)
{
led_element[i][x_button]=1;      led_element[i+1][x_button]=1;
led_element[i+1][x_button-1]=1;  led_element[i+2][x_button]=1;
}
bin_hex();

_delay_ms(300);


if((led_element[i+3][x_button]==1)||(led_element[i+2][x_button-1]==1))
goto finish;
else
step_fallen++;


if(i<5) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0;      led_element[i+1][x_button+1]=0;
led_element[i+1][x_button]=0;  led_element[i+1][x_button-1]=0;

}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break; //End of Rotation Index = 2
/////////////////////////////////////////////////////////////

case 3:  //Rotation Index = 3
x_button_control(); //Left or Right movement control
block_rotation(block_type);
if(i<=5)
{
led_element[i+1][x_button]=1;      led_element[i+1][x_button+1]=1;
led_element[i+1][x_button-1]=1;  led_element[i+2][x_button]=1;
}
bin_hex();

_delay_ms(300);


if((led_element[i+2][x_button+1]==1)||(led_element[i+3][x_button]==1)||(led_element[i+2][x_button-1]==1))
goto finish;
else
step_fallen++;


if(i<5) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i+1][x_button]=0;      led_element[i+1][x_button+1]=0;
led_element[i+1][x_button-1]=0;  led_element[i+2][x_button]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break; //End of Rotation Index = 3

}//End of Switching Rotation Index
}//end of for loop i
break;   //end of Case 4
/////////////////////////////////////////////////////////////////////////////////////////////////

case 5:  //block S

for(i=0;i<=6;i++)
{
switch(rotation_index)
{

case 0: // rotation_index = 0
    x_button_control(); //Left or Right movement control
block_rotation(block_type);
if(i<=5)
{
led_element[i][x_button]=1;       led_element[i+1][x_button]=1;
led_element[i+1][x_button+1]=1;   led_element[i+2][x_button+1]=1;
}
bin_hex();

_delay_ms(300);

if((led_element[i+3][x_button+1]==1)||(led_element[i+2][x_button]==1))
goto finish;
else
step_fallen++;

if(i<5) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0;       led_element[i+1][x_button]=0;
led_element[i+1][x_button+1]=0;   led_element[i+2][x_button+1]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break; //End of rotation_index=0
//////////////////////////////////////////////////////////////////////

case 1: // rotation_index = 1
x_button_control(); //Left or Right movement control
block_rotation(block_type);
if(i<=6)
{
led_element[i][x_button+1]=1;       led_element[i][x_button]=1;
led_element[i+1][x_button]=1;   led_element[i+1][x_button-1]=1;
}
bin_hex();

_delay_ms(300);

if((led_element[i+1][x_button+1]==1)||(led_element[i+2][x_button]==1)||(led_element[i+2][x_button-1]==1))
goto finish;
else
step_fallen++;

if(i<6) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button+1]=0;       led_element[i][x_button]=0;
led_element[i+1][x_button]=0;   led_element[i+1][x_button-1]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break; //End of rotation_index=1
///////////////////////////////////////////////////////////////////////////////////////

case 2: // rotation_index = 2
x_button_control(); //Left or Right movement control
block_rotation(block_type);
if(i<=5)
{
led_element[i][x_button-1]=1;       led_element[i+1][x_button]=1;
led_element[i+1][x_button-1]=1;   led_element[i+2][x_button]=1;
}
bin_hex();

_delay_ms(300);

if((led_element[i+3][x_button]==1)||(led_element[i+2][x_button-1]==1))
goto finish;
else
step_fallen++;

if(i<5) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button-1]=0;       led_element[i+1][x_button]=0;
led_element[i+1][x_button-1]=0;   led_element[i+2][x_button]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break; //End of rotation_index=2
///////////////////////////////////////////////////////////////////////////

case 3: // rotation_index = 3
x_button_control(); //Left or Right movement control
block_rotation(block_type);
if(i<=5)
{
led_element[i+1][x_button+1]=1;       led_element[i+1][x_button]=1;
led_element[i+2][x_button]=1;   led_element[i+2][x_button-1]=1;
}
bin_hex();

_delay_ms(300);

if((led_element[i+2][x_button+1]==1)||(led_element[i+3][x_button]==1)||(led_element[i+2][x_button-1]==1))
goto finish;
else
step_fallen++;

if(i<5) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i+1][x_button+1]=0;       led_element[i+1][x_button]=0;
led_element[i+2][x_button]=0;   led_element[i+2][x_button-1]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
break; //End of rotation_index=3





}//end of switching rotation_index
}//End of for loop i
break; //end of Case 5
////////////////////////////////////////////////////////////////////////

case 6:  //block |
for(i=0;i<=7;i++)
{
switch(rotation_index)
{
case 0:

    x_button_control(); //Left or Right movement control
block_rotation(block_type);


if(i<=5)
led_element[i][x_button]=1;   led_element[i+1][x_button]=1;    led_element[i+2][x_button]=1;
bin_hex();

_delay_ms(300);

/*Checking if the LED element(s) beneath is ON, if yes,
then the block will stop right there */
if(led_element[i+3][x_button]==1)
goto finish;
else
step_fallen++;

if(i<5) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i][x_button]=0;   led_element[i+1][x_button]=0;    led_element[i+2][x_button]=0;
}

x_button_control();
block_rotation(block_type);

bin_hex();
bingo();

break; //End of Case 0 of rotation_index

////////////////////////////////////////////

case 1:

x_button_control(); //Left or Right movement control
block_rotation(block_type);

led_element[i+1][x_button-1]=1;   led_element[i+1][x_button]=1;    led_element[i+1][x_button+1]=1;
bin_hex();

_delay_ms(300);

/*Checking if the LED element(s) beneath is ON, if yes,
then the block will stop right there */
if((led_element[i+2][x_button-1]==1)||(led_element[i+2][x_button]==1)||(led_element[i+2][x_button+1]==1))
goto finish;
else
step_fallen++;

if(i<6) //The old tetris block will always be deleted unless it reaches the bottom
{
led_element[i+1][x_button-1]=0;   led_element[i+1][x_button]=0;    led_element[i+1][x_button+1]=0;
}

x_button_control();
block_rotation(block_type);
bin_hex();
bingo();
 
} //end of switch(rotation_index)
}//end of for loop i
}//end of switch(block_type)

finish: ;
}//end of block_falling()





void block_clear()
{
int i,j;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
led_element[i][j]=0;
}
bin_hex();

//static_led_display_bottom(1);
}  //block_clear() is hidden

void write_data(unsigned char register_address, unsigned  char data)
{

SLAVE_SELECT;
SPDR = register_address;
while (!(SPSR & (1 << SPIF)));

SPDR = data;
while (!(SPSR & (1 << SPIF)));
SLAVE_DESELECT;
}  //write_data() is hidden

void bin_hex()
{
unsigned int i,j;

for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
decimal_value += led_element[i][j]*((int)ceil(pow(2,j)));
}
write_data((i+1),decimal_value);
decimal_value = 0;

}
}  //bin_hex() is hidden


void x_button_control()
{

if((x_button>=0)&&(x_button<=6))
{

if(PIND==0x01) 
{
x_button--; 
button_pressed++;
if(x_button<0)
x_button=0;
//if(x_button<0)

}
         

if(PIND==0x02) 
{
x_button++; 
button_pressed++;
if(x_button>6)
x_button=6;
//if(x_button>7)
//x_button--;
}
}
       
}

void bingo()
{
unsigned int i,j,k; unsigned int dec;

unsigned int row_bingo=0;


for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
dec += led_element[i][j]*((int)ceil(pow(2,j)));
}
if(dec==255)
{
row_bingo=i;
write_data((i+1),0x00);
for(k=0;k<8;k++)
led_element[i][k]=0;
row_cancel++;
score++;
}

dec = 0;

} //end of for loop i
digit_check();
if(row_cancel>0)
down_after_bingo(row_bingo);
}  //bingo()


void down_after_bingo(unsigned int row_bingo)
{
int i,j,k;
for(i=row_bingo;i>=0;i--) //you need to scan the ON LEDs from bottom to the top
{                //If you don't understand, you may DM me
for(j=0;j<8;j++)
{
if(led_element[i][j]==1)               

for(k=1;k <= row_cancel ; k++)
led_element[i+k][j]=1; //set the new LEDs to 1 falling down after bingo()
led_element[i][j]=0;   //set the old LEDs to 0

} //end of for loop j
} //end of for loop i
bin_hex();
row_cancel=0;
_delay_ms(230);
}  //down_after_bingo()


void block_rotation(unsigned int block_type)
{
int n;

switch(block_type)
{
case 1:
break;

case 2:
if(PIND==0x04)
rotation_button_pressed++;
for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(2+n))
rotation_index=0;
}

for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(3+n))
rotation_index=1;
}

for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(4+n))
rotation_index=2;
}

for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(5+n))
rotation_index=3;
}
break;

case 3:
break;

case 4:
if(PIND==0x04)
rotation_button_pressed++;
for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(2+n))
rotation_index=0;
}

for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(3+n))
rotation_index=1;
}

for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(4+n))
rotation_index=2;
}

for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(5+n))
rotation_index=3;
}
break;

case 5:
if(PIND==0x04)
rotation_button_pressed++;
for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(2+n))
rotation_index=0;
}

for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(3+n))
rotation_index=1;
}

for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(4+n))
rotation_index=2;
}

for(n=0;n<40;n+=4)
{
if(rotation_button_pressed==(5+n))
rotation_index=3;
}
break;

case 6:

if(PIND==0x04)
rotation_button_pressed++;

if(rotation_button_pressed % 2 == 0)
rotation_index=0;
else
rotation_index=1;
break;
}
}

void digit_check()
{


/*for(n=0 ; n<=9 ; n++)
{
if((score-n)%10==0)
{
first_digit=n;
second_digit = (score-n)/10 ;
}
}
dec_bin(first_digit,second_digit);*/

dec_bin(score);

}

void dec_bin(unsigned int first_digit) //for displaying the score on 7 Segment Display
{
switch(first_digit)
{
case 0:
PORTC=0x00;
break;
case 1:
PORTC=0x01;
break;
case 2:
PORTC=0x02;
break;
case 3:
PORTC=0x03;
break;
case 4:
PORTC=0x04;
break;
case 5:
PORTC=0x05;
break;
case 6:
PORTC=0x06;
break;
case 7:
PORTC=0x07;
break;
case 8:
PORTC=0x08;
break;
case 9:
PORTC=0x09;
break;
}
}
/*
void _7_seg_display_test()
{
PORTC=0x00;
_delay_ms(1000);
PORTC=0x01;
_delay_ms(1000);
PORTC=0x02;
_delay_ms(1000);
PORTC=0x03;
_delay_ms(1000);
PORTC=0x04;
_delay_ms(1000);
PORTC=0x05;
_delay_ms(1000);
PORTC=0x06;
_delay_ms(1000);
PORTC=0x07;
_delay_ms(1000);
PORTC=0x08;
_delay_ms(1000);
PORTC=0x09;
_delay_ms(1000);
} */

void random_block_generator()
{
unsigned int i,j;

unsigned int tag[6][8]= {{1,5,9,16,19,23,29,37},{3,7,10,12,17,24,32,42},
{2,6,13,18,25,30,36,46},{4,11,15,21,26,31,35,41},
{8,20,27,34,40,44,47,48},{14,22,28,33,38,39,43,45}};


if((button_pressed + step_fallen+1)>48)
{
button_pressed=0; step_fallen=0;
}

if((button_pressed + step_fallen+1)<=48)
{
for(i=0;i<6;i++)
{
for(j=0;j<8;j++)
{
if((button_pressed + step_fallen+1)==tag[i][j])
{
block_type=(i+1);

}
}
}

}
}

留言

這個網誌中的熱門文章

DIY Electronic Alarm

This is my DIY Electronic Alarm, now the prototype has been finished with breadboard, but the PCB layout has not been finished yet. I use a MCU(Arduino Uno) and four 74LS47 7-segment-display drivers to control the four 7-segment-displays to show the digits of Minutes and Seconds. When the alarm is triggered, the buzzer will generate sound.

Heart-shaped LED Chaser PCB Board

Using Printed Circuit Board (PCB) can give you a neat and stable electronic circuit assembly. A month ago I used PCB technology to make a heart-shaped LED Chaser board.