Code for simple game of snake with four playing modes.

Dependencies:   N5110 PinDetect PowerControl mbed

Committer:
fiifimills
Date:
Mon May 11 01:51:37 2015 +0000
Revision:
12:fa654504b51f
Parent:
11:f421defe6f55
Final Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fiifimills 0:3bcffeeec36d 1 #include "mbed.h"
fiifimills 0:3bcffeeec36d 2 #include "N5110.h"
fiifimills 0:3bcffeeec36d 3 #include "PinDetect.h"
fiifimills 3:8fa09c9a93f3 4 #include "PowerControl/PowerControl.h"
fiifimills 3:8fa09c9a93f3 5 #include "PowerControl/EthernetPowerControl.h"
fiifimills 0:3bcffeeec36d 6 #include <vector>
fiifimills 0:3bcffeeec36d 7 #include <stdlib.h> /* srand, rand */
fiifimills 0:3bcffeeec36d 8 #include <time.h>
fiifimills 0:3bcffeeec36d 9
fiifimills 0:3bcffeeec36d 10 /* Code for Snake game
fiifimills 0:3bcffeeec36d 11
fiifimills 0:3bcffeeec36d 12 B.F. Mills
fiifimills 0:3bcffeeec36d 13
fiifimills 0:3bcffeeec36d 14 April 12th 2015
fiifimills 0:3bcffeeec36d 15
fiifimills 0:3bcffeeec36d 16 */
fiifimills 0:3bcffeeec36d 17
fiifimills 0:3bcffeeec36d 18 // change this to alter tolerance of joystick direction
fiifimills 0:3bcffeeec36d 19 #define DIRECTION_TOLERANCE 0.05
fiifimills 0:3bcffeeec36d 20
fiifimills 0:3bcffeeec36d 21 // vcc, sce, rst, dc, mosi, sck, backlight
fiifimills 0:3bcffeeec36d 22 N5110 lcd(p7, p8, p9, p10, p11, p13, p26);
fiifimills 0:3bcffeeec36d 23
fiifimills 0:3bcffeeec36d 24 // joystick connections
fiifimills 0:3bcffeeec36d 25 AnalogIn yPot(p15);
fiifimills 0:3bcffeeec36d 26 AnalogIn xPot(p16);
fiifimills 0:3bcffeeec36d 27 DigitalIn button(p17);
fiifimills 0:3bcffeeec36d 28
fiifimills 0:3bcffeeec36d 29 // leds
fiifimills 9:739c0e5cba63 30 BusOut myleds(LED1, LED2, LED3, LED4);
fiifimills 0:3bcffeeec36d 31
fiifimills 0:3bcffeeec36d 32 // buttons
fiifimills 0:3bcffeeec36d 33 PinDetect buttonA(p30);
fiifimills 0:3bcffeeec36d 34 PinDetect buttonB(p29);
fiifimills 0:3bcffeeec36d 35
fiifimills 0:3bcffeeec36d 36 // timer to regularly read the joystick
fiifimills 0:3bcffeeec36d 37 Ticker pollJoystick;
fiifimills 0:3bcffeeec36d 38 // Serial for debug
fiifimills 0:3bcffeeec36d 39 Serial serial(USBTX,USBRX);
fiifimills 0:3bcffeeec36d 40
fiifimills 0:3bcffeeec36d 41 // create enumerated type (0,1,2,3 etc. for direction)
fiifimills 0:3bcffeeec36d 42 // could be extended for diagonals etc.
fiifimills 0:3bcffeeec36d 43 enum DirectionName {
fiifimills 0:3bcffeeec36d 44 UP,
fiifimills 0:3bcffeeec36d 45 DOWN,
fiifimills 0:3bcffeeec36d 46 LEFT,
fiifimills 0:3bcffeeec36d 47 RIGHT,
fiifimills 0:3bcffeeec36d 48 CENTRE,
fiifimills 0:3bcffeeec36d 49 UNKNOWN
fiifimills 0:3bcffeeec36d 50 };
fiifimills 0:3bcffeeec36d 51
fiifimills 12:fa654504b51f 52 DirectionName currentDirection; // enum variable for current direction of snake's movement
fiifimills 9:739c0e5cba63 53 DirectionName previousDirection; // enum variable for previous direction of snake's movement
fiifimills 9:739c0e5cba63 54
fiifimills 9:739c0e5cba63 55 // enumerated type for game menu screen
fiifimills 0:3bcffeeec36d 56 enum GameMenu {
fiifimills 9:739c0e5cba63 57 STARTUP,
fiifimills 9:739c0e5cba63 58 SELECTSPEED,
fiifimills 9:739c0e5cba63 59 GAMEPLAY
fiifimills 0:3bcffeeec36d 60 };
fiifimills 0:3bcffeeec36d 61
fiifimills 9:739c0e5cba63 62 GameMenu currentGameMenu; // create game menu variable
fiifimills 9:739c0e5cba63 63
fiifimills 0:3bcffeeec36d 64 // struct for Joystick
fiifimills 0:3bcffeeec36d 65 typedef struct JoyStick Joystick;
fiifimills 0:3bcffeeec36d 66 struct JoyStick {
fiifimills 0:3bcffeeec36d 67 float x; // current x value
fiifimills 0:3bcffeeec36d 68 float x0; // 'centred' x value
fiifimills 0:3bcffeeec36d 69 float y; // current y value
fiifimills 0:3bcffeeec36d 70 float y0; // 'centred' y value
fiifimills 0:3bcffeeec36d 71 int button; // button state (assume pull-down used, so 1 = pressed, 0 = unpressed)
fiifimills 0:3bcffeeec36d 72 DirectionName direction; // current direction
fiifimills 0:3bcffeeec36d 73 };
fiifimills 0:3bcffeeec36d 74 // create struct variable
fiifimills 0:3bcffeeec36d 75 Joystick joystick;
fiifimills 0:3bcffeeec36d 76
fiifimills 9:739c0e5cba63 77 // struct for a coordinate
fiifimills 9:739c0e5cba63 78 struct coordinate {
fiifimills 9:739c0e5cba63 79 int x; // x coordinate
fiifimills 9:739c0e5cba63 80 int y; // y coordinate
fiifimills 9:739c0e5cba63 81 };
fiifimills 5:6dd0bec55e52 82
fiifimills 9:739c0e5cba63 83 char buffer [14]; // buffer for printing score to screen
fiifimills 9:739c0e5cba63 84
fiifimills 9:739c0e5cba63 85 // flags
fiifimills 0:3bcffeeec36d 86 int printFlag = 0;
fiifimills 12:fa654504b51f 87 int Aflag = 0; // flag for notification of A button interrupt
fiifimills 12:fa654504b51f 88 int Bflag = 0; // flag for notification of B button interrupt
fiifimills 12:fa654504b51f 89 int collisionFlag = 0; // flag for notification of self snake collision
fiifimills 12:fa654504b51f 90 int borderFlag = 0; // flag for hitting border in insane mode
fiifimills 0:3bcffeeec36d 91
fiifimills 9:739c0e5cba63 92 // global variables
fiifimills 12:fa654504b51f 93 int score = 0; // score value
fiifimills 12:fa654504b51f 94 bool gameOver; // boolean variable for game over
fiifimills 12:fa654504b51f 95 int xCentre = 4; // x coordinate for centre of selection circle
fiifimills 12:fa654504b51f 96 int yCentre = 11; // y coordinate for centre of selection circle
fiifimills 12:fa654504b51f 97 float speed; // wait time for moveSnake function
fiifimills 0:3bcffeeec36d 98
fiifimills 0:3bcffeeec36d 99 void pressedA()
fiifimills 0:3bcffeeec36d 100 {
fiifimills 9:739c0e5cba63 101 Aflag = 1; // set flag when A button is pressed
fiifimills 0:3bcffeeec36d 102 }
fiifimills 0:3bcffeeec36d 103
fiifimills 0:3bcffeeec36d 104 void pressedB()
fiifimills 0:3bcffeeec36d 105 {
fiifimills 9:739c0e5cba63 106 Bflag = 1; // set flag when B button is pressed
fiifimills 0:3bcffeeec36d 107 }
fiifimills 0:3bcffeeec36d 108
fiifimills 0:3bcffeeec36d 109 // function prototypes
fiifimills 0:3bcffeeec36d 110 void calibrateJoystick();
fiifimills 0:3bcffeeec36d 111 void updateJoystick();
fiifimills 0:3bcffeeec36d 112 void moveSnake();
fiifimills 5:6dd0bec55e52 113 void speedSelect();
fiifimills 7:df77530b5fb5 114
fiifimills 0:3bcffeeec36d 115 std::vector<coordinate> Snake; // create a vector that stores coordinate structs
fiifimills 0:3bcffeeec36d 116
fiifimills 0:3bcffeeec36d 117 int main()
fiifimills 0:3bcffeeec36d 118 {
fiifimills 0:3bcffeeec36d 119
fiifimills 0:3bcffeeec36d 120 calibrateJoystick(); // get centred values of joystick
fiifimills 9:739c0e5cba63 121 pollJoystick.attach(&updateJoystick,1.0/20.0); // read joystick 20 times per second
fiifimills 0:3bcffeeec36d 122
fiifimills 0:3bcffeeec36d 123 lcd.init(); // initialise display
fiifimills 0:3bcffeeec36d 124 lcd.setBrightness(0.5); // set brightness of backlight
fiifimills 0:3bcffeeec36d 125
fiifimills 6:f3cebcce5c9a 126 PHY_PowerDown(); // power down ethernet
fiifimills 9:739c0e5cba63 127
fiifimills 9:739c0e5cba63 128 // set button modes to pull down
fiifimills 0:3bcffeeec36d 129 buttonA.mode(PullDown);
fiifimills 0:3bcffeeec36d 130 buttonB.mode(PullDown);
fiifimills 9:739c0e5cba63 131
fiifimills 9:739c0e5cba63 132 buttonA.attach_asserted(&pressedA); // call pressedA function when button is pressed
fiifimills 9:739c0e5cba63 133 buttonB.attach_asserted(&pressedB); // call pressedB function when button is presed
fiifimills 9:739c0e5cba63 134
fiifimills 9:739c0e5cba63 135 // set sample frequency for buttons (default = 20ms)
fiifimills 0:3bcffeeec36d 136 buttonA.setSampleFrequency();
fiifimills 0:3bcffeeec36d 137 buttonB.setSampleFrequency();
fiifimills 0:3bcffeeec36d 138
fiifimills 0:3bcffeeec36d 139 currentGameMenu = STARTUP; // initialise game menu to be splash screen
fiifimills 9:739c0e5cba63 140 gameOver = false; // initialise gameOver as false
fiifimills 9:739c0e5cba63 141
fiifimills 0:3bcffeeec36d 142
fiifimills 0:3bcffeeec36d 143 while (1) { // infinite loop
fiifimills 0:3bcffeeec36d 144
fiifimills 0:3bcffeeec36d 145 if (currentGameMenu == STARTUP) { // start up screen
fiifimills 0:3bcffeeec36d 146
fiifimills 0:3bcffeeec36d 147 // splash screen for startup
fiifimills 9:739c0e5cba63 148 lcd.printString("SNAKE",28,1);
fiifimills 5:6dd0bec55e52 149 lcd.printString("PRESS A",21,5);
fiifimills 5:6dd0bec55e52 150
fiifimills 9:739c0e5cba63 151 // draw snake logo
fiifimills 9:739c0e5cba63 152 lcd.drawRect(26,27,5,5,0); // bottom rectangle of snake
fiifimills 9:739c0e5cba63 153 lcd.drawRect(26,22,5,5,0); // the rectangle directly above
fiifimills 9:739c0e5cba63 154 lcd.drawRect(31,22,5,5,0); // the rectangle one to the right
fiifimills 9:739c0e5cba63 155 lcd.drawRect(36,22,5,5,0); // one to the right
fiifimills 9:739c0e5cba63 156 lcd.drawRect(41,22,5,5,0); // one to the right
fiifimills 9:739c0e5cba63 157 lcd.drawRect(51,22,5,5,1); // "food"
fiifimills 3:8fa09c9a93f3 158 lcd.refresh();
fiifimills 11:f421defe6f55 159
fiifimills 12:fa654504b51f 160 Sleep(); // when flag is not set, go to sleep & wait for interrupt
fiifimills 5:6dd0bec55e52 161
fiifimills 9:739c0e5cba63 162 if (Aflag) { // if currentGameMenu is STARTUP and A is pressed,
fiifimills 9:739c0e5cba63 163 Aflag = 0; // reset flag
fiifimills 9:739c0e5cba63 164 lcd.clear(); // clear screen
fiifimills 9:739c0e5cba63 165 currentGameMenu = SELECTSPEED; // segue to select speed menu
fiifimills 6:f3cebcce5c9a 166 }
fiifimills 11:f421defe6f55 167
fiifimills 5:6dd0bec55e52 168 }
fiifimills 5:6dd0bec55e52 169
fiifimills 9:739c0e5cba63 170 if (currentGameMenu == SELECTSPEED) { // select speed menu
fiifimills 5:6dd0bec55e52 171
fiifimills 9:739c0e5cba63 172 // print menu options to screen
fiifimills 5:6dd0bec55e52 173 lcd.printString("SLOW",10,1);
fiifimills 5:6dd0bec55e52 174 lcd.printString("MEDIUM",10,3);
fiifimills 5:6dd0bec55e52 175 lcd.printString("FAST",10,5);
fiifimills 5:6dd0bec55e52 176 lcd.printString("INSANE",46,1);
fiifimills 5:6dd0bec55e52 177
fiifimills 9:739c0e5cba63 178 lcd.drawCircle(xCentre,yCentre,3,1); // draw selection circle (starting on SLOW)
fiifimills 5:6dd0bec55e52 179 lcd.refresh();
fiifimills 7:df77530b5fb5 180 speedSelect();
fiifimills 6:f3cebcce5c9a 181
fiifimills 9:739c0e5cba63 182 if (Aflag) { // if currentGameMenu is SELECTSPEED and A is pressed,
fiifimills 9:739c0e5cba63 183 Aflag = 0; // reset flag
fiifimills 9:739c0e5cba63 184 lcd.clear(); // cleat screen
fiifimills 9:739c0e5cba63 185 currentGameMenu = GAMEPLAY; // segue to gameplay
fiifimills 6:f3cebcce5c9a 186 }
fiifimills 6:f3cebcce5c9a 187
fiifimills 9:739c0e5cba63 188 Sleep(); // when flag is not set, got to sleep & wait for interrupt
fiifimills 6:f3cebcce5c9a 189
fiifimills 0:3bcffeeec36d 190 }
fiifimills 5:6dd0bec55e52 191
fiifimills 9:739c0e5cba63 192 if (currentGameMenu == GAMEPLAY) { // gameplay
fiifimills 0:3bcffeeec36d 193
fiifimills 9:739c0e5cba63 194 if (gameOver == false) { // whilst game is not over
fiifimills 9:739c0e5cba63 195
fiifimills 9:739c0e5cba63 196 if (xCentre + yCentre == 15) { // if the addition of the coordinates of the centre of the selection circle = 15 i.e when selecting SLOW
fiifimills 10:96f2c1dc956f 197 speed = 0.20; // set wait time for moveSnake
fiifimills 8:b52d2f436a35 198 }
fiifimills 8:b52d2f436a35 199 if (xCentre + yCentre == 31) { // medium
fiifimills 10:96f2c1dc956f 200 speed = 0.12;
fiifimills 8:b52d2f436a35 201 }
fiifimills 8:b52d2f436a35 202 if (xCentre + yCentre == 47) { // fast
fiifimills 10:96f2c1dc956f 203 speed = 0.04;
fiifimills 8:b52d2f436a35 204 }
fiifimills 9:739c0e5cba63 205 if (xCentre + yCentre == 53) { // insane
fiifimills 10:96f2c1dc956f 206 speed = 0.02;
fiifimills 9:739c0e5cba63 207
fiifimills 10:96f2c1dc956f 208 for (int y=0; y<23 ; y++) { // set upper border
fiifimills 9:739c0e5cba63 209 lcd.setPixel(43,y);
fiifimills 9:739c0e5cba63 210 lcd.refresh();
fiifimills 9:739c0e5cba63 211 }
fiifimills 9:739c0e5cba63 212
fiifimills 10:96f2c1dc956f 213 for (int y=25; y<47; y++) { // set lower border
fiifimills 9:739c0e5cba63 214 lcd.setPixel(43,y);
fiifimills 9:739c0e5cba63 215 lcd.refresh();
fiifimills 9:739c0e5cba63 216 }
fiifimills 8:b52d2f436a35 217 }
fiifimills 9:739c0e5cba63 218
fiifimills 6:f3cebcce5c9a 219 previousDirection = RIGHT; // initialise first direction to be right
fiifimills 0:3bcffeeec36d 220
fiifimills 6:f3cebcce5c9a 221 // set of initial coordinates
fiifimills 6:f3cebcce5c9a 222 coordinate cord0 = {45, 24};
fiifimills 6:f3cebcce5c9a 223 coordinate cord1 = {46, 24};
fiifimills 6:f3cebcce5c9a 224 coordinate cord2 = {47, 24};
fiifimills 6:f3cebcce5c9a 225 coordinate cord3 = {48, 24};
fiifimills 0:3bcffeeec36d 226
fiifimills 9:739c0e5cba63 227 // add these coordinates to the snake vector
fiifimills 6:f3cebcce5c9a 228 Snake.push_back(cord0);
fiifimills 6:f3cebcce5c9a 229 Snake.push_back(cord1);
fiifimills 6:f3cebcce5c9a 230 Snake.push_back(cord2);
fiifimills 6:f3cebcce5c9a 231 Snake.push_back(cord3);
fiifimills 0:3bcffeeec36d 232
fiifimills 6:f3cebcce5c9a 233 // set these co-ordinate's pixels
fiifimills 6:f3cebcce5c9a 234 for (int i=0; i<Snake.size(); i++) {
fiifimills 6:f3cebcce5c9a 235 lcd.setPixel(Snake.at(i).x, Snake.at(i).y);
fiifimills 6:f3cebcce5c9a 236 lcd.refresh();
fiifimills 0:3bcffeeec36d 237 }
fiifimills 0:3bcffeeec36d 238
fiifimills 6:f3cebcce5c9a 239 moveSnake();
fiifimills 0:3bcffeeec36d 240 }
fiifimills 0:3bcffeeec36d 241
fiifimills 9:739c0e5cba63 242 if (gameOver == true) { // if game is over
fiifimills 6:f3cebcce5c9a 243
fiifimills 9:739c0e5cba63 244 // display game over splash screen
fiifimills 6:f3cebcce5c9a 245 lcd.printString("Game Over!",14,1);
fiifimills 6:f3cebcce5c9a 246 lcd.printString("Press B",23,4);
fiifimills 9:739c0e5cba63 247 int printScore = sprintf(buffer,"Score = %d",score*5); // print formatted data to buffer
fiifimills 9:739c0e5cba63 248 if (printScore <= 14) { // if string fits on display
fiifimills 6:f3cebcce5c9a 249 lcd.printString(buffer,16,3);
fiifimills 9:739c0e5cba63 250 }
fiifimills 9:739c0e5cba63 251 Snake.clear(); // clear snake vector
fiifimills 6:f3cebcce5c9a 252
fiifimills 9:739c0e5cba63 253 while (1) { // flash leds
fiifimills 9:739c0e5cba63 254 myleds = 15;
fiifimills 9:739c0e5cba63 255 wait(0.5);
fiifimills 9:739c0e5cba63 256 myleds = 0;
fiifimills 9:739c0e5cba63 257 wait(0.5);
fiifimills 9:739c0e5cba63 258 if (Bflag) // if B is pressed, break out of infinite loop
fiifimills 9:739c0e5cba63 259 break;
fiifimills 6:f3cebcce5c9a 260 }
fiifimills 6:f3cebcce5c9a 261
fiifimills 9:739c0e5cba63 262 if (Bflag) { // if B is pressed,
fiifimills 9:739c0e5cba63 263 Bflag = 0; // reset flag
fiifimills 9:739c0e5cba63 264 collisionFlag = 0; // reset collision flag
fiifimills 9:739c0e5cba63 265 score = 0; // reset score
fiifimills 9:739c0e5cba63 266 myleds = 0; // switch off leds
fiifimills 9:739c0e5cba63 267 borderFlag = 0;
fiifimills 9:739c0e5cba63 268 gameOver = false; // reset gameOver to false
fiifimills 9:739c0e5cba63 269 lcd.clear(); // clear the screen
fiifimills 9:739c0e5cba63 270 currentGameMenu = STARTUP; // go back to startup screen
fiifimills 9:739c0e5cba63 271 }
fiifimills 9:739c0e5cba63 272
fiifimills 6:f3cebcce5c9a 273 }
fiifimills 0:3bcffeeec36d 274 }
fiifimills 6:f3cebcce5c9a 275
fiifimills 0:3bcffeeec36d 276 }
fiifimills 6:f3cebcce5c9a 277 }
fiifimills 0:3bcffeeec36d 278
fiifimills 0:3bcffeeec36d 279 // read default positions of the joystick to calibrate later readings
fiifimills 6:f3cebcce5c9a 280 void calibrateJoystick()
fiifimills 6:f3cebcce5c9a 281 {
fiifimills 6:f3cebcce5c9a 282 button.mode(PullDown);
fiifimills 6:f3cebcce5c9a 283 // must not move during calibration
fiifimills 6:f3cebcce5c9a 284 joystick.x0 = xPot; // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
fiifimills 6:f3cebcce5c9a 285 joystick.y0 = yPot;
fiifimills 6:f3cebcce5c9a 286 }
fiifimills 6:f3cebcce5c9a 287
fiifimills 6:f3cebcce5c9a 288 void updateJoystick()
fiifimills 6:f3cebcce5c9a 289 {
fiifimills 6:f3cebcce5c9a 290 // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
fiifimills 6:f3cebcce5c9a 291 joystick.x = xPot - joystick.x0;
fiifimills 6:f3cebcce5c9a 292 joystick.y = yPot - joystick.y0;
fiifimills 6:f3cebcce5c9a 293 // read button state
fiifimills 6:f3cebcce5c9a 294 joystick.button = button;
fiifimills 6:f3cebcce5c9a 295
fiifimills 6:f3cebcce5c9a 296 // calculate direction depending on x,y values
fiifimills 6:f3cebcce5c9a 297 // tolerance allows a little lee-way in case joystick not exactly in the stated direction
fiifimills 6:f3cebcce5c9a 298 if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
fiifimills 6:f3cebcce5c9a 299 joystick.direction = CENTRE;
fiifimills 6:f3cebcce5c9a 300 } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
fiifimills 6:f3cebcce5c9a 301 joystick.direction = RIGHT;
fiifimills 6:f3cebcce5c9a 302 } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
fiifimills 6:f3cebcce5c9a 303 joystick.direction = LEFT;
fiifimills 6:f3cebcce5c9a 304 } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
fiifimills 6:f3cebcce5c9a 305 joystick.direction = DOWN;
fiifimills 6:f3cebcce5c9a 306 } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
fiifimills 6:f3cebcce5c9a 307 joystick.direction = UP;
fiifimills 6:f3cebcce5c9a 308 } else {
fiifimills 6:f3cebcce5c9a 309 joystick.direction = UNKNOWN;
fiifimills 0:3bcffeeec36d 310 }
fiifimills 0:3bcffeeec36d 311
fiifimills 6:f3cebcce5c9a 312 // set flag for printing
fiifimills 6:f3cebcce5c9a 313 printFlag = 1;
fiifimills 6:f3cebcce5c9a 314 }
fiifimills 6:f3cebcce5c9a 315
fiifimills 6:f3cebcce5c9a 316 void moveSnake()
fiifimills 6:f3cebcce5c9a 317 {
fiifimills 9:739c0e5cba63 318 srand(time(NULL)); // use time as seed for rand
fiifimills 6:f3cebcce5c9a 319
fiifimills 12:fa654504b51f 320 int foodX = rand()%82+1; // random x coordinate between 1-82
fiifimills 12:fa654504b51f 321 int foodY = rand()%46+1; // random y coordinate between 1-46
fiifimills 6:f3cebcce5c9a 322
fiifimills 6:f3cebcce5c9a 323 // draw border
fiifimills 6:f3cebcce5c9a 324 lcd.drawRect(0,0,83,47,0); // x-origin, y-origin, width, height, fill
fiifimills 6:f3cebcce5c9a 325 lcd.refresh();
fiifimills 6:f3cebcce5c9a 326
fiifimills 11:f421defe6f55 327 if (!lcd.getPixel(foodX,foodY)) // if pixel is not already set
fiifimills 9:739c0e5cba63 328 lcd.setPixel(foodX,foodY); // set pixel of this coordinate (used for food)
fiifimills 11:f421defe6f55 329 lcd.refresh();
fiifimills 9:739c0e5cba63 330
fiifimills 9:739c0e5cba63 331 while (1) { // infinite loop
fiifimills 0:3bcffeeec36d 332
fiifimills 6:f3cebcce5c9a 333 if (joystick.direction == CENTRE) { // if the joystick is in the centre
fiifimills 6:f3cebcce5c9a 334 currentDirection = previousDirection; // current direction is the previous direction of movement
fiifimills 6:f3cebcce5c9a 335 }
fiifimills 9:739c0e5cba63 336 if (joystick.direction == UNKNOWN) { // if the joystick's direction is unknown
fiifimills 6:f3cebcce5c9a 337 currentDirection = previousDirection; // current direction is the previous direction
fiifimills 6:f3cebcce5c9a 338 }
fiifimills 9:739c0e5cba63 339
fiifimills 9:739c0e5cba63 340 // if joystick direction is left, right, up or down, set the current direction to be the joystick's direction
fiifimills 9:739c0e5cba63 341 if (joystick.direction == LEFT) {
fiifimills 9:739c0e5cba63 342 currentDirection = joystick.direction;
fiifimills 6:f3cebcce5c9a 343 }
fiifimills 6:f3cebcce5c9a 344 if (joystick.direction == RIGHT) {
fiifimills 6:f3cebcce5c9a 345 currentDirection = joystick.direction;
fiifimills 6:f3cebcce5c9a 346 }
fiifimills 6:f3cebcce5c9a 347 if (joystick.direction == UP) {
fiifimills 6:f3cebcce5c9a 348 currentDirection = joystick.direction;
fiifimills 6:f3cebcce5c9a 349 }
fiifimills 6:f3cebcce5c9a 350 if (joystick.direction == DOWN) {
fiifimills 6:f3cebcce5c9a 351 currentDirection = joystick.direction;
fiifimills 6:f3cebcce5c9a 352 }
fiifimills 6:f3cebcce5c9a 353
fiifimills 9:739c0e5cba63 354 lcd.clearPixel(Snake.front().x, Snake.front().y); // clear the tail pixel of snake
fiifimills 6:f3cebcce5c9a 355
fiifimills 6:f3cebcce5c9a 356 for (int i=0; i<Snake.size()-1; i++) { // shift along each element in the vector so that..
fiifimills 9:739c0e5cba63 357 Snake.at(i) = Snake.at(i+1); // value of element Snake[0] = Snake[1], Snake[1] = Snake[2] etc.
fiifimills 0:3bcffeeec36d 358 }
fiifimills 0:3bcffeeec36d 359
fiifimills 6:f3cebcce5c9a 360 switch (currentDirection) { // check the current direction
fiifimills 0:3bcffeeec36d 361
fiifimills 6:f3cebcce5c9a 362 case UP: // if up
fiifimills 9:739c0e5cba63 363 if (previousDirection == DOWN) { // check if the previous direction was opposite to the current direction
fiifimills 9:739c0e5cba63 364 currentDirection = DOWN; // if so, move in the previous direction
fiifimills 9:739c0e5cba63 365 Snake.back().y++; // increment appropiate coordinate value
fiifimills 9:739c0e5cba63 366 } else { // if the previous direction wasn't opposite to the current direction,
fiifimills 9:739c0e5cba63 367 previousDirection = UP; // set the previous direction
fiifimills 6:f3cebcce5c9a 368 Snake.back().y--; // increment appropiate coordinate value
fiifimills 6:f3cebcce5c9a 369 }
fiifimills 6:f3cebcce5c9a 370 break;
fiifimills 5:6dd0bec55e52 371
fiifimills 6:f3cebcce5c9a 372 case DOWN:
fiifimills 6:f3cebcce5c9a 373 if (previousDirection == UP) {
fiifimills 6:f3cebcce5c9a 374 currentDirection = UP;
fiifimills 6:f3cebcce5c9a 375 Snake.back().y--;
fiifimills 6:f3cebcce5c9a 376 } else {
fiifimills 6:f3cebcce5c9a 377 previousDirection = DOWN;
fiifimills 6:f3cebcce5c9a 378 Snake.back().y++;
fiifimills 6:f3cebcce5c9a 379 }
fiifimills 6:f3cebcce5c9a 380 break;
fiifimills 0:3bcffeeec36d 381
fiifimills 6:f3cebcce5c9a 382 case LEFT:
fiifimills 6:f3cebcce5c9a 383 if (previousDirection == RIGHT) {
fiifimills 6:f3cebcce5c9a 384 currentDirection = RIGHT;
fiifimills 6:f3cebcce5c9a 385 Snake.back().x++;
fiifimills 6:f3cebcce5c9a 386 } else {
fiifimills 6:f3cebcce5c9a 387 previousDirection = LEFT;
fiifimills 6:f3cebcce5c9a 388 Snake.back().x--;
fiifimills 6:f3cebcce5c9a 389 }
fiifimills 6:f3cebcce5c9a 390 break;
fiifimills 0:3bcffeeec36d 391
fiifimills 6:f3cebcce5c9a 392 case RIGHT:
fiifimills 6:f3cebcce5c9a 393 if (previousDirection == LEFT) {
fiifimills 6:f3cebcce5c9a 394 currentDirection = LEFT;
fiifimills 6:f3cebcce5c9a 395 Snake.back().x--;
fiifimills 6:f3cebcce5c9a 396 } else {
fiifimills 6:f3cebcce5c9a 397 previousDirection = RIGHT;
fiifimills 6:f3cebcce5c9a 398 Snake.back().x++;
fiifimills 6:f3cebcce5c9a 399 }
fiifimills 6:f3cebcce5c9a 400 break;
fiifimills 0:3bcffeeec36d 401
fiifimills 6:f3cebcce5c9a 402 default:
fiifimills 6:f3cebcce5c9a 403 break;
fiifimills 6:f3cebcce5c9a 404 }
fiifimills 0:3bcffeeec36d 405
fiifimills 9:739c0e5cba63 406 if ((Snake.back().x == foodX) && (Snake.back().y == foodY)) { // if the snake head hits the food
fiifimills 5:6dd0bec55e52 407
fiifimills 0:3bcffeeec36d 408 switch (currentDirection) { // check the current direction
fiifimills 0:3bcffeeec36d 409
fiifimills 6:f3cebcce5c9a 410 case UP:
fiifimills 9:739c0e5cba63 411 Snake.push_back(Snake.back()); // add an element, which is equal to the penultimate element, to the end of the vector
fiifimills 9:739c0e5cba63 412 Snake.back().y--; // increment the appropiate coordinate of this new element for the direction of movement
fiifimills 6:f3cebcce5c9a 413 foodX = rand()%82 + 1; // x coordinate of food is now a new random number between 1-83
fiifimills 6:f3cebcce5c9a 414 foodY = rand()%46 + 1; // y coordinate of food is now a new random number between 1-47
fiifimills 6:f3cebcce5c9a 415
fiifimills 9:739c0e5cba63 416 if (!lcd.getPixel(foodX,foodY)) {
fiifimills 9:739c0e5cba63 417 lcd.setPixel(foodX,foodY);
fiifimills 9:739c0e5cba63 418 lcd.refresh();
fiifimills 9:739c0e5cba63 419 }
fiifimills 9:739c0e5cba63 420
fiifimills 9:739c0e5cba63 421 score++; // increment score value
fiifimills 9:739c0e5cba63 422
fiifimills 9:739c0e5cba63 423 // flash led
fiifimills 9:739c0e5cba63 424 myleds = 1;
fiifimills 9:739c0e5cba63 425 wait(0.2);
fiifimills 9:739c0e5cba63 426 myleds = 0;
fiifimills 0:3bcffeeec36d 427 break;
fiifimills 0:3bcffeeec36d 428
fiifimills 0:3bcffeeec36d 429 case DOWN:
fiifimills 6:f3cebcce5c9a 430 Snake.push_back(Snake.back());
fiifimills 6:f3cebcce5c9a 431 Snake.back().y++;
fiifimills 6:f3cebcce5c9a 432 foodX = rand()%82 + 1;
fiifimills 6:f3cebcce5c9a 433 foodY = rand()%46 + 1;
fiifimills 6:f3cebcce5c9a 434
fiifimills 9:739c0e5cba63 435 if (!lcd.getPixel(foodX,foodY)) {
fiifimills 9:739c0e5cba63 436 lcd.setPixel(foodX,foodY);
fiifimills 9:739c0e5cba63 437 lcd.refresh();
fiifimills 9:739c0e5cba63 438 }
fiifimills 6:f3cebcce5c9a 439 score++;
fiifimills 9:739c0e5cba63 440
fiifimills 9:739c0e5cba63 441 myleds = 1;
fiifimills 9:739c0e5cba63 442 wait(0.2);
fiifimills 9:739c0e5cba63 443 myleds = 0;
fiifimills 0:3bcffeeec36d 444 break;
fiifimills 0:3bcffeeec36d 445
fiifimills 0:3bcffeeec36d 446 case LEFT:
fiifimills 6:f3cebcce5c9a 447 Snake.push_back(Snake.back());
fiifimills 6:f3cebcce5c9a 448 Snake.back().x--;
fiifimills 6:f3cebcce5c9a 449 foodX = rand()%82 + 1;
fiifimills 6:f3cebcce5c9a 450 foodY = rand()%46 + 1;
fiifimills 6:f3cebcce5c9a 451
fiifimills 9:739c0e5cba63 452 if (!lcd.getPixel(foodX,foodY)) {
fiifimills 9:739c0e5cba63 453 lcd.setPixel(foodX,foodY);
fiifimills 9:739c0e5cba63 454 lcd.refresh();
fiifimills 9:739c0e5cba63 455 }
fiifimills 6:f3cebcce5c9a 456 score++;
fiifimills 9:739c0e5cba63 457
fiifimills 9:739c0e5cba63 458 myleds = 1;
fiifimills 9:739c0e5cba63 459 wait(0.2);
fiifimills 9:739c0e5cba63 460 myleds = 0;
fiifimills 0:3bcffeeec36d 461 break;
fiifimills 0:3bcffeeec36d 462
fiifimills 0:3bcffeeec36d 463 case RIGHT:
fiifimills 6:f3cebcce5c9a 464 Snake.push_back(Snake.back());
fiifimills 6:f3cebcce5c9a 465 Snake.back().x++;
fiifimills 6:f3cebcce5c9a 466 foodX = rand()%82 + 1;
fiifimills 6:f3cebcce5c9a 467 foodY = rand()%46 + 1;
fiifimills 6:f3cebcce5c9a 468
fiifimills 9:739c0e5cba63 469 if (!lcd.getPixel(foodX,foodY)) {
fiifimills 9:739c0e5cba63 470 lcd.setPixel(foodX,foodY);
fiifimills 9:739c0e5cba63 471 lcd.refresh();
fiifimills 9:739c0e5cba63 472 }
fiifimills 6:f3cebcce5c9a 473 score++;
fiifimills 9:739c0e5cba63 474
fiifimills 9:739c0e5cba63 475 myleds = 1;
fiifimills 9:739c0e5cba63 476 wait(0.2);
fiifimills 9:739c0e5cba63 477 myleds = 0;
fiifimills 0:3bcffeeec36d 478 break;
fiifimills 0:3bcffeeec36d 479
fiifimills 0:3bcffeeec36d 480 default:
fiifimills 0:3bcffeeec36d 481 break;
fiifimills 0:3bcffeeec36d 482 }
fiifimills 0:3bcffeeec36d 483
fiifimills 6:f3cebcce5c9a 484 }
fiifimills 6:f3cebcce5c9a 485
fiifimills 5:6dd0bec55e52 486
fiifimills 9:739c0e5cba63 487 for (int i = 0; i < Snake.size()-1; i++) { // iterate through all elements in the snake vector
fiifimills 9:739c0e5cba63 488 if ((Snake.back().x == Snake.at(i).x) && (Snake.back().y == Snake.at(i).y)) { // if snake head touches any other part of the snake
fiifimills 9:739c0e5cba63 489 collisionFlag = 1; // set colision flag
fiifimills 9:739c0e5cba63 490 gameOver = true; // set gameOver to true
fiifimills 9:739c0e5cba63 491 }
fiifimills 9:739c0e5cba63 492
fiifimills 9:739c0e5cba63 493 }
fiifimills 9:739c0e5cba63 494
fiifimills 9:739c0e5cba63 495 if (collisionFlag) break; // if collision flag is set, break out of infinite loop
fiifimills 9:739c0e5cba63 496
fiifimills 6:f3cebcce5c9a 497 if (Snake.back().x > 82) { // if snakeHead's x coordinate is 83 or larger (i.e touching the right hand side border)
fiifimills 6:f3cebcce5c9a 498 gameOver = true; // game over is true
fiifimills 6:f3cebcce5c9a 499 break; // break out of infinite loop
fiifimills 6:f3cebcce5c9a 500 }
fiifimills 5:6dd0bec55e52 501
fiifimills 6:f3cebcce5c9a 502 if (Snake.back().x < 1) { // touching left hand side border
fiifimills 6:f3cebcce5c9a 503 gameOver = true;
fiifimills 6:f3cebcce5c9a 504 break;
fiifimills 6:f3cebcce5c9a 505 }
fiifimills 6:f3cebcce5c9a 506
fiifimills 6:f3cebcce5c9a 507 if (Snake.back().y > 46) { // touching top border
fiifimills 6:f3cebcce5c9a 508 gameOver = true;
fiifimills 6:f3cebcce5c9a 509 break;
fiifimills 6:f3cebcce5c9a 510 }
fiifimills 6:f3cebcce5c9a 511
fiifimills 6:f3cebcce5c9a 512 if (Snake.back().y < 1) { // touching bottom border
fiifimills 6:f3cebcce5c9a 513 gameOver = true;
fiifimills 6:f3cebcce5c9a 514 break;
fiifimills 6:f3cebcce5c9a 515 }
fiifimills 5:6dd0bec55e52 516
fiifimills 9:739c0e5cba63 517 if (xCentre + yCentre == 53) { // insane
fiifimills 9:739c0e5cba63 518
fiifimills 10:96f2c1dc956f 519 if ((Snake.back().x == 43) && (Snake.back().y < 23)) { // if snake touches upper border
fiifimills 9:739c0e5cba63 520 gameOver = true; // game over is true
fiifimills 9:739c0e5cba63 521 borderFlag = 1; // set border flag
fiifimills 9:739c0e5cba63 522 }
fiifimills 9:739c0e5cba63 523
fiifimills 10:96f2c1dc956f 524 if ((Snake.back().x == 43) && (Snake.back().y > 24)) { // if snake touches lower border
fiifimills 9:739c0e5cba63 525 gameOver = true; // game over is true
fiifimills 9:739c0e5cba63 526 borderFlag = 1; // set border flag
fiifimills 9:739c0e5cba63 527 }
fiifimills 6:f3cebcce5c9a 528 }
fiifimills 7:df77530b5fb5 529
fiifimills 9:739c0e5cba63 530 if (borderFlag) break; // if border flag is set, break out of infinite loop
fiifimills 9:739c0e5cba63 531
fiifimills 10:96f2c1dc956f 532 lcd.setPixel(Snake.back().x, Snake.back().y); // set new snakeHead's pixel
fiifimills 6:f3cebcce5c9a 533 lcd.refresh();
fiifimills 8:b52d2f436a35 534 wait(speed);
fiifimills 6:f3cebcce5c9a 535
fiifimills 6:f3cebcce5c9a 536 }
fiifimills 6:f3cebcce5c9a 537 }
fiifimills 5:6dd0bec55e52 538
fiifimills 6:f3cebcce5c9a 539 void speedSelect()
fiifimills 6:f3cebcce5c9a 540 {
fiifimills 10:96f2c1dc956f 541 if (joystick.direction == DOWN) { // if the joystick is moved down
fiifimills 5:6dd0bec55e52 542
fiifimills 10:96f2c1dc956f 543 if (xCentre == 4 && yCentre == 11) { // i.e. when the selection circle is on SLOW
fiifimills 10:96f2c1dc956f 544 lcd.clear(); // clear the screen
fiifimills 11:f421defe6f55 545
fiifimills 11:f421defe6f55 546 // print options
fiifimills 9:739c0e5cba63 547 lcd.printString("SLOW",10,1);
fiifimills 9:739c0e5cba63 548 lcd.printString("MEDIUM",10,3);
fiifimills 9:739c0e5cba63 549 lcd.printString("FAST",10,5);
fiifimills 9:739c0e5cba63 550 lcd.printString("INSANE",46,1);
fiifimills 11:f421defe6f55 551
fiifimills 10:96f2c1dc956f 552 yCentre = 27; // set new y value for centre of selection circle
fiifimills 10:96f2c1dc956f 553 lcd.drawCircle(xCentre,yCentre,3,1); // draw new selection circle
fiifimills 9:739c0e5cba63 554 lcd.refresh();
fiifimills 9:739c0e5cba63 555 wait(0.3);
fiifimills 9:739c0e5cba63 556 }
fiifimills 5:6dd0bec55e52 557
fiifimills 9:739c0e5cba63 558 else if (xCentre == 4 && yCentre == 27) { // medium
fiifimills 9:739c0e5cba63 559 lcd.clear();
fiifimills 9:739c0e5cba63 560 lcd.printString("SLOW",10,1);
fiifimills 9:739c0e5cba63 561 lcd.printString("MEDIUM",10,3);
fiifimills 9:739c0e5cba63 562 lcd.printString("FAST",10,5);
fiifimills 9:739c0e5cba63 563 lcd.printString("INSANE!",46,1);
fiifimills 9:739c0e5cba63 564 yCentre = 43;
fiifimills 9:739c0e5cba63 565 lcd.drawCircle(xCentre,yCentre,3,1);
fiifimills 9:739c0e5cba63 566 lcd.refresh();
fiifimills 9:739c0e5cba63 567 wait(0.3);
fiifimills 9:739c0e5cba63 568 }
fiifimills 0:3bcffeeec36d 569
fiifimills 9:739c0e5cba63 570 else if (xCentre == 4 && yCentre == 43) { // fast
fiifimills 9:739c0e5cba63 571 lcd.clear();
fiifimills 9:739c0e5cba63 572 lcd.printString("SLOW",10,1);
fiifimills 9:739c0e5cba63 573 lcd.printString("MEDIUM",10,3);
fiifimills 9:739c0e5cba63 574 lcd.printString("FAST",10,5);
fiifimills 9:739c0e5cba63 575 lcd.printString("INSANE",46,1);
fiifimills 9:739c0e5cba63 576 xCentre = 42;
fiifimills 9:739c0e5cba63 577 yCentre = 11;
fiifimills 9:739c0e5cba63 578 lcd.drawCircle(xCentre,yCentre,3,1);
fiifimills 9:739c0e5cba63 579 lcd.refresh();
fiifimills 9:739c0e5cba63 580 wait(0.3);
fiifimills 9:739c0e5cba63 581 }
fiifimills 7:df77530b5fb5 582 }
fiifimills 9:739c0e5cba63 583
fiifimills 9:739c0e5cba63 584 if (joystick.direction == UP) {
fiifimills 9:739c0e5cba63 585
fiifimills 9:739c0e5cba63 586 if (xCentre == 42 && yCentre == 11) { // insane
fiifimills 9:739c0e5cba63 587 lcd.clear();
fiifimills 9:739c0e5cba63 588 lcd.printString("SLOW",10,1);
fiifimills 9:739c0e5cba63 589 lcd.printString("MEDIUM",10,3);
fiifimills 9:739c0e5cba63 590 lcd.printString("FAST",10,5);
fiifimills 9:739c0e5cba63 591 lcd.printString("INSANE",46,1);
fiifimills 9:739c0e5cba63 592 xCentre = 4;
fiifimills 9:739c0e5cba63 593 yCentre = 43;
fiifimills 9:739c0e5cba63 594 lcd.drawCircle(xCentre,yCentre,3,1);
fiifimills 9:739c0e5cba63 595 lcd.refresh();
fiifimills 9:739c0e5cba63 596 wait(0.3);
fiifimills 9:739c0e5cba63 597 }
fiifimills 7:df77530b5fb5 598
fiifimills 9:739c0e5cba63 599 else if (xCentre == 4 && yCentre == 43) { // fast
fiifimills 9:739c0e5cba63 600 lcd.clear();
fiifimills 9:739c0e5cba63 601 lcd.printString("SLOW",10,1);
fiifimills 9:739c0e5cba63 602 lcd.printString("MEDIUM",10,3);
fiifimills 9:739c0e5cba63 603 lcd.printString("FAST",10,5);
fiifimills 9:739c0e5cba63 604 lcd.printString("INSANE!",46,1);
fiifimills 9:739c0e5cba63 605 yCentre = 27;
fiifimills 9:739c0e5cba63 606 lcd.drawCircle(xCentre,yCentre,3,1);
fiifimills 9:739c0e5cba63 607 lcd.refresh();
fiifimills 9:739c0e5cba63 608 wait(0.3);
fiifimills 9:739c0e5cba63 609 }
fiifimills 7:df77530b5fb5 610
fiifimills 9:739c0e5cba63 611 else if (xCentre == 4 && yCentre == 27) { // medium
fiifimills 9:739c0e5cba63 612 lcd.clear();
fiifimills 9:739c0e5cba63 613 lcd.printString("SLOW",10,1);
fiifimills 9:739c0e5cba63 614 lcd.printString("MEDIUM",10,3);
fiifimills 9:739c0e5cba63 615 lcd.printString("FAST",10,5);
fiifimills 9:739c0e5cba63 616 lcd.printString("INSANE",46,1);
fiifimills 9:739c0e5cba63 617 yCentre = 11;
fiifimills 9:739c0e5cba63 618 lcd.drawCircle(xCentre,yCentre,3,1);
fiifimills 9:739c0e5cba63 619 lcd.refresh();
fiifimills 9:739c0e5cba63 620 wait(0.3);
fiifimills 7:df77530b5fb5 621 }
fiifimills 9:739c0e5cba63 622 }
fiifimills 9:739c0e5cba63 623
fiifimills 9:739c0e5cba63 624
fiifimills 9:739c0e5cba63 625
fiifimills 9:739c0e5cba63 626
fiifimills 12:fa654504b51f 627 }