[CLEANUP] Refactored the code

This commit is contained in:
Diogo Cordeiro 2020-02-13 16:15:23 +00:00
parent 297095a166
commit 5e8402354e
2 changed files with 234 additions and 352 deletions

View File

@ -1,153 +0,0 @@
#define BOARD_LENGTH 8
struct pair {
int x;
int y;
};
class Snake {
private:
char state;
int snake_size;
pair pos[64];
pair get_next_move(pair p);
public:
Snake() {
this->state = 'U';
this->snake_size = 4;
for (int i = snake_size - 1; i >= 0; i--) {
pair p;
p.x = 5;
p.y = i;
this->pos[i] = p;
}
}
void change_state(char m);
void eat(pair p);
void snake_to_matrix(int (*pixels)[BOARD_LENGTH]){
for(int i = 0; i < BOARD_LENGTH; i++){
for(int j = 0; j < BOARD_LENGTH; j++){
pixels[i][j] = HIGH; // CLEAR ALL PIXELS;
}
}
for(int i = 0; i < snake_size; i++) {
pair p = pos[i];
pixels[p.x][p.y] = LOW; // TURN ON PIXELS OF SNAKE
}
}
void next_move();
pair snake_head() {
return pos[0];
}
};
pair Snake::get_next_move(pair p) {
pair r;
switch (state) {
case 'U':
r.x = (p.x + BOARD_LENGTH - 1) % BOARD_LENGTH;
r.y = p.y;
break;
case 'D':
r.x = (p.x + 1) % BOARD_LENGTH;
r.y = p.y;
break;
case 'L':
r.x = p.x;
r.y = (p.y + 1) % BOARD_LENGTH;
break;
case 'R':
r.x = p.x;
r.y = (p.y + BOARD_LENGTH - 1) % BOARD_LENGTH;
break;
}
return r;
}
void Snake::next_move() {
for (int i = snake_size; i > 0; i--) {
pos[i] = pos[i - 1];
}
pos[0] = get_next_move(pos[0]);
}
void Snake::eat(pair p) { pos[snake_size++] = p; }
const int row[8] = {2, 7, 19, 5, 13, 18, 12, 16};
// 2-dimensional array of column pin numbers:
const int col[8] = {6, 11, 10, 3, 17, 4, 8, 9};
// 2-dimensional array of pixels:
int pixels[8][8];
// cursor position:
int x = 5;
int y = 5;
Snake snake;
void setup() {
// initialize the I/O pins as outputs
// iterate over the pins:
for (int thisPin = 0; thisPin < 8; thisPin++) {
// initialize the output pins:
pinMode(col[thisPin], OUTPUT);
pinMode(row[thisPin], OUTPUT);
// take the col pins (i.e. the cathodes) high to ensure that
// the LEDS are off:
digitalWrite(col[thisPin], HIGH);
}
// initialize the pixel matrix:
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
pixels[x][y] = HIGH;
}
}
}
void loop() {
// read input:
// readSensors();
snake.snake_to_matrix(pixels);
snake.next_move();
// draw the screen:
for(int i = 0; i < 100; i++)
Display();
}
void readSensors() {
// turn off the last position:
pixels[x][y] = HIGH;
// read the sensors for X and Y values:
x = 7 - map(analogRead(A0), 0, 1022, 0, 7);
y = map(analogRead(A1), 0, 1022, 0, 7);
// set the new pixel position low so that the LED will turn on
// in the next screen refresh:
pixels[x][y] = LOW;
}
void Display()
{
for(int c = 0; c<8;c++)
{
digitalWrite(col[c],LOW);//use thr column
//loop
for(int r = 0;r<8;r++)
{
digitalWrite(row[r],(pixels[r][c]+1)%2);
}
delay(1);
Clear(); //Remove empty display light
}
}
void Clear() //清空显示
{
for(int i = 0;i<8;i++)
{
digitalWrite(row[i],LOW);
digitalWrite(col[i],HIGH);
}
}

433
snake.ino
View File

