Source code of my entry for Retro gaming contest (www.outrageouscircuits.com)

Dependencies:   MMA8453 mbed

Fork of LCD_DEMO by Chris Taylor

NOTE: I don't why mbed says that it's a fork form LCD_DEMO by Chris Taylor -> I don't use that library

SHAKE THE MAZE!!!

Shake your RETRO board and solve the maze!!! /media/uploads/gbr1mbed/dscn0738.jpg

Different maze everytime! /media/uploads/gbr1mbed/dscn0739.jpg

Here a case I built. /media/uploads/gbr1mbed/dscn0742.jpg

More details in main.cpp comments

video:

Committer:
gbr1mbed
Date:
Sun Mar 01 11:18:52 2015 +0000
Revision:
1:600980390cf7
Parent:
0:7260a2716edf
Hello! this is my source for "Shake the Maze" game.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gbr1mbed 1:600980390cf7 1 /*
gbr1mbed 1:600980390cf7 2 * SHAKE THE MAZE!!!
gbr1mbed 1:600980390cf7 3 *
gbr1mbed 1:600980390cf7 4 * Author: BRUNO Giovanni di Dio [ aka GBr1 ]
gbr1mbed 1:600980390cf7 5 * site: www.gbr1industries.altervista.org
gbr1mbed 1:600980390cf7 6 *
gbr1mbed 1:600980390cf7 7 * video: http://youtu.be/puCMuQ1Li1I
gbr1mbed 1:600980390cf7 8 *
gbr1mbed 1:600980390cf7 9 *
gbr1mbed 1:600980390cf7 10 *
gbr1mbed 1:600980390cf7 11 * HOW TO PLAY:
gbr1mbed 1:600980390cf7 12 * 1. You need only the RETRO board by Outrageous Circuit
gbr1mbed 1:600980390cf7 13 * 2. After loaded the file (I use "cp" command in mac osx terminal )
gbr1mbed 1:600980390cf7 14 * Note: file .bin is about 32KB I don't try if Windows drag and drop works well :(
gbr1mbed 1:600980390cf7 15 * 3. Reset
gbr1mbed 1:600980390cf7 16 * 4. Left LED is turned on
gbr1mbed 1:600980390cf7 17 * 5. Shake the board
gbr1mbed 1:600980390cf7 18 * 6. Press start button (alien spaceship button)
gbr1mbed 1:600980390cf7 19 * 7. Left LED is turned off
gbr1mbed 1:600980390cf7 20 * 8. Wait beep end
gbr1mbed 1:600980390cf7 21 * 9. Move the board to put green ball into red square (finish)
gbr1mbed 1:600980390cf7 22 * 10. When you finish Right LED is turned on
gbr1mbed 1:600980390cf7 23 * 11. Press start to play again
gbr1mbed 1:600980390cf7 24 * 12. Right LED is turned off
gbr1mbed 1:600980390cf7 25 * 13. You have a new maze to solve (go to 8)
gbr1mbed 1:600980390cf7 26 *
gbr1mbed 1:600980390cf7 27 *
gbr1mbed 1:600980390cf7 28 * NOTE: don't update to a newer version
gbr1mbed 1:600980390cf7 29 */
gbr1mbed 1:600980390cf7 30
gbr1mbed 1:600980390cf7 31
gbr1mbed 1:600980390cf7 32
gbr1mbed 1:600980390cf7 33
gbr1mbed 1:600980390cf7 34
gbr1mbed 1:600980390cf7 35
taylorza 0:7260a2716edf 36 #include "mbed.h"
gbr1mbed 1:600980390cf7 37 //RETRO board display
gbr1mbed 1:600980390cf7 38 #include "DisplayN18.h"
gbr1mbed 1:600980390cf7 39 //C++ standard stack class
gbr1mbed 1:600980390cf7 40 #include <stack>
gbr1mbed 1:600980390cf7 41 //RETRO board accelerometer
gbr1mbed 1:600980390cf7 42 #include "MMA8453.h"
gbr1mbed 1:600980390cf7 43
gbr1mbed 1:600980390cf7 44 //accelerometer
gbr1mbed 1:600980390cf7 45 MMA8453 acc(P0_5,P0_4);
gbr1mbed 1:600980390cf7 46 //x axis
gbr1mbed 1:600980390cf7 47 double xx=0;
gbr1mbed 1:600980390cf7 48 //y axis
gbr1mbed 1:600980390cf7 49 double yy=0;
gbr1mbed 1:600980390cf7 50 //z axis (it will be used in initRand())
gbr1mbed 1:600980390cf7 51 double zz=0;
gbr1mbed 1:600980390cf7 52
gbr1mbed 1:600980390cf7 53 //Alien Spaceship button
gbr1mbed 1:600980390cf7 54 DigitalIn start(P0_1,PullUp);
gbr1mbed 1:600980390cf7 55 //Left LED -> capturing accelerometer data to random seed
gbr1mbed 1:600980390cf7 56 DigitalOut ledL(P0_9);
gbr1mbed 1:600980390cf7 57 //Right LED -> Do you want to play?
gbr1mbed 1:600980390cf7 58 DigitalOut ledR(P0_8);
gbr1mbed 1:600980390cf7 59 //Buzzer (due low program memory I use software PWM)
gbr1mbed 1:600980390cf7 60 DigitalOut buzzer(P0_18);
gbr1mbed 1:600980390cf7 61
gbr1mbed 1:600980390cf7 62 //numbers for random function
gbr1mbed 1:600980390cf7 63 unsigned int m_z=0;
gbr1mbed 1:600980390cf7 64 unsigned int m_w=0;
gbr1mbed 1:600980390cf7 65
gbr1mbed 1:600980390cf7 66 //display object
gbr1mbed 1:600980390cf7 67 DisplayN18 Surface;
gbr1mbed 1:600980390cf7 68 //colors used
gbr1mbed 1:600980390cf7 69 static const unsigned short CLINE = DisplayN18::BLUE; //blue
gbr1mbed 1:600980390cf7 70 static const unsigned short CBALL = DisplayN18::GREEN; //green
gbr1mbed 1:600980390cf7 71 static const unsigned short CEND = DisplayN18::RED; //red
gbr1mbed 1:600980390cf7 72 static const unsigned short CBACK = DisplayN18::BLACK; //black
gbr1mbed 1:600980390cf7 73 static const unsigned short CTEXT1 = 0xF81F; //yellow
gbr1mbed 1:600980390cf7 74 static const unsigned short CTEXT2 = 0xFFE0; //violet
gbr1mbed 1:600980390cf7 75 static const unsigned short CTEXT3 = 0xFFFF; //white
gbr1mbed 1:600980390cf7 76
gbr1mbed 1:600980390cf7 77 //constants to indicate cardinal coordinates
gbr1mbed 1:600980390cf7 78 //I used 0 to 3 because I will do random from 0 to 3
gbr1mbed 1:600980390cf7 79 const int NORTH=0;
gbr1mbed 1:600980390cf7 80 const int SOUTH=1;
gbr1mbed 1:600980390cf7 81 const int EAST=2;
gbr1mbed 1:600980390cf7 82 const int WEST=3;
gbr1mbed 1:600980390cf7 83 //maze blocks size
gbr1mbed 1:600980390cf7 84 const int SIZEX=32;
gbr1mbed 1:600980390cf7 85 const int SIZEY=23;
gbr1mbed 1:600980390cf7 86
gbr1mbed 1:600980390cf7 87 //create maze variables
gbr1mbed 1:600980390cf7 88 int nGood = 0;
gbr1mbed 1:600980390cf7 89 int locX = 1, locY = 1;
gbr1mbed 1:600980390cf7 90
gbr1mbed 1:600980390cf7 91 //ball and generally print coordinates
gbr1mbed 1:600980390cf7 92 int x=0;
gbr1mbed 1:600980390cf7 93 int y=0;
gbr1mbed 1:600980390cf7 94
gbr1mbed 1:600980390cf7 95
gbr1mbed 1:600980390cf7 96 /*my function to explore maze and generate random values*/
gbr1mbed 1:600980390cf7 97 //pseudo-random function
gbr1mbed 1:600980390cf7 98 //on lpc11u24 random doesn't work (it equals rand() )
gbr1mbed 1:600980390cf7 99 unsigned int rnd();
gbr1mbed 1:600980390cf7 100
gbr1mbed 1:600980390cf7 101 //random seed & initial window (it equals srand and a simple text show function)
gbr1mbed 1:600980390cf7 102 void initRand();
gbr1mbed 1:600980390cf7 103
gbr1mbed 1:600980390cf7 104 //estabilish on which type of pattern you are
gbr1mbed 1:600980390cf7 105 //you have to remember that in this case N=1 S=2 E=4 W=8 it allows you to have unique combinations
gbr1mbed 1:600980390cf7 106 int evaluateCell(int i, int j,bool grid[SIZEY][SIZEX]);
gbr1mbed 1:600980390cf7 107
gbr1mbed 1:600980390cf7 108 //redraw ball and check if there are collisions
gbr1mbed 1:600980390cf7 109 void updateBall(int direction, bool grid[SIZEY][SIZEX]);
gbr1mbed 1:600980390cf7 110
gbr1mbed 1:600980390cf7 111 //draw the maze
gbr1mbed 1:600980390cf7 112 void printGrid(bool grid[SIZEY][SIZEX]);
gbr1mbed 1:600980390cf7 113
gbr1mbed 1:600980390cf7 114
gbr1mbed 1:600980390cf7 115 /*maze creation functions*/
gbr1mbed 1:600980390cf7 116 //I used recoursive backtracker http://en.wikipedia.org/wiki/Maze_generation_algorithm#Recursive_backtracker
taylorza 0:7260a2716edf 117
gbr1mbed 1:600980390cf7 118 //move on x axis
gbr1mbed 1:600980390cf7 119 int moveEW(int direction, int i);
gbr1mbed 1:600980390cf7 120 //move on y axis
gbr1mbed 1:600980390cf7 121 int moveNS(int direction, int j);
gbr1mbed 1:600980390cf7 122 //check if it can go here
gbr1mbed 1:600980390cf7 123 bool isGood(int i, int j, int direction, bool grid[SIZEY][SIZEX]);
gbr1mbed 1:600980390cf7 124 //create maze
gbr1mbed 1:600980390cf7 125 void createMaze(bool grid[SIZEY][SIZEX]);
gbr1mbed 1:600980390cf7 126 //draw finish pattern and mark it on the maze and check also if it will be possible to go there
gbr1mbed 1:600980390cf7 127 void checkEnd(bool grid[SIZEY][SIZEX]);
gbr1mbed 1:600980390cf7 128
gbr1mbed 1:600980390cf7 129
gbr1mbed 1:600980390cf7 130 /*---game functions---*/
gbr1mbed 1:600980390cf7 131
gbr1mbed 1:600980390cf7 132 //simple beep
gbr1mbed 1:600980390cf7 133 void sound();
gbr1mbed 1:600980390cf7 134 //initialize game
gbr1mbed 1:600980390cf7 135 void initGame(bool grid[SIZEY][SIZEX]);
gbr1mbed 1:600980390cf7 136 //function which allows you to play
gbr1mbed 1:600980390cf7 137 void coreGame(bool grid[SIZEY][SIZEX]);
gbr1mbed 1:600980390cf7 138
gbr1mbed 1:600980390cf7 139
gbr1mbed 1:600980390cf7 140 /*---main---*/
gbr1mbed 1:600980390cf7 141 int main(){
gbr1mbed 1:600980390cf7 142 //create grid
gbr1mbed 1:600980390cf7 143 //using recoursive function is better if grid is here
gbr1mbed 1:600980390cf7 144 bool grid[SIZEY][SIZEX];
gbr1mbed 1:600980390cf7 145
gbr1mbed 1:600980390cf7 146 //initialize random (first screen)
gbr1mbed 1:600980390cf7 147 initRand();
gbr1mbed 1:600980390cf7 148 //initialize game (second screen - play)
gbr1mbed 1:600980390cf7 149 initGame(grid);
gbr1mbed 1:600980390cf7 150 //play ;)
gbr1mbed 1:600980390cf7 151 while(1){
gbr1mbed 1:600980390cf7 152 coreGame(grid);
gbr1mbed 1:600980390cf7 153 }
gbr1mbed 1:600980390cf7 154 }
gbr1mbed 1:600980390cf7 155
gbr1mbed 1:600980390cf7 156
gbr1mbed 1:600980390cf7 157
gbr1mbed 1:600980390cf7 158
gbr1mbed 1:600980390cf7 159 /*---implementations---*/
gbr1mbed 1:600980390cf7 160
gbr1mbed 1:600980390cf7 161 unsigned int rnd(){
gbr1mbed 1:600980390cf7 162 //pseudo-random function
gbr1mbed 1:600980390cf7 163 m_z = 36969 * (m_z & 65535) + (m_z >>16);
gbr1mbed 1:600980390cf7 164 m_w = 18000 * (m_w & 65535) + (m_w >>16);
gbr1mbed 1:600980390cf7 165 return ((m_z <<16) + m_w);
gbr1mbed 1:600980390cf7 166 }
gbr1mbed 1:600980390cf7 167
gbr1mbed 1:600980390cf7 168 void initRand(){
gbr1mbed 1:600980390cf7 169 //preserve for pressing button before the game
gbr1mbed 1:600980390cf7 170 while(start==0);
gbr1mbed 1:600980390cf7 171 //show initial screen
gbr1mbed 1:600980390cf7 172 ledL=1;
gbr1mbed 1:600980390cf7 173 Surface.clear();
gbr1mbed 1:600980390cf7 174 Surface.drawString(16,30,"Shake it!!!",CTEXT1,CBACK,2);
gbr1mbed 1:600980390cf7 175 Surface.drawString(32,90,"press start",CTEXT2,CBACK);
gbr1mbed 1:600980390cf7 176 Surface.drawString(48,100,"to continue...",CTEXT2,CBACK);
gbr1mbed 1:600980390cf7 177 //wait for checking alien spaceship button
gbr1mbed 1:600980390cf7 178 while(start==1){
gbr1mbed 1:600980390cf7 179 //simple function to read values and sum them
gbr1mbed 1:600980390cf7 180 //NOTE: you need to do abs because accelerometer values could be negative
gbr1mbed 1:600980390cf7 181 acc.getXYZ(xx,yy,zz);
gbr1mbed 1:600980390cf7 182 xx=abs(xx)*200;
gbr1mbed 1:600980390cf7 183 yy=abs(yy)*200;
gbr1mbed 1:600980390cf7 184 zz=abs(zz)*200;
gbr1mbed 1:600980390cf7 185 m_z=m_z+xx*yy+zz;
gbr1mbed 1:600980390cf7 186 m_w=m_w+xx+yy*zz;
gbr1mbed 1:600980390cf7 187 }
gbr1mbed 1:600980390cf7 188 ledL=0;
gbr1mbed 1:600980390cf7 189 }
gbr1mbed 1:600980390cf7 190
gbr1mbed 1:600980390cf7 191
gbr1mbed 1:600980390cf7 192
gbr1mbed 1:600980390cf7 193 int evaluateCell(int i, int j,bool grid[SIZEY][SIZEX]){
gbr1mbed 1:600980390cf7 194 int cell=0;
gbr1mbed 1:600980390cf7 195 //estabilish type of pattern (just sum values of walls
gbr1mbed 1:600980390cf7 196 if ((i>=0)&&(i<(SIZEX-1))){
gbr1mbed 1:600980390cf7 197 if (grid[j][i+1]==true) {
gbr1mbed 1:600980390cf7 198 cell+=4;
gbr1mbed 1:600980390cf7 199 }
gbr1mbed 1:600980390cf7 200 }
gbr1mbed 1:600980390cf7 201 if ((i>0)&&(i<=(SIZEX-1))){
gbr1mbed 1:600980390cf7 202 if (grid[j][i-1]==true) {
gbr1mbed 1:600980390cf7 203 cell+=8;
gbr1mbed 1:600980390cf7 204 }
gbr1mbed 1:600980390cf7 205 }
gbr1mbed 1:600980390cf7 206 if ((j>=0)&&(j<(SIZEY-1))){
gbr1mbed 1:600980390cf7 207 if (grid[j+1][i]==true) {
gbr1mbed 1:600980390cf7 208 cell+=2;
gbr1mbed 1:600980390cf7 209 }
gbr1mbed 1:600980390cf7 210 }
gbr1mbed 1:600980390cf7 211 if ((j>0)&&(j<=(SIZEY-1))){
gbr1mbed 1:600980390cf7 212 if (grid[j-1][i]==true) {
gbr1mbed 1:600980390cf7 213 cell+=1;
gbr1mbed 1:600980390cf7 214 }
gbr1mbed 1:600980390cf7 215 }
gbr1mbed 1:600980390cf7 216 return cell;
gbr1mbed 1:600980390cf7 217 }
gbr1mbed 1:600980390cf7 218
gbr1mbed 1:600980390cf7 219 void updateBall(int direction, bool grid[SIZEY][SIZEX]){
gbr1mbed 1:600980390cf7 220 //clear old ball
gbr1mbed 1:600980390cf7 221 Surface.fillCircle(x+2,y+15,2,CBACK);
gbr1mbed 1:600980390cf7 222 //check if is possible to move ball in "direction"
gbr1mbed 1:600980390cf7 223 //it checks every situation
gbr1mbed 1:600980390cf7 224 int cell=evaluateCell(x/5,y/5,grid);
gbr1mbed 1:600980390cf7 225 if ((direction==NORTH)&&((cell%2)==0)){
gbr1mbed 1:600980390cf7 226 y=y-5;
gbr1mbed 1:600980390cf7 227 }
gbr1mbed 1:600980390cf7 228 if ((direction==SOUTH)&&((cell==0)||(cell==1)||(cell==4)||(cell==5)||(cell==8)||(cell==9)||(cell==12)||(cell==13))){
gbr1mbed 1:600980390cf7 229 y=y+5;
gbr1mbed 1:600980390cf7 230 }
gbr1mbed 1:600980390cf7 231 if ((direction==EAST)&&((cell==0)||(cell==1)||(cell==2)||(cell==3)||(cell==8)||(cell==9)||(cell==10)||(cell==11))){
gbr1mbed 1:600980390cf7 232 x=x+5;
gbr1mbed 1:600980390cf7 233 }
gbr1mbed 1:600980390cf7 234 if ((direction==WEST)&&((cell>=0)&&(cell<=7))){
gbr1mbed 1:600980390cf7 235 x=x-5;
gbr1mbed 1:600980390cf7 236 }
gbr1mbed 1:600980390cf7 237 //draw ball
gbr1mbed 1:600980390cf7 238 Surface.fillCircle(x+2,y+15,2,CBALL);
gbr1mbed 1:600980390cf7 239 }
gbr1mbed 1:600980390cf7 240
taylorza 0:7260a2716edf 241
gbr1mbed 1:600980390cf7 242 void printGrid(bool grid[SIZEY][SIZEX]){
gbr1mbed 1:600980390cf7 243 Surface.clear();
gbr1mbed 1:600980390cf7 244 Surface.drawString(2,2,"Shake the Maze!!! GBr1_15",CTEXT3,CBACK);
gbr1mbed 1:600980390cf7 245 int cell=0;
gbr1mbed 1:600980390cf7 246 for (int j = 0; j < SIZEY; j++){
gbr1mbed 1:600980390cf7 247 for(int i = 0; i < SIZEX; i++){
gbr1mbed 1:600980390cf7 248 cell=0;
gbr1mbed 1:600980390cf7 249 if (grid[j][i]==true) {
gbr1mbed 1:600980390cf7 250 cell=evaluateCell(i,j,grid);
gbr1mbed 1:600980390cf7 251 //offset and 5pixels maze block
gbr1mbed 1:600980390cf7 252 x=i*5;
gbr1mbed 1:600980390cf7 253 y=(j*5)+13;
gbr1mbed 1:600980390cf7 254 //show 16 different cases of maze patterns
gbr1mbed 1:600980390cf7 255 //using N=1 E=4 S=2 W=8 -> do combination
gbr1mbed 1:600980390cf7 256 //example 11 is
gbr1mbed 1:600980390cf7 257 //
gbr1mbed 1:600980390cf7 258 // OXO
gbr1mbed 1:600980390cf7 259 // XXO
gbr1mbed 1:600980390cf7 260 // OXO
gbr1mbed 1:600980390cf7 261 //where O is free pattern X is a wall
gbr1mbed 1:600980390cf7 262
gbr1mbed 1:600980390cf7 263 switch (cell) {
gbr1mbed 1:600980390cf7 264 case 0:
gbr1mbed 1:600980390cf7 265 Surface.setPixel(x+2,y+2,CLINE);
gbr1mbed 1:600980390cf7 266 break;
gbr1mbed 1:600980390cf7 267 case 1:
gbr1mbed 1:600980390cf7 268 Surface.drawLine(x+2,y,x+2,y+3,CLINE);
gbr1mbed 1:600980390cf7 269 break;
gbr1mbed 1:600980390cf7 270 case 2:
gbr1mbed 1:600980390cf7 271 Surface.drawLine(x+2,y+2,x+2,y+5,CLINE);
gbr1mbed 1:600980390cf7 272 break;
gbr1mbed 1:600980390cf7 273 case 3:
gbr1mbed 1:600980390cf7 274 Surface.drawLine(x+2,y,x+2,y+5,CLINE);
gbr1mbed 1:600980390cf7 275 break;
gbr1mbed 1:600980390cf7 276 case 4:
gbr1mbed 1:600980390cf7 277 Surface.drawLine(x+2,y+2,x+5,y+2,CLINE);
gbr1mbed 1:600980390cf7 278 break;
gbr1mbed 1:600980390cf7 279 case 5:
gbr1mbed 1:600980390cf7 280 Surface.drawLine(x+2,y,x+2,y+3,CLINE);
gbr1mbed 1:600980390cf7 281 Surface.drawLine(x+3,y+2,x+5,y+2,CLINE);
gbr1mbed 1:600980390cf7 282 break;
gbr1mbed 1:600980390cf7 283 case 6:
gbr1mbed 1:600980390cf7 284 Surface.drawLine(x+2,y+2,x+5,y+2,CLINE);
gbr1mbed 1:600980390cf7 285 Surface.drawLine(x+2,y+3,x+2,y+5,CLINE);
gbr1mbed 1:600980390cf7 286 break;
gbr1mbed 1:600980390cf7 287 case 7:
gbr1mbed 1:600980390cf7 288 Surface.drawLine(x+2,y,x+2,y+5,CLINE);
gbr1mbed 1:600980390cf7 289 Surface.drawLine(x+3,y+2,x+5,y+2,CLINE);
gbr1mbed 1:600980390cf7 290 break;
gbr1mbed 1:600980390cf7 291 case 8:
gbr1mbed 1:600980390cf7 292 Surface.drawLine(x,y+2,x+3,y+2,CLINE);
gbr1mbed 1:600980390cf7 293 break;
gbr1mbed 1:600980390cf7 294 case 9:
gbr1mbed 1:600980390cf7 295 Surface.drawLine(x+2,y,x+2,y+3,CLINE);
gbr1mbed 1:600980390cf7 296 Surface.drawLine(x,y+2,x+2,y+2,CLINE);
gbr1mbed 1:600980390cf7 297 break;
gbr1mbed 1:600980390cf7 298 case 10:
gbr1mbed 1:600980390cf7 299 Surface.drawLine(x+2,y+2,x+2,y+5,CLINE);
gbr1mbed 1:600980390cf7 300 Surface.drawLine(x,y+2,x+2,y+2,CLINE);
gbr1mbed 1:600980390cf7 301 break;
gbr1mbed 1:600980390cf7 302 case 11:
gbr1mbed 1:600980390cf7 303 Surface.drawLine(x+2,y,x+2,y+5,CLINE);
gbr1mbed 1:600980390cf7 304 Surface.drawLine(x,y+2,x+2,y+2,CLINE);
gbr1mbed 1:600980390cf7 305 break;
gbr1mbed 1:600980390cf7 306 case 12:
gbr1mbed 1:600980390cf7 307 Surface.drawLine(x,y+2,x+5,y+2,CLINE);
gbr1mbed 1:600980390cf7 308 break;
gbr1mbed 1:600980390cf7 309 case 13:
gbr1mbed 1:600980390cf7 310 Surface.drawLine(x+2,y,x+2,y+2,CLINE);
gbr1mbed 1:600980390cf7 311 Surface.drawLine(x,y+2,x+5,y+2,CLINE);
gbr1mbed 1:600980390cf7 312 break;
gbr1mbed 1:600980390cf7 313 case 14:
gbr1mbed 1:600980390cf7 314 Surface.drawLine(x+2,y+3,x+2,y+5,CLINE);
gbr1mbed 1:600980390cf7 315 Surface.drawLine(x,y+2,x+5,y+2,CLINE);
gbr1mbed 1:600980390cf7 316 break;
gbr1mbed 1:600980390cf7 317 case 15:
gbr1mbed 1:600980390cf7 318 Surface.drawLine(x+2,y,x+2,y+5,CLINE);
gbr1mbed 1:600980390cf7 319 Surface.drawLine(x,y+2,x+5,y+2,CLINE);
gbr1mbed 1:600980390cf7 320 break;
gbr1mbed 1:600980390cf7 321 }
gbr1mbed 1:600980390cf7 322 }
gbr1mbed 1:600980390cf7 323 }
gbr1mbed 1:600980390cf7 324 }
gbr1mbed 1:600980390cf7 325 }
gbr1mbed 1:600980390cf7 326
gbr1mbed 1:600980390cf7 327
gbr1mbed 1:600980390cf7 328 int moveEW(int direction, int i){
gbr1mbed 1:600980390cf7 329 if (direction == EAST)
gbr1mbed 1:600980390cf7 330 return i + 1;
gbr1mbed 1:600980390cf7 331 else if (direction == WEST)
gbr1mbed 1:600980390cf7 332 return i - 1;
gbr1mbed 1:600980390cf7 333 else
gbr1mbed 1:600980390cf7 334 return i;
gbr1mbed 1:600980390cf7 335 }
gbr1mbed 1:600980390cf7 336
gbr1mbed 1:600980390cf7 337 int moveNS(int direction, int j){
gbr1mbed 1:600980390cf7 338 if (direction == NORTH)
gbr1mbed 1:600980390cf7 339 return j - 1;
gbr1mbed 1:600980390cf7 340 else if (direction == SOUTH)
gbr1mbed 1:600980390cf7 341 return j + 1;
gbr1mbed 1:600980390cf7 342 else
gbr1mbed 1:600980390cf7 343 return j;
gbr1mbed 1:600980390cf7 344 }
gbr1mbed 1:600980390cf7 345
gbr1mbed 1:600980390cf7 346 bool isGood(int i, int j, int direction, bool grid[SIZEY][SIZEX]){
gbr1mbed 1:600980390cf7 347 i = moveEW(direction,i);
gbr1mbed 1:600980390cf7 348 j = moveNS(direction,j);
gbr1mbed 1:600980390cf7 349 //check if it should be the end
gbr1mbed 1:600980390cf7 350 if ((grid[j][i]==false)||(i>=(SIZEX - 1))||(i<=0)||(j<= 0)||(j>=(SIZEY - 1))){
gbr1mbed 1:600980390cf7 351 return false;
gbr1mbed 1:600980390cf7 352 }
gbr1mbed 1:600980390cf7 353 //check cardinal directions
gbr1mbed 1:600980390cf7 354 if (direction == NORTH){
gbr1mbed 1:600980390cf7 355 if ((grid[j][i-1]!=false)&&(grid[j-1][i]!=false)&&(grid[j][i+1]!=false)&&(grid[j-1][i-1]!=false)&&(grid[j-1][i+1]!=false)){
gbr1mbed 1:600980390cf7 356 return true;
gbr1mbed 1:600980390cf7 357 }
gbr1mbed 1:600980390cf7 358 }
gbr1mbed 1:600980390cf7 359 if (direction == SOUTH){
gbr1mbed 1:600980390cf7 360 if ((grid[j][i-1]!=false)&&(grid[j+1][i]!=false)&&(grid[j][i+1]!=false)&&(grid[j+1][i-1]!=false)&&(grid[j+1][i+1]!=false)){
gbr1mbed 1:600980390cf7 361 return true;
gbr1mbed 1:600980390cf7 362 }
gbr1mbed 1:600980390cf7 363 }
gbr1mbed 1:600980390cf7 364 if (direction == EAST){
gbr1mbed 1:600980390cf7 365 if ((grid[j][i+1]!=false)&&(grid[j-1][i]!=false)&&(grid[j+1][i]!=false)&&(grid[j-1][i+1]!=false)&&(grid[j+1][i+1]!=false)){
gbr1mbed 1:600980390cf7 366 return true;
gbr1mbed 1:600980390cf7 367 }
gbr1mbed 1:600980390cf7 368 }
gbr1mbed 1:600980390cf7 369 if (direction == WEST){
gbr1mbed 1:600980390cf7 370 if ((grid[j][i-1]!=false)&&(grid[j-1][i]!=false)&&(grid[j+1][i]!=false)&&(grid[j-1][i-1]!=false)&&(grid[j+1][i-1]!=false)){
gbr1mbed 1:600980390cf7 371 return true;
gbr1mbed 1:600980390cf7 372 }
gbr1mbed 1:600980390cf7 373 }
gbr1mbed 1:600980390cf7 374 return false;
gbr1mbed 1:600980390cf7 375 }
taylorza 0:7260a2716edf 376
gbr1mbed 1:600980390cf7 377 void createMaze(bool grid[SIZEY][SIZEX]){
gbr1mbed 1:600980390cf7 378 //initialize grid
gbr1mbed 1:600980390cf7 379 for (int i = 0; i < SIZEY; i++){
gbr1mbed 1:600980390cf7 380 for(int j = 0; j < SIZEX; j++){
gbr1mbed 1:600980390cf7 381 grid[i][j] = true;
gbr1mbed 1:600980390cf7 382 }
gbr1mbed 1:600980390cf7 383 }
gbr1mbed 1:600980390cf7 384 //initialize stacks for xy coordinates
gbr1mbed 1:600980390cf7 385 stack<int> xValues;
gbr1mbed 1:600980390cf7 386 stack<int> yValues;
gbr1mbed 1:600980390cf7 387
gbr1mbed 1:600980390cf7 388 nGood = 0;
gbr1mbed 1:600980390cf7 389 int direction = 0;
taylorza 0:7260a2716edf 390
gbr1mbed 1:600980390cf7 391 do{
gbr1mbed 1:600980390cf7 392 //find n good moves
gbr1mbed 1:600980390cf7 393 for (int i = 0; i < 4; i++){
gbr1mbed 1:600980390cf7 394 if (isGood(locX,locY,i,grid))
gbr1mbed 1:600980390cf7 395 nGood++;
gbr1mbed 1:600980390cf7 396 }
gbr1mbed 1:600980390cf7 397 // if only 1 good move, move there
gbr1mbed 1:600980390cf7 398 if (nGood == 1){
gbr1mbed 1:600980390cf7 399 if (isGood(locX,locY,NORTH,grid))
gbr1mbed 1:600980390cf7 400 locY = moveNS(NORTH,locY);
gbr1mbed 1:600980390cf7 401 else if (isGood(locX,locY,SOUTH,grid))
gbr1mbed 1:600980390cf7 402 locY = moveNS(SOUTH,locY);
gbr1mbed 1:600980390cf7 403 else if (isGood(locX,locY,EAST,grid))
gbr1mbed 1:600980390cf7 404 locX = moveEW(EAST,locX);
gbr1mbed 1:600980390cf7 405 else if (isGood(locX,locY,WEST,grid))
gbr1mbed 1:600980390cf7 406 locX = moveEW(WEST,locX);
gbr1mbed 1:600980390cf7 407 }
gbr1mbed 1:600980390cf7 408 // if no good moves, move back in stack
gbr1mbed 1:600980390cf7 409 else if (nGood == 0){
gbr1mbed 1:600980390cf7 410 locX = xValues.top();
gbr1mbed 1:600980390cf7 411 locY = yValues.top();
gbr1mbed 1:600980390cf7 412 xValues.pop();
gbr1mbed 1:600980390cf7 413 yValues.pop();
gbr1mbed 1:600980390cf7 414 }
gbr1mbed 1:600980390cf7 415 //if more than 1 good move, push stack
gbr1mbed 1:600980390cf7 416 else if (nGood > 1){
gbr1mbed 1:600980390cf7 417 xValues.push(locX);
gbr1mbed 1:600980390cf7 418 yValues.push(locY);
gbr1mbed 1:600980390cf7 419 //direction to move randomly chosen
gbr1mbed 1:600980390cf7 420 do{
gbr1mbed 1:600980390cf7 421 direction = rnd()%4;
gbr1mbed 1:600980390cf7 422 }while (!isGood(locX,locY,direction,grid));
gbr1mbed 1:600980390cf7 423
gbr1mbed 1:600980390cf7 424 locX = moveEW(direction,locX);
gbr1mbed 1:600980390cf7 425 locY = moveNS(direction,locY);
gbr1mbed 1:600980390cf7 426 }
gbr1mbed 1:600980390cf7 427 //set grid
gbr1mbed 1:600980390cf7 428 grid[locY][locX] = false;
gbr1mbed 1:600980390cf7 429 //reset nGood value
gbr1mbed 1:600980390cf7 430 nGood = 0;
gbr1mbed 1:600980390cf7 431 }while(!xValues.empty());
gbr1mbed 1:600980390cf7 432 }
gbr1mbed 1:600980390cf7 433
gbr1mbed 1:600980390cf7 434 void checkEnd(bool grid[SIZEY][SIZEX]){
gbr1mbed 1:600980390cf7 435 //check low right angle
gbr1mbed 1:600980390cf7 436 if (grid[SIZEY-2][SIZEX-2]==true){
gbr1mbed 1:600980390cf7 437 grid[SIZEY-2][SIZEX-2]=false;
gbr1mbed 1:600980390cf7 438 }
gbr1mbed 1:600980390cf7 439
gbr1mbed 1:600980390cf7 440 int k=1;
taylorza 0:7260a2716edf 441
gbr1mbed 1:600980390cf7 442 while(((grid[SIZEY-3][SIZEX-2]==false)&&(grid[SIZEY-2][SIZEX-2-k]==false))&&(k<SIZEX-3)){
gbr1mbed 1:600980390cf7 443 grid[SIZEY-2][SIZEX-2-k]=false;
gbr1mbed 1:600980390cf7 444 Surface.fillRect((SIZEX-2-k)*5,(SIZEY-2)*5+13,5,5,CBACK);
gbr1mbed 1:600980390cf7 445 k++;
gbr1mbed 1:600980390cf7 446 }
gbr1mbed 1:600980390cf7 447
gbr1mbed 1:600980390cf7 448 if(k>=SIZEX-3){
gbr1mbed 1:600980390cf7 449 initGame(grid);
gbr1mbed 1:600980390cf7 450 }
gbr1mbed 1:600980390cf7 451
gbr1mbed 1:600980390cf7 452 //draw finish square
gbr1mbed 1:600980390cf7 453 Surface.fillRect((SIZEX-2)*5,(SIZEY-2)*5+13,5,5,CEND);
gbr1mbed 1:600980390cf7 454 }
gbr1mbed 1:600980390cf7 455
gbr1mbed 1:600980390cf7 456 void sound(){
gbr1mbed 1:600980390cf7 457 //simulate pwm
gbr1mbed 1:600980390cf7 458 for(int i=0; i<1000; i++){
gbr1mbed 1:600980390cf7 459 buzzer=1;
gbr1mbed 1:600980390cf7 460 wait(0.0005);
gbr1mbed 1:600980390cf7 461 buzzer=0;
gbr1mbed 1:600980390cf7 462 }
gbr1mbed 1:600980390cf7 463 }
gbr1mbed 1:600980390cf7 464
gbr1mbed 1:600980390cf7 465 void initGame(bool grid[SIZEY][SIZEX]){
gbr1mbed 1:600980390cf7 466 createMaze(grid);
gbr1mbed 1:600980390cf7 467 printGrid(grid);
gbr1mbed 1:600980390cf7 468 checkEnd(grid); //it is for checking the possible maze finish (low right angle)
gbr1mbed 1:600980390cf7 469 x=5;
gbr1mbed 1:600980390cf7 470 y=5;
gbr1mbed 1:600980390cf7 471 Surface.fillCircle(x+2,y+15,2,CBALL);
gbr1mbed 1:600980390cf7 472 sound();
taylorza 0:7260a2716edf 473 }
gbr1mbed 1:600980390cf7 474
gbr1mbed 1:600980390cf7 475 void coreGame(bool grid[SIZEY][SIZEX]){
gbr1mbed 1:600980390cf7 476 //read x and y on accelerometer
gbr1mbed 1:600980390cf7 477 xx=acc.getX();
gbr1mbed 1:600980390cf7 478 yy=acc.getY();
gbr1mbed 1:600980390cf7 479 //increase accelerometer value (generally 0.xx and standard value 0.5G and not G);
gbr1mbed 1:600980390cf7 480 xx=2*xx*10;
gbr1mbed 1:600980390cf7 481 yy=2*yy*10;
gbr1mbed 1:600980390cf7 482 //conditions and relative next move
gbr1mbed 1:600980390cf7 483 //I put 2 as filter value so, if you leave you RETRO on a table ball will not move
gbr1mbed 1:600980390cf7 484 if(xx<-2){
gbr1mbed 1:600980390cf7 485 updateBall(WEST,grid);
gbr1mbed 1:600980390cf7 486 }
gbr1mbed 1:600980390cf7 487 else{
gbr1mbed 1:600980390cf7 488 if(xx>2){
gbr1mbed 1:600980390cf7 489 updateBall(EAST,grid);
gbr1mbed 1:600980390cf7 490 }
gbr1mbed 1:600980390cf7 491 }
gbr1mbed 1:600980390cf7 492 if(yy>2){
gbr1mbed 1:600980390cf7 493 updateBall(SOUTH,grid);
gbr1mbed 1:600980390cf7 494 }
gbr1mbed 1:600980390cf7 495 else{
gbr1mbed 1:600980390cf7 496 if(yy<-2){
gbr1mbed 1:600980390cf7 497 updateBall(NORTH,grid);
gbr1mbed 1:600980390cf7 498 }
gbr1mbed 1:600980390cf7 499 }
gbr1mbed 1:600980390cf7 500 //check if the ball is at the end of the pattern (low right angle)
gbr1mbed 1:600980390cf7 501 if ((x/5==(SIZEX-2))&&(y/5==SIZEY-2)){
gbr1mbed 1:600980390cf7 502 ledR=1;
gbr1mbed 1:600980390cf7 503 sound();
gbr1mbed 1:600980390cf7 504 //wait for start button
gbr1mbed 1:600980390cf7 505 while(start==1);
gbr1mbed 1:600980390cf7 506 //init game
gbr1mbed 1:600980390cf7 507 initGame(grid);
gbr1mbed 1:600980390cf7 508 ledR=0;
gbr1mbed 1:600980390cf7 509 }
gbr1mbed 1:600980390cf7 510 }
gbr1mbed 1:600980390cf7 511
gbr1mbed 1:600980390cf7 512
gbr1mbed 1:600980390cf7 513
gbr1mbed 1:600980390cf7 514