//Snake source: https://www.youtube.com/watch?v=IkTK6WMlMs4 & http://pastebin.com/yiDBzjvZ #include <LiquidCrystal.h> #include <Time.h> // LCD variables LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7); int adc_key_val[5] = {50, 200, 400, 600, 800 }; int NUM_KEYS = 5; int adc_key_in; int key = -1; int oldkey = -1; int pressedKey = -1; // project variables int pinIn = 3; int pinOut = 2; int reading; int previous = LOW; long lastTime; long checkTime = 100; bool snakeMode = false; bool clockMode = false; // clock variables bool settingClock, settingTime, settingDate; bool settingHour, settingMinute; bool settingDay, settingMonth, settingYear; int h, m, s, d, n, y, dMax; //snake variables unsigned long time, timeNow; int gameSpeed; boolean skip, gameOver, gameStarted; int olddir; int selectedLevel, levels; boolean x[16][80]; byte myChar[8]; byte nullChar[8] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; boolean special; struct partdef { int row, column, dir; //0 - up, 1 - down, 2 - right, 3 - left struct partdef *next; }; typedef partdef part; part *head, *tail; int i, j, collected; long pc, pr; void startF() { gameOver = false; gameStarted = false; selectedLevel = 1; lcd.clear(); lcd.setCursor(0, 0); lcd.print("Select to Start"); collected = 0; gameSpeed = 8; createSnake(3); time = 0; } void setup() { pinMode(pinIn, INPUT_PULLUP); pinMode(pinOut, OUTPUT); Serial.begin(9600); lcd.begin(16, 2); setTime(12, 00, 00, 01, 01, 2016); levels = 5; //number of lvls checkMode(); } void loop() { while (snakeMode) { if (!gameOver && !gameStarted) { adc_key_in = analogRead(0); // read the value from the sensor key = get_key(adc_key_in); // convert into key press if (key != oldkey) // if keypress is detected { delay(50); // wait for debounce time adc_key_in = analogRead(0); // read the value from the sensor key = get_key(adc_key_in); // convert into key press if (key != oldkey) { oldkey = key; if (key >= 0) { olddir = head->dir; if (key == 1 && selectedLevel < levels) selectedLevel++; if (key == 2 && selectedLevel > 1) selectedLevel--; if (key == 4) { lcd.clear(); selectedLevel--; newPoint(); gameStarted = true; } else { lcd.setCursor(14, 0); lcd.print(selectedLevel); } } } } } if (!gameOver && gameStarted) { skip = false; //skip the second moveAll() function call if the first was made adc_key_in = analogRead(0); // read the value from the sensor key = get_key(adc_key_in); // convert into key press if (key != oldkey) // if keypress is detected { delay(50); // wait for debounce time adc_key_in = analogRead(0); // read the value from the sensor key = get_key(adc_key_in); // convert into key press if (key != oldkey) { oldkey = key; if (key >= 0) { olddir = head->dir; if (key == 0 && head->dir != 3) head->dir = 2; if (key == 1 && head->dir != 1) head->dir = 0; if (key == 2 && head->dir != 0) head->dir = 1; if (key == 3 && head->dir != 2) head->dir = 3; if (olddir != head->dir) { skip = true; delay(1000 / gameSpeed); moveAll(); drawMatrix(); } } } } if (!skip) { timeNow = millis(); if (timeNow - time > 1000 / gameSpeed) { moveAll(); drawMatrix(); time = millis(); } } } if (gameOver) { adc_key_in = analogRead(0); // read the value from the sensor key = get_key(adc_key_in); // convert into key press if (key != oldkey) // if keypress is detected { delay(50); // wait for debounce time adc_key_in = analogRead(0); // read the value from the sensor key = get_key(adc_key_in); // convert into key press if (key != oldkey) { oldkey = key; if (key >= 0) { startF(); } } } } checkMode(); } while (clockMode) { if (settingTime) setTime(); else if (settingDate) setDate(); else printTimeDate(); readingInput(); lcd.noBlink(); checkMode(); } } void checkMode() { lcd.clear(); reading = digitalRead(pinIn); Serial.println(reading); if (reading == 1) { snakeMode = true; clockMode = false; startF(); } else if (reading == 0) { snakeMode = false; clockMode = true; } } bool isKeyPressed() { if (clockMode) { adc_key_in = analogRead(0); // read the value from the sensor key = get_key(adc_key_in); // convert into key press if (key != oldkey) // if keypress is detected { delay(50); // wait for debounce time adc_key_in = analogRead(0); // read the value from the sensor key = get_key(adc_key_in); // convert into key press if (key != oldkey) { oldkey = key; return true; } } delay(100); return false; } } void printTimeDate() { lcd.setCursor(4, 0); if (hour() < 10) lcd.print(0); lcd.print(hour()); lcd.print(":"); if (minute() < 10) lcd.print(0); lcd.print(minute()); lcd.print(":"); if (second() < 10) lcd.print(0); lcd.print(second()); lcd.setCursor(1, 1); lcd.print(dayShortStr(weekday())); lcd.setCursor(5, 1); if (day() < 10) lcd.print(0); lcd.print(day()); lcd.print("/"); if (month() < 10) lcd.print(0); lcd.print(month()); lcd.print("/"); lcd.print(year()); } void setTime() { lcd.clear(); lcd.setCursor(4, 0); lcd.print("Set time:"); lcd.setCursor(4, 1); if (h < 10) lcd.print(0); lcd.print(h); lcd.print(":"); if (m < 10) lcd.print(0); lcd.print(m); lcd.print(":00"); if (settingHour) lcd.setCursor(5, 1); else if (settingMinute) lcd.setCursor(8, 1); lcd.blink(); } void setDate() { lcd.clear(); lcd.setCursor(4, 0); lcd.print("Set date:"); lcd.setCursor(3, 1); if (d < 10) lcd.print(0); lcd.print(d); lcd.print("/"); if (n < 10) lcd.print(0); lcd.print(n); lcd.print("/"); lcd.print(y); if (settingDay) lcd.setCursor(4, 1); else if (settingMonth) lcd.setCursor(7, 1); else if (settingYear) lcd.setCursor(12, 1); lcd.blink(); } void readingInput() { if (isKeyPressed()) { if (key == 0) // right key { if (settingTime) { if (settingHour) { settingMinute = true; settingHour = false; } else if (settingMinute) { settingHour = true; settingMinute = false; } } else if (settingDate) { if (settingDay) { settingMonth = true; settingDay = false; } else if (settingMonth) { settingYear = true; settingMonth = false; } else if (settingYear) { settingDay = true; settingYear = false; } } } if (key == 1) // up key { if (settingTime) { if (settingHour) { h++; if (h > 23) h = 0; } else if (settingMinute) { m++; if (m > 59) m = 0; } } else if (settingDate) { if (settingDay) { d++; if (d > dMax) d = 1; } else if (settingMonth) { n++; if (n > 12) n = 1; updateMaxDay(); } else if (settingYear) { y++; updateMaxDay(); } } } if (key == 2) // down key { if (settingTime) { if (settingHour) { h--; if (h < 0) h = 23; } else if (settingMinute) { m--; if (m < 0) m = 59; } } else if (settingDate) { if (settingDay) { d--; if (d < 1) d = dMax; } else if (settingMonth) { n--; if (n < 1) n = 12; updateMaxDay(); } else if (settingYear) { y--; updateMaxDay(); } } } if (key == 3) // left key { if (settingTime) { if (settingHour) { settingMinute = true; settingHour = false; } else if (settingMinute) { settingHour = true; settingMinute = false; } } else if (settingDate) { if (settingDay) { settingYear = true; settingDay = false; } else if (settingYear) { settingMonth = true; settingYear = false; } else if (settingMonth) { settingDay = true; settingMonth = false; } } } if (key == 4) // select key { updateMaxDay(); lcd.clear(); if (!settingClock) { settingTime = true; settingClock = true; settingHour = true; h = hour(); m = minute(); s = 0; d = day(); n = month(); y = year(); } else if (settingTime) { settingHour = false; settingDay = true; settingTime = false; settingDate = true; } else if (settingDate) { settingDay = false; settingDate = false; settingClock = false; setTime(h, m, s, d, n, y); } } key = -1; } } void updateMaxDay() { if (n == 2) { if (y % 4 == 0) dMax = 29; else dMax = 28; } else if (n == 4 || n == 6 || n == 9 || n == 11) dMax = 30; else dMax = 31; } // Convert ADC value to key number int get_key(unsigned int input) { int k; for (k = 0; k < NUM_KEYS; k++) { if (input < adc_key_val[k]) { return k; } } if (k >= NUM_KEYS)k = -1; // No valid key pressed return k; } void drawMatrix() { int cc = 0; if (!gameOver) { x[pr][pc] = true; for (int r = 0; r < 2; r++) { for (int c = 0; c < 16; c++) { special = false; for (int i = 0; i < 8; i++) { byte b = B00000; if (x[r * 8 + i][c * 5 + 0]) { b += B10000; special = true; } if (x[r * 8 + i][c * 5 + 1]) { b += B01000; special = true; } if (x[r * 8 + i][c * 5 + 2]) { b += B00100; special = true; } if (x[r * 8 + i][c * 5 + 3]) { b += B00010; special = true; } if (x[r * 8 + i][c * 5 + 4]) { b += B00001; special = true; } myChar[i] = b; } if (special) { lcd.createChar(cc, myChar); lcd.setCursor(c, r); lcd.write(byte(cc)); cc++; } else { lcd.setCursor(c, r); lcd.write(254); } } } } } void freeList() { part *p, *q; p = tail; while (p != NULL) { q = p; p = p->next; free(q); } head = tail = NULL; } void gameOverFunction() { delay(1000); lcd.clear(); freeList(); lcd.setCursor(3, 0); lcd.print("Game Over!"); lcd.setCursor(4, 1); lcd.print("Score: "); lcd.print(collected); delay(1000); } void growSnake() { part *p; p = (part*)malloc(sizeof(part)); p->row = tail->row; p->column = tail->column; p->dir = tail->dir; p->next = tail; tail = p; } void newPoint() { part *p; p = tail; boolean newp = true; while (newp) { pr = random(16); pc = random(80); newp = false; while (p->next != NULL && !newp) { if (p->row == pr && p->column == pc) newp = true; p = p->next; } } if (collected < 13 && gameStarted) growSnake(); } void moveHead() { switch (head->dir) // 1 step in direction { case 0: head->row--; break; case 1: head->row++; break; case 2: head->column++; break; case 3: head->column--; break; default : break; } if (head->column >= 80) head->column = 0; if (head->column < 0) head->column = 79; if (head->row >= 16) head->row = 0; if (head->row < 0) head->row = 15; part *p; p = tail; while (p != head && !gameOver) // self collision { if (p->row == head->row && p->column == head->column) gameOver = true; p = p->next; } if (gameOver) gameOverFunction(); else { x[head->row][head->column] = true; if (head->row == pr && head->column == pc) // point pickup check { collected++; if (gameSpeed < 25) gameSpeed += 3; newPoint(); } } } void moveAll() { part *p; p = tail; x[p->row][p->column] = false; while (p->next != NULL) { p->row = p->next->row; p->column = p->next->column; p->dir = p->next->dir; p = p->next; } moveHead(); } void createSnake(int n) // n = size of snake { for (i = 0; i < 16; i++) for (j = 0; j < 80; j++) x[i][j] = false; part *p, *q; tail = (part*)malloc(sizeof(part)); tail->row = 7; tail->column = 39 + n / 2; tail->dir = 3; q = tail; x[tail->row][tail->column] = true; for (i = 0; i < n - 1; i++) // build snake from tail to head { p = (part*)malloc(sizeof(part)); p->row = q->row; p->column = q->column - 1; //initial snake id placed horizoltally x[p->row][p->column] = true; p->dir = q->dir; q->next = p; q = p; } if (n > 1) { p->next = NULL; head = p; } else { tail->next = NULL; head = tail; } }
Code
Leave a reply