#include <LedControl.h>
#include <ezButton.h>
LedControl lc = LedControl(2, 4, 3, 4);
//ezButton button(7);
int currentRow = 0;
int timeDelay = 10; // * 10ms
int BlockWidth = 4;
int buttonPin = 7;
void(* resetFunc) (void) = 0; // declare reset fuction at address 0
byte row[] = {
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
byte fourBlockSweep[] = { //length is 20
0b10000000,
0b11000000,
0b11100000,
0b11110000,
0b01111000,
0b00111100,
0b00011110,
0b00001111,
0b00000111,
0b00000011,
0b00000001,
0b00000011,
0b00000111,
0b00001111,
0b00011110,
0b00111100,
0b01111000,
0b11110000,
0b11100000,
0b11000000
};
int fourBlockSweepLength = 20;
byte threeBlockSweep[] = { // length is 18
0b10000000,
0b11000000,
0b11100000,
0b01110000,
0b00111000,
0b00011100,
0b00001110,
0b00000111,
0b00000011,
0b00000001,
0b00000011,
0b00000111,
0b00001110,
0b00011100,
0b00111000,
0b01110000,
0b11100000,
0b11000000
};
int threeBlockSweepLength = 18;
byte twoBlockSweep[] = { // length is 16
0b10000000,
0b11000000,
0b01100000,
0b00110000,
0b00011000,
0b00001100,
0b00000110,
0b00000011,
0b00000001,
0b00000011,
0b00000110,
0b00001100,
0b00011000,
0b00110000,
0b01100000,
0b11000000
};
int twoBlockSweepLength = 16;
byte oneBlockSweep[] = { // length is 14
0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000
};
int oneBlockSweepLength = 14;
void setup() {
// put your setup code here, to run once:
pinMode(7, INPUT_PULLUP);
}
void loop() {
// put your main code here, to run repeatedly:
//inGame();
//updateDisplay();
pressToPlayScreen();
}
void inGame() { //run this code when the game is running
for(int i = 0; i < 100; i++){
if (BlockWidth == 1){
if (i > oneBlockSweepLength - 1){
i = 0;
}
row[currentRow] = oneBlockSweep[i];
updateOneRowOnly(currentRow);
}
if (BlockWidth == 2){
if (i > twoBlockSweepLength - 1){
i = 0;
}
row[currentRow] = twoBlockSweep[i];
updateOneRowOnly(currentRow);
}
if (BlockWidth == 3){
if (i > threeBlockSweepLength - 1){
i = 0;
}
row[currentRow] = threeBlockSweep[i];
updateOneRowOnly(currentRow);
}
if (BlockWidth == 4){
if (i > fourBlockSweepLength - 1){
i = 0;
}
row[currentRow] = fourBlockSweep[i];
updateOneRowOnly(currentRow);
}
for(int wait = 0; wait < timeDelay; wait++){
delay(10);
if (!digitalRead(7)){
delay(500);
checkPlacement();
delay(500);
currentRow++;
checkSpeed();
checkBlockWidth();
checkLoseWin();
//break;
}
}
}
}
void checkPlacement() {
int lastRow = currentRow - 1;
if (currentRow > 0){
row[currentRow] = row[currentRow] & row[lastRow];
}
BlockWidth = count_bits(row[currentRow]);
updateDisplay();
}
void checkLoseWin(){
//check if the game is lost or won
if (BlockWidth == 0){
gameOverScreen();
}
if (currentRow == 32){
winScreen();
}
}
void gameOverScreen(){
int fadeDelay = 50;
byte gameRows[] = {
0b01111110, //letter G
0b00000001,
0b00000001,
0b00000001,
0b11000001,
0b10000001,
0b10000001,
0b01111110,
0b01111110, //letter A
0b10000001,
0b10000001,
0b10000001,
0b11111111,
0b10000001,
0b10000001,
0b10000001,
0b10000001, //letter M
0b11000011,
0b10100101,
0b10011001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b11111111, //letter E
0b00000001,
0b00000001,
0b00000001,
0b11111111,
0b00000001,
0b00000001,
0b11111111
};
byte overRows[] = {
0b01111110, //letter O
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b01111110,
0b10000001, //letter V
0b10000001,
0b01000010,
0b01000010,
0b00100100,
0b00100100,
0b00011000,
0b00011000,
0b11111111, //letter E
0b00000001,
0b00000001,
0b00000001,
0b11111111,
0b00000001,
0b00000001,
0b11111111,
0b01111111, //letter R
0b10000001,
0b10000001,
0b01111111,
0b00000111,
0b00011001,
0b01100001,
0b10000001
};
int j = 0;
for (int i = 31; i >= 0; i--){
row[i] = gameRows[j];
updateOneRowOnly(i);
j++;
delay(fadeDelay);
}
delay(1000);
j = 0;
for (int i = 31; i >= 0; i--){
row[i] = overRows[j];
updateOneRowOnly(i);
j++;
delay(fadeDelay);
}
delay(1000);
resetFunc();
}
void winScreen(){
int fadeDelay = 50;
byte youRows[] = {
0b01000001, //letter Y
0b00100010,
0b00010100,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b01111110, //letter O
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b01111110,
0b00000000,
0b10000001, //letter U
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b01111110,
0b00000000, //empty
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
byte winRows[] = {
0b10000001, //letter W
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10011001,
0b10100101,
0b01000010,
0b00111110, //letter I
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00111110,
0b10000011, //letter N
0b10000101,
0b10001001,
0b10010001,
0b10010001,
0b10100001,
0b11000001,
0b10000001,
0b00000000, //empty
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
int j = 0;
for (int i = 31; i >= 0; i--){
row[i] = youRows[j];
updateOneRowOnly(i);
j++;
delay(fadeDelay);
}
delay(1000);
j = 0;
for (int i = 31; i >= 0; i--){
row[i] = winRows[j];
updateOneRowOnly(i);
j++;
delay(fadeDelay);
}
delay(1000);
resetFunc();
}
void pressToPlayScreen(){
int fadeDelay = 50;
byte pushRows[] = {
0b01111111, //letter P
0b10000001,
0b10000001,
0b01111111,
0b00000001,
0b00000001,
0b00000001,
0b00000000,
0b10000001, //letter U
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b01111110,
0b00000000,
0b01111110, //letter S
0b00000001,
0b00000001,
0b01111110,
0b10000000,
0b10000000,
0b01111111,
0b00000000,
0b10000001, //letter H
0b10000001,
0b10000001,
0b11111111,
0b10000001,
0b10000001,
0b10000001,
0b00000000
};
byte toRows[] = {
0b01111111, //letter T
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00000000,
0b01111110,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b01111110,
0b00000000,
0b00000000, //empty
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000, //empty
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
byte playRows[] = {
0b00000000, //letter P
0b01111111,
0b10000001,
0b10000001,
0b01111111,
0b00000001,
0b00000001,
0b00000001,
0b00000000, //letter L
0b00000001,
0b00000001,
0b00000001,
0b00000001,
0b00000001,
0b00111111,
0b00000000,
0b01111110, //letter A
0b10000001,
0b10000001,
0b11111111,
0b10000001,
0b10000001,
0b10000001,
0b00000000,
0b01000001, //letter Y
0b00100010,
0b00010100,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00000000
};
int j = 0;
for (int i = 31; i >= 0; i--){
row[i] = pushRows[j];
updateOneRowOnly(i);
j++;
delay(fadeDelay);
if(!digitalRead(buttonPin)){startGame();}
}
for(int wait = 0; wait < 100; wait++){ //wait 100*10ms if there is no input
if(!digitalRead(buttonPin)){startGame();}
delay(10);
}
j = 0;
for (int i = 31; i >= 0; i--){
row[i] = toRows[j];
updateOneRowOnly(i);
j++;
delay(fadeDelay);
if(!digitalRead(buttonPin)){startGame();}
}
j = 0;
for(int wait = 0; wait < 100; wait++){
if(!digitalRead(buttonPin)){startGame();}
delay(10);
}
for (int i = 31; i >= 0; i--){
row[i] = playRows[j];
updateOneRowOnly(i);
j++;
delay(fadeDelay);
if(!digitalRead(buttonPin)){startGame();}
}
for(int wait = 0; wait < 100; wait++){
if(!digitalRead(buttonPin)){startGame();}
delay(10);
}
}
void checkSpeed(){
//change the speed depending on the height of the tower
if(currentRow >= 7){
timeDelay = 8;
}
if(currentRow >= 15){
timeDelay = 6;
}
if(currentRow >= 23){
timeDelay = 4;
}
}
void checkBlockWidth(){
//change the width of the block when you pass a certain heigth
if(currentRow >= 7 && BlockWidth > 3){
BlockWidth = 3;
}
if(currentRow >= 15 && BlockWidth > 2){
BlockWidth = 2;
}
if(currentRow >= 23 && BlockWidth > 1){
BlockWidth = 1;
}
}
void startGame(){
clearScreen();
delay(1000);
inGame();
}
void updateDisplay() {
for (int i = 0; i < 8; i++)
{
lc.setColumn(0,i,row[i]);
}
for (int i = 8; i < 16; i++)
{
lc.setColumn(1,i - 8,row[i]);
}
for (int i = 16; i < 24; i++)
{
lc.setColumn(2,i - 16,row[i]);
}
for (int i = 24; i < 32; i++)
{
lc.setColumn(3,i - 24,row[i]);
}
}
void updateOneRowOnly(int rowToUpdate) {
if (rowToUpdate < 8){
lc.setColumn(0,rowToUpdate,row[rowToUpdate]);
}else if (rowToUpdate < 16){
lc.setColumn(1,rowToUpdate - 8,row[rowToUpdate]);
}else if (rowToUpdate < 24){
lc.setColumn(2,rowToUpdate - 16,row[rowToUpdate]);
}else{
lc.setColumn(3,rowToUpdate - 24,row[rowToUpdate]);
}
}
int count_bits(unsigned char byte) {
int count = 0;
for (int i = 0; i < 8; i++) {
if (byte & 1) { // check the least significant bit
count++; // increment the counter
}
byte >>= 1; // right shift the byte by one bit
}
return count;
}
void clearScreen(){
for (int i = 0; i < 32; i++){
row[i] = 0b00000000;
}
updateDisplay();
}