@ -2,117 +2,128 @@
#define SNAKE_MAX_SIZE 32 #define SNAKE_MAX_SIZE 32
struct pair { struct pair {
int x; int x;
int y; int y;
}; };
class Snake { class Snake {
private: private:
char state; char state;
int snake_size; int snake_size;
pair pos[64]; pair pos[64];
pair get_next_move(pair p); pair get_next_move(pair p);
pair fruitPos; pair fruit_pos;
bool fruit; bool fruit;
public: public:
Snake() { Snake() {
this->state = 'U'; this->state = 'R';
this->snake_size = 4; this->snake_size = 4;
fruit = false; fruit = false;
for (int i = snake_size - 1; i >= 0; i--) { for (int i = 0; i < snake_size ; ++i) {
pair p; pair p;
p.x = 5; p.x = 7;
p.y = i; p.y = i;
this->pos[i] = p; this->pos[0] = p;
} }
} }
void change_state(char state) { void change_state(char state) {
if (state != '\0'){ if (state != 'I') {
if((state == 'L' || state == 'R') && (this->state == 'U' || this->state=='D')) // if currently moving up or down and state change is left or right update // if currently moving up or down and state change is
this->state = state; // left or right, then update
else if((state == 'U' || state == 'D') && (this->state == 'L' || this->state=='R')) // the opposite if ((state == 'R' || state == 'L') &&
this->state = state; (this->state == 'U' || this->state == 'D')) {
} this->state = state;
//else ignore }
} else if ((state == 'U' || state == 'D') &&
void grow(); (this->state == 'R' || this->state == 'L')) {
void snake_to_matrix(int (*pixels)[BOARD_LENGTH]){ this->state = state;
for(int i = 0; i < BOARD_LENGTH; i++){ }
for(int j = 0; j < BOARD_LENGTH; j++){ }
pixels[i][j] = HIGH; // CLEAR ALL PIXELS; //else ignore
} }
} void snake_to_matrix(int (*pixels)[BOARD_LENGTH]) {
for(int i = 0; i < snake_size; i++) { for (int i = 0; i < BOARD_LENGTH; ++i) {
pair p = pos[i]; for (int j = 0; j < BOARD_LENGTH; ++j) {
pixels[p.x][p.y] = LOW; // TURN ON PIXELS OF SNAKE pixels[i][j] = LOW; // CLEAR ALL PIXELS;
} }
if(fruit) }
pixels[fruitPos.x][fruitPos.y] = LOW; for (int i = 0; i < snake_size; ++i) {
} pair p = pos[i];
pair snake_head() { pixels[p.x][p.y] = HIGH; // TURN ON PIXELS OF SNAKE
return pos[0]; }
} if (fruit) {
void generate_fruit() { pixels[fruit_pos.x][fruit_pos.y] = HIGH;
if(!fruit) { }
fruit = true; }
fruitPos.x = random(7); pair snake_head() {
fruitPos.y = random(7); return pos[0];
} }
} void generate_fruit() {
void next_move() { if (!fruit) {
for (int i = snake_size; i > 0; i--) { fruit = true;
pos[i] = pos[i - 1]; // random inclusive (starts at 0)
} fruit_pos.x = random(7);
pos[0] = get_next_move(pos[0]); fruit_pos.y = random(7);
if (fruit) { }
if (pos[0].x == fruitPos.x && pos[0].y == fruitPos.y) { }
grow(); void grow();
fruit = false; void next_move() {
} for (int i = snake_size; i > 0; --i) {
} pos[i] = pos[i - 1];
} }
bool eats_itself() { pos[0] = get_next_move(pos[0]);
for(int i = 1; i < snake_size; i++) if (fruit) {
if( pos[0].x == pos[i].x && pos[0].y == pos[i].y ) return true; if (pos[0].x == fruit_pos.x && pos[0].y == fruit_pos.y) {
return false; grow();
} fruit = false;
}
}
}
bool eats_itself() {
for (int i = 1; i < snake_size; ++i) {
if (pos[0].x == pos[i].x && pos[0].y == pos[i].y) {
return true;
}
}
return false;
}
}; };
pair Snake::get_next_move(pair p) { pair Snake::get_next_move(pair p)
pair r(p); {
switch (state) { pair r(p);
case 'U': switch (state) {
r.x = (p.x + BOARD_LENGTH - 1) % BOARD_LENGTH; case 'U':
r.y = p.y; r.x = (p.x + BOARD_LENGTH - 1) % BOARD_LENGTH;
break; r.y = p.y;
case 'D': break;
r.x = (p.x + 1) % BOARD_LENGTH; case 'D':
r.y = p.y; r.x = (p.x + 1) % BOARD_LENGTH;
break; r.y = p.y;
case 'L': break;
r.x = p.x; case 'R':
r.y = (p.y + 1) % BOARD_LENGTH; r.x = p.x;
break; r.y = (p.y + 1) % BOARD_LENGTH;
case 'R': break;
r.x = p.x; case 'L':
r.y = (p.y + BOARD_LENGTH - 1) % BOARD_LENGTH; r.x = p.x;
break; r.y = (p.y + BOARD_LENGTH - 1) % BOARD_LENGTH;
} break;
return r; }
return r;
} }
void Snake::grow() { void Snake::grow()
if (snake_size < SNAKE_MAX_SIZE) { {
pos[snake_size] = pos[snake_size - 1]; if (snake_size < SNAKE_MAX_SIZE) {
++snake_size; pos[snake_size] = pos[snake_size - 1];
} ++snake_size;
}
} }
const int row[8] = {2, 7, 19, 5, 13, 18, 12, 16}; const int row[8] = { 2, 7, 19, 5, 13, 18, 12, 16 };
const int col[8] = { 6, 11, 10, 3, 17, 4, 8, 9 };
// 2-dimensional array of column pin numbers:
const int col[8] = {6, 11, 10, 3, 17, 4, 8, 9};
// 2-dimensional array of pixels: // 2-dimensional array of pixels:
int pixels[8][8]; int pixels[8][8];
@ -122,109 +133,133 @@ int x = 5;
int y = 5; int y = 5;
Snake snake; Snake snake;
void setup() {
Serial.begin(9600); // 9600 bps
// initialize the I/O pins as outputs
// iterate over the pins:
for (int thisPin = 0; thisPin < 8; thisPin++) {
// initialize the output pins:
pinMode(col[thisPin], OUTPUT);
pinMode(row[thisPin], OUTPUT);
// take the col pins (i.e. the cathodes) high to ensure that
// the LEDS are off:
digitalWrite(col[thisPin], HIGH);
}
// initialize the pixel matrix: // A BIG SAD CROSS
for (int x = 0; x < 8; x++) { int dead[8][8] = {
for (int y = 0; y < 8; y++) { {HIGH, LOW, LOW, LOW, LOW, LOW, LOW, HIGH},
pixels[x][y] = HIGH; {LOW, HIGH, LOW, LOW, LOW, LOW, HIGH, LOW},
} {LOW, LOW, HIGH, LOW, LOW, HIGH, LOW, LOW},
} {LOW, LOW, LOW, HIGH, HIGH, LOW, LOW, LOW},
randomSeed(analogRead(0)); {LOW, LOW, LOW, HIGH, HIGH, LOW, LOW, LOW},
{LOW, LOW, HIGH, LOW, LOW, HIGH, LOW, LOW},
{LOW, HIGH, LOW, LOW, LOW, LOW, HIGH, LOW},
{HIGH, LOW, LOW, LOW, LOW, LOW, LOW, HIGH},
};
/**
* The setup routine runs once when you press reset.
*/
void setup()
{
Serial.begin(9600); // 9600 bps
// initialize the I/O pins as outputs
// iterate over the pins:
for (int this_pin = 0; this_pin < 8; ++this_pin) {
// initialize the output pins:
pinMode(col[this_pin], OUTPUT);
pinMode(row[this_pin], OUTPUT);
// take the col pins (i.e. the cathodes) high to ensure that
// the LEDS are off:
digitalWrite(col[this_pin], HIGH);
}
// initialize the pixel matrix:
for (int x = 0; x < 8; ++x) {
for (int y = 0; y < 8; ++y) {
pixels[x][y] = HIGH;
}
}
randomSeed(analogRead(0));
} }
void loop() { /**
if(random(20) == 0) snake.generate_fruit(); * The loop routine runs over and over again forever.
snake.snake_to_matrix(pixels); */
snake.next_move(); void loop()
// draw the screen: {
if(snake.eats_itself()){ snake.generate_fruit();
for(int i = 0; i < 3; i++){ snake.next_move();
for(int j = 0; j < 100; j++) snake.snake_to_matrix(pixels);
Display(); for (int i = 0; i < 30; ++i) {
delay(500); display_pixels();
} snake.change_state(read_sensors());
int dead[8][8] = { }
{0,1,1,1,1,1,1,0}, // draw the screen:
{1,0,1,1,1,1,0,1}, if (snake.eats_itself()) {
{1,1,0,1,1,0,1,1}, for (int i = 0; i < 3; i++) {
{1,1,1,0,0,1,1,1}, for (int j = 0; j < 100; ++j) {
{1,1,1,0,0,1,1,1}, display_pixels();
{1,1,0,1,1,0,1,1}, }
{1,0,1,1,1,1,0,1}, delay(500);
{0,1,1,1,1,1,1,0}, }
}; for (int i = 0; i < 8; ++i) {
for(int i = 0; i < 8; i++) for (int j = 0; j < 8; ++j) {
for(int j = 0; j < 8; j++) pixels[i][j] = dead[i][j];
pixels[i][j] = dead[i][j]; }
while(true) Display(); }
} while (true) {
for(int i = 0; i < 30; i++) { display_pixels();
Display(); }
snake.change_state(read_sensors()); }
}
} }
void readSensors() { /**
// turn off the last position: * Prints the pixels array in the matrix
pixels[x][y] = HIGH; */
// read the sensors for X and Y values: void display_pixels()
x = 7 - map(analogRead(A0), 0, 1022, 0, 7); {
y = map(analogRead(A1), 0, 1022, 0, 7); for (int c = 0; c < 8; ++c) {
// set the new pixel position low so that the LED will turn on digitalWrite(col[c], LOW);
// in the next screen refresh: for (int r = 0; r < 8; ++r) {
pixels[x][y] = LOW; digitalWrite(row[r], pixels[r][c]);
}
delay(1);
display_clear();
}
} }
void Display() /**
{ * Remove empty display light
for(int c = 0; c<8;c++) *
{ */
digitalWrite(col[c],LOW);//use thr column void display_clear()
//loop {
for(int r = 0;r<8;r++) for (int i = 0; i < 8; ++i) {
{ digitalWrite(row[i], LOW);
digitalWrite(row[r],(pixels[r][c]+1)%2); digitalWrite(col[i], HIGH);
} }
delay(1); }
Clear(); //Remove empty display light
} /**
} * Returns the current joystick input with some leeway
* I means Iddle
void Clear() //清空显示 * L means Left
{ * R means Right
for(int i = 0;i<8;i++) * U means Up
{ * D means Down
digitalWrite(row[i],LOW); */
digitalWrite(col[i],HIGH); char read_sensors()
} {
} //int clicked = digitalRead(z); // if 0, then clicked
//if(!clicked) return 'C';
char read_sensors() { x = map(analogRead(A0), 0, 1023, 0, 10) - 5;
//int clicked = digitalRead(z); // if 0, then clicked y = map(analogRead(A1), 0, 1023, 0, 10) - 5;
//if(!clicked) return 'C'; // test if joystick is the middle with some leeway
x = map(analogRead(A0),0,1023,0,10) - 5; if (abs(x) <= 3 && abs(y) <= 3) {
y = map(analogRead(A1),0,1023,0,10) - 5; return 'I';
if(abs(x) <= 1 && abs(y) <= 1) { // test if joystick is the middle with some leeway // test if move in x axis is > than in y axis
return '\0'; } else if (abs(x) > abs(y)) {
}else if(abs(x) > abs(y) ) { // test if move in x axis is > than in y axis if (x > 1) {
if(x > 1) return 'L'; return 'R';
else return 'R'; } else {
} else { return 'L';
if(y > 1) return 'U'; }
else return 'D'; } else {
} if (y > 1) {
return '\0'; return 'U';
} else {
return 'D';
}
}
return 'I';
} }