controllable snake
This commit is contained in:
parent
5c2380a564
commit
fc71a279d5
350
snake.ino
350
snake.ino
@ -1,32 +1,102 @@
|
|||||||
const int row[8] = {
|
#define BOARD_LENGTH 8
|
||||||
2, 7, 19, 5, 13, 18, 12, 16
|
|
||||||
|
struct pair {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 2-dimensional array of column pin numbers:
|
class Snake {
|
||||||
const int col[8] = {
|
private:
|
||||||
6, 11, 10, 3, 17, 4, 8, 9
|
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 state) {
|
||||||
|
if (state != '\0'){
|
||||||
|
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
|
||||||
|
this->state = state;
|
||||||
|
else if((state == 'U' || state == 'D') && (this->state == 'L' || this->state=='R')) // the opposite
|
||||||
|
this->state = state;
|
||||||
|
}
|
||||||
|
//else ignore
|
||||||
|
}
|
||||||
|
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(p);
|
||||||
|
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:
|
// 2-dimensional array of pixels:
|
||||||
int pixels[8][8];
|
int pixels[8][8];
|
||||||
|
|
||||||
// cursor position:
|
// cursor position:
|
||||||
int x = 4;
|
int x = 5;
|
||||||
int y = 4;
|
int y = 5;
|
||||||
int z = 0;
|
Snake snake;
|
||||||
|
|
||||||
// up: 1
|
|
||||||
// right: 2
|
|
||||||
// down: 3
|
|
||||||
// left: 4
|
|
||||||
int cur_dir = 0;
|
|
||||||
int snake_x = 4,
|
|
||||||
snake_y = 4;
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
//Serial.begin(9600); // 9600 bps
|
Serial.begin(9600); // 9600 bps
|
||||||
// Enable the Z pin
|
|
||||||
pinMode(z, INPUT_PULLUP);
|
|
||||||
// initialize the I/O pins as outputs
|
// initialize the I/O pins as outputs
|
||||||
// iterate over the pins:
|
// iterate over the pins:
|
||||||
for (int thisPin = 0; thisPin < 8; thisPin++) {
|
for (int thisPin = 0; thisPin < 8; thisPin++) {
|
||||||
@ -44,209 +114,65 @@ void setup() {
|
|||||||
pixels[x][y] = HIGH;
|
pixels[x][y] = HIGH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*pixels[2][3] = LOW;
|
|
||||||
pixels[3][2] = LOW;
|
|
||||||
pixels[4][2] = LOW;
|
|
||||||
pixels[4][3] = LOW;
|
|
||||||
pixels[4][4] = LOW;*/
|
|
||||||
pixels[snake_x][snake_y] = LOW;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
for (int i = 0; i < 420; ++i) {
|
snake.change_state(read_sensors());
|
||||||
refresh_screen();
|
snake.snake_to_matrix(pixels);
|
||||||
}
|
snake.next_move();
|
||||||
delay(42);
|
|
||||||
if (!move_snake(read_sensors())) {
|
|
||||||
switch(cur_dir)
|
|
||||||
{
|
|
||||||
case 0: // iddle
|
|
||||||
// Just don't
|
|
||||||
break;
|
|
||||||
case 1: // up
|
|
||||||
// Move
|
|
||||||
if (snake_y+1 <= 7) {
|
|
||||||
pixels[snake_x][++snake_y] = LOW;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2: // right
|
|
||||||
// Move
|
|
||||||
if (snake_x+1 <= 7) {
|
|
||||||
pixels[++snake_x][snake_y] = LOW;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3: // down
|
|
||||||
// Move
|
|
||||||
if (snake_y-1 >= 0) {
|
|
||||||
pixels[snake_x][--snake_y] = LOW;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4: // left
|
|
||||||
// Move
|
|
||||||
if (snake_x-1 >= 0) {
|
|
||||||
pixels[--snake_x][snake_y] = LOW;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the screen:
|
// draw the screen:
|
||||||
refresh_screen();
|
for(int i = 0; i < 100; i++)
|
||||||
|
Display();
|
||||||
}
|
}
|
||||||
|
|
||||||
// true if it has moved, false otherwise
|
void readSensors() {
|
||||||
bool move_snake(int dir) {
|
// turn off the last position:
|
||||||
// read input:
|
pixels[x][y] = HIGH;
|
||||||
switch(dir)
|
// read the sensors for X and Y values:
|
||||||
{
|
x = 7 - map(analogRead(A0), 0, 1022, 0, 7);
|
||||||
case 0: // iddle
|
y = map(analogRead(A1), 0, 1022, 0, 7);
|
||||||
// Just don't
|
|
||||||
break;
|
|
||||||
case 1: // up
|
|
||||||
// Move
|
|
||||||
if (cur_dir != 3) {
|
|
||||||
pixels[snake_x][++snake_y] = LOW;
|
|
||||||
cur_dir = 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2: // right
|
|
||||||
// Move
|
|
||||||
if (cur_dir != 4) {
|
|
||||||
pixels[++snake_x][snake_y] = LOW;
|
|
||||||
cur_dir = 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3: // down
|
|
||||||
// Move
|
|
||||||
if (cur_dir != 1) {
|
|
||||||
pixels[snake_x][--snake_y] = LOW;
|
|
||||||
cur_dir = 3;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4: // left
|
|
||||||
// Move
|
|
||||||
if (cur_dir != 2) {
|
|
||||||
pixels[--snake_x][snake_y] = LOW;
|
|
||||||
cur_dir = 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// iddle: 0
|
|
||||||
// up: 1
|
|
||||||
// right: 2
|
|
||||||
// down: 3
|
|
||||||
// left: 4
|
|
||||||
int read_sensors() {
|
|
||||||
int clicked = digitalRead(z); // if 0, then clicked
|
|
||||||
x = 7 - map(analogRead(A0), 0, 1021, 0, 7);
|
|
||||||
Serial.print("Just read x=: ");
|
|
||||||
Serial.print(x);
|
|
||||||
Serial.print("\n");
|
|
||||||
y = map(analogRead(A1), 0, 1021, 0, 7)+1;
|
|
||||||
Serial.print("Just read y=: ");
|
|
||||||
Serial.print(y);
|
|
||||||
Serial.print("\n");
|
|
||||||
|
|
||||||
if (x == 4 && y == 4) {
|
|
||||||
Serial.print("We're iddle\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (abs(4-x) > abs(4-y)) // X
|
|
||||||
{
|
|
||||||
Serial.print("Let's consider x\n");
|
|
||||||
if (x < 4) {
|
|
||||||
Serial.print("Move right\n");
|
|
||||||
return 2;
|
|
||||||
} else {
|
|
||||||
Serial.print("Move left\n");
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Serial.print("Let's consider y\n");
|
|
||||||
if (y > 4) {
|
|
||||||
Serial.print("Move up\n");
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
Serial.print("Move down\n");
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the new pixel position low so that the LED will turn on
|
// set the new pixel position low so that the LED will turn on
|
||||||
// in the next screen refresh:
|
// in the next screen refresh:
|
||||||
}
|
|
||||||
|
|
||||||
/*bool to_right() {
|
|
||||||
// read the sensors for X
|
|
||||||
x = 7 - map(analogRead(A0), 0, 1021, 0, 7);
|
|
||||||
Serial.print("rX is: ");
|
|
||||||
Serial.print(x);
|
|
||||||
Serial.print("\n");
|
|
||||||
if ((x > 4 && cur_dir != 4) || // user inputs right and it isn't currently going left
|
|
||||||
(cur_dir == 2 && (x == 4 && y == 4)) // user has no input and cur_dir is set
|
|
||||||
) {
|
|
||||||
cur_dir = 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool to_left() {
|
|
||||||
// read the sensors for X
|
|
||||||
x = 7 - map(analogRead(A0), 0, 1021, 0, 7);
|
|
||||||
Serial.print("lX is: ");
|
|
||||||
Serial.print(x);
|
|
||||||
Serial.print("\n");
|
|
||||||
if ((x < 4 && cur_dir != 2) || // user inputs right and it isn't currently going left
|
|
||||||
(cur_dir == 4 && (x == 4 && y == 4)) // user has no input and cur_left is set
|
|
||||||
) {
|
|
||||||
cur_dir = 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void blink(int x, int y)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void write_new_screen(int delay_write, int x, int y) {
|
|
||||||
for (int i = 0; i < 20; ++i) {
|
|
||||||
refresh_screen();
|
|
||||||
}
|
|
||||||
pixels[x][y] = LOW;
|
pixels[x][y] = LOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
void refresh_screen() {
|
void Display()
|
||||||
// iterate over the rows (anodes):
|
{
|
||||||
for (int thisRow = 0; thisRow < 8; thisRow++) {
|
for(int c = 0; c<8;c++)
|
||||||
// take the row pin (anode) high:
|
{
|
||||||
digitalWrite(row[thisRow], HIGH);
|
digitalWrite(col[c],LOW);//use thr column
|
||||||
// iterate over the cols (cathodes):
|
//loop
|
||||||
for (int thisCol = 0; thisCol < 8; thisCol++) {
|
for(int r = 0;r<8;r++)
|
||||||
// get the state of the current pixel;
|
{
|
||||||
int thisPixel = pixels[thisRow][thisCol];
|
digitalWrite(row[r],(pixels[r][c]+1)%2);
|
||||||
// when the row is HIGH and the col is LOW,
|
}
|
||||||
// the LED where they meet turns on:
|
delay(1);
|
||||||
digitalWrite(col[thisCol], thisPixel);
|
Clear(); //Remove empty display light
|
||||||
// turn the pixel off:
|
}
|
||||||
if (thisPixel == LOW) {
|
}
|
||||||
digitalWrite(col[thisCol], HIGH);
|
|
||||||
}
|
void Clear() //清空显示
|
||||||
}
|
{
|
||||||
// take the row pin low to turn off the whole row:
|
for(int i = 0;i<8;i++)
|
||||||
digitalWrite(row[thisRow], LOW);
|
{
|
||||||
|
digitalWrite(row[i],LOW);
|
||||||
|
digitalWrite(col[i],HIGH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char read_sensors() {
|
||||||
|
//int clicked = digitalRead(z); // if 0, then clicked
|
||||||
|
//if(!clicked) return 'C';
|
||||||
|
x = map(analogRead(A0),0,1023,0,10) - 5;
|
||||||
|
y = map(analogRead(A1),0,1023,0,10) - 5;
|
||||||
|
if(abs(x) <= 1 && abs(y) <= 1) { // test if joystick is the middle with some leeway
|
||||||
|
return '\0';
|
||||||
|
}else if(abs(x) > abs(y) ) { // test if move in x axis is > than in y axis
|
||||||
|
if(x > 1) return 'L';
|
||||||
|
else return 'R';
|
||||||
|
} else {
|
||||||
|
if(y > 1) return 'U';
|
||||||
|
else return 'D';
|
||||||
}
|
}
|
||||||
|
return '\0';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user