Skip to content

Instantly share code, notes, and snippets.

@FlorianCassayre
Created July 12, 2018 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FlorianCassayre/7c44a8d64f959083462c457ed6e5df32 to your computer and use it in GitHub Desktop.
Save FlorianCassayre/7c44a8d64f959083462c457ed6e5df32 to your computer and use it in GitHub Desktop.
#include "LedControl.h"
#define SIZE 8
#define PIN_MATRIX_DATA 55
#define PIN_MATRIX_CLK 56
#define PIN_MATRIX_CS 54
#define PIN_BUTTON 57
enum State {
PIECE_MOVING,
PIECE_PLACED,
GAME_LOST,
GAME_WON
};
const LedControl matrix = LedControl(PIN_MATRIX_DATA, PIN_MATRIX_CLK, PIN_MATRIX_CS, 1);
State state;
unsigned long last;
int height;
int piecePosition, pieceSize;
bool pieceDirection;
bool mistake;
int pieceRemaining;
long pieceSpeed;
bool layers[SIZE][SIZE];
void setup() {
// Matrix
matrix.shutdown(0, false);
matrix.setIntensity(0, 8);
matrix.clearDisplay(0);
// Button
pinMode(PIN_BUTTON, INPUT);
// Serial
// Serial.begin(9600);
// Initialize game
resetGame();
}
void loop() {
unsigned long diff = millis() - last;
if(state == PIECE_MOVING) {
// Display previous layers
for(int i = 0; i < height - 1; i++) {
for(int j = 0; j < SIZE; j++) {
matrix.setLed(0, i, j, layers[i][j]);
}
}
// Display current layer
for(int i = 0; i < SIZE; i++) {
matrix.setLed(0, height, i, i >= piecePosition && i < piecePosition + pieceSize);
}
if(digitalRead(PIN_BUTTON) == HIGH) { // Button is pressed
mistake = false;
if(height == 0) { // First layer, no check
for(int i = 0; i < pieceSize; i++) {
layers[0][piecePosition + i] = true;
}
} else { // Check that the piece was correctly placed
pieceRemaining = 0;
for(int i = 0; i < pieceSize; i++) {
if(layers[height - 1][piecePosition + i]) { // Square is correctly placed on top of something
layers[height][piecePosition + i] = true;
pieceRemaining++;
} else { // Square is not correctly placed
mistake = true;
}
}
}
height++;
last = millis();
state = PIECE_PLACED;
} else {
if(millis() - last >= pieceSpeed) { // Move piece
if(pieceDirection) { // Should move to the right
if(piecePosition + pieceSize >= SIZE) {
pieceDirection = false;
}
} else {
if(piecePosition <= 0) {
pieceDirection = true;
}
}
piecePosition += pieceDirection ? 1 : -1;
last = millis();
}
}
} else if(state == PIECE_PLACED) {
State next = pieceRemaining > 0 ? (height >= SIZE ? GAME_WON : PIECE_MOVING) : GAME_LOST;
if(mistake) {
if(diff >= 1400) {
for(int i = 0; i < SIZE; i++) { // Reset to state 1
matrix.setLed(0, height - 1, i, layers[height - 1][i]);
}
updateDifficulty();
last = millis();
state = next;
} else if((diff / 200) % 2 == 0) { // Blink state 1
for(int i = 0; i < SIZE; i++) {
matrix.setLed(0, height - 1, i, layers[height - 1][i]);
}
} else { // Blink state 2
for(int i = 0; i < SIZE; i++) {
matrix.setLed(0, height - 1, i, i >= piecePosition && i < piecePosition + pieceSize);
}
}
} else {
if(millis() - last >= 500) {
updateDifficulty();
last = millis();
state = next;
}
}
} else if(state == GAME_LOST) {
if(diff <= 500) { // Animation state 1
// Freeze screen
} else if(diff <= 2000) { // Animation state 2
// Tower falls
int displacement = (diff - 500) / 120;
for(int i = 0; i < SIZE; i++) {
int k = i + displacement; // True row
for(int j = 0; j < SIZE; j++) {
matrix.setLed(0, i, j, k < SIZE ? layers[k][j] : false);
}
}
} else {
resetGame();
}
} else if(state == GAME_WON) {
if(diff <= 3600) { // Blinking inverted colors
bool invert = (diff / 200) % 2 != 0;
for(int i = 0; i < SIZE; i++) {
for(int j = 0; j < SIZE; j++) {
matrix.setLed(0, i, j, layers[i][j] ^ invert);
}
}
} else {
resetGame();
}
}
}
void resetGame() {
state = PIECE_MOVING;
last = millis();
height = 0;
pieceRemaining = 3;
updateDifficulty();
pieceSpeed = 400;
for(int i = 0; i < SIZE; i++) {
matrix.setRow(0, i, (byte) 0);
}
for(int i = 0; i < SIZE; i++) {
for(int j = 0; j < SIZE; j++) {
layers[i][j] = false;
}
}
}
void updateDifficulty() {
int maxPieceSize = height >= 3 ? (height >= 5 ? 1 : 2) : 3;
pieceSize = min(pieceRemaining, maxPieceSize);
piecePosition = random(0, SIZE - pieceSize);
pieceDirection = random(0, 2) == 0;
pieceSpeed -= pieceSpeed / 3;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment