//build error :)
#define CLK 13
#define DIN 11
#define CS 10
#define X_SEGMENTS 4
#define Y_SEGMENTS 2
#define NUM_SEGMENTS (X_SEGMENTS * Y_SEGMENTS)
#define rb 5
#define gb 4
#define yb 6
#define bb 7
byte fb[8 * NUM_SEGMENTS];
int matrix[16][32];
int dir = 0;
int last_dir = 0;
unsigned long start = millis();
bool gameOver = false;
int prevTop = 0;
int prevBottom = 0;
int minDistance = 1; //minimum distance between any 2 walls so that the spaceship can cross
bool autopilot = true;
int ship_line = 8;
int score = 0;
void generateWalls1(int column){
srand(analogRead(0));
//generate current Top wall size
//it needs to not connect with the previous bottom wall or current buttom wall
int currTop = rand()%(16 - (minDistance + prevBottom));
//reset the rng
srand(analogRead(0));
int currBottom = rand()%(16 - (max(prevTop, currTop) + minDistance));
//update the limits
prevTop = currTop;
prevBottom = currBottom;
//building the walls
for(int line = 0; line < currTop; ++line){
matrix[line][column] = 1;
}
for(int line = 15; line >= 15 - currBottom; --line){
matrix[line][column] = 1;
}
}
void generateWalls2(int column){
//shift size by 1
}
void shiftWalls(){
for(int line = 0; line < 16; ++line){
for(int col = 0; col < 31; ++col){
matrix[line][col] = matrix[line][col+1];
}
}
if(matrix[ship_line][0] == 1){
gameOver = true;
Serial.println("lovit in miscare");
}
//clean and regenerate lasgt column
for(int line = 0; line < 16; ++line){
matrix[line][31] = 0;
}
generateWalls1(31);
matrix[ship_line][0] = 2;
}
bool updateDirection(){
bool changed = false;
byte rbtn = digitalRead(rb);
byte gbtn = digitalRead(gb);
byte bbtn = digitalRead(bb);
byte ybtn = digitalRead(yb);
if (rbtn==1){
changed = true;
dir = 1;
}else if(gbtn == 1){
if(autopilot){
autopilot = false;
Serial.println("Control manual activat - Drum bun o7!");
}else{
Serial.println("Autopilot reactivat");
autopilot = true;
}
}else if(bbtn == 1){
changed = true;
dir = -1;
}else if(ybtn == 1){
if(autopilot){
autopilot = false;
Serial.println("Control manual activat - Drum bun o7!");
}else{
Serial.println("Autopilot reactivat");
autopilot = true;
}
}
return changed;
}
void shiftAll(byte send_to_address, byte send_this_data){
digitalWrite(CS, LOW);
for (int i = 0; i < NUM_SEGMENTS; i++) {
shiftOut(DIN, CLK, MSBFIRST, send_to_address);
shiftOut(DIN, CLK, MSBFIRST, send_this_data);
}
digitalWrite(CS, HIGH);
}
void matrixToDisplay(){
int v;
int fb_ind = 63;
for(int line_ind = 0; line_ind < 16; ++line_ind){
for(int col_ind = 0; col_ind < 32; col_ind += 8){
v = 0;
for(int i=0; i < 8; ++i){
v |= ((matrix[line_ind][col_ind + 7 - i] > 0) << i); //sau la shiftare 7-i
}
fb[fb_ind] = v;
--fb_ind;
}
}
}
void show() {
matrixToDisplay();
for (byte row = 0; row <= 7; row++) {
digitalWrite(CS, LOW);
byte segment = NUM_SEGMENTS;
while (segment--) {
//compute row and column
byte x = segment % X_SEGMENTS;
byte y = segment / X_SEGMENTS * 8;
//compute address given the above
byte addr = (row + y) * X_SEGMENTS;
// odd rows of segments
if (segment & X_SEGMENTS) {
shiftOut(DIN, CLK, MSBFIRST, 8 - row);
shiftOut(DIN, CLK, LSBFIRST, fb[addr + x]);
} else {
shiftOut(DIN, CLK, MSBFIRST, 1 + row);
shiftOut(DIN, CLK, MSBFIRST, fb[addr - x + X_SEGMENTS - 1]);
}
}
digitalWrite(CS, HIGH);
}
}
void setup() {
Serial.begin(115200);
pinMode(CLK, OUTPUT);
pinMode(DIN, OUTPUT);
pinMode(CS, OUTPUT);
// Setup each MAX7219
shiftAll(0x0f, 0x00); //display test register - test mode off
shiftAll(0x0b, 0x07); //scan limit register - display digits 0 thru 7
shiftAll(0x0c, 0x01); //shutdown register - normal operation
shiftAll(0x0a, 0x0f); //intensity register - max brightness
shiftAll(0x09, 0x00); //decode mode register - No decode
//genereaza starea initiala a jocului
matrix[ship_line][0] = 2;
for(int col = 5; col < 32; ++col){
generateWalls1(col);
}
show();
pinMode(23, OUTPUT);
pinMode(bb, INPUT);
pinMode(gb, INPUT);
pinMode(rb, INPUT);
pinMode(yb, INPUT);
}
unsigned long start_time = millis();
unsigned long button_delay = millis();
void loop() {
if(!gameOver){
//button_delay pentru a evita citirea aceleiasi miscari de mai multe ori
if(millis() - button_delay > 100){
button_delay = millis();
//verifica aparitia unei noi miscari si actualizeaza pozitia navei
if(updateDirection()){
if(!autopilot){
//nava nu poate calatori sub marginea matricei
if(!((ship_line == 0 && dir == -1) || (ship_line == 15 && dir == 1))){
matrix[ship_line][0] = 0;
//nava a virat intr-un perete
if(matrix[ship_line+dir][0] == 1){
gameOver = true;
Serial.println("Lovit in viraj");
}
ship_line += dir;
matrix[ship_line][0] = 2;
show();
dir = 0;
}
}
}
}
//actualizeaza starea peretilor la fiecare 1500ms si incrementeaza valoarea score ului daca autopilotul e dezactivat
if(millis() - start_time > 1500){
start_time = millis();
shiftWalls();
if(!autopilot){
score++;
Serial.println(score);
}
// Serial.println("shifted");
show();
}
}
}