ECE 4180 - Lab 4 Tower of Hanoi
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player
main.cpp@0:159d50728af0, 2016-11-02 (annotated)
- Committer:
- molorvida3
- Date:
- Wed Nov 02 17:29:14 2016 +0000
- Revision:
- 0:159d50728af0
ECE 4180 - Lab 4 Tower of Hanoi
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
molorvida3 | 0:159d50728af0 | 1 | //ECE 4180 Lab 4 |
molorvida3 | 0:159d50728af0 | 2 | //Tower of Hanoi Game - uLCD, joystick, sd card, speakers |
molorvida3 | 0:159d50728af0 | 3 | //Mark Francisco Olorvida, Khayame Maiki |
molorvida3 | 0:159d50728af0 | 4 | #include "mbed.h" |
molorvida3 | 0:159d50728af0 | 5 | #include "uLCD_4DGL.h" |
molorvida3 | 0:159d50728af0 | 6 | #include "SDFileSystem.h" |
molorvida3 | 0:159d50728af0 | 7 | #include "wave_player.h" |
molorvida3 | 0:159d50728af0 | 8 | #include "rtos.h" |
molorvida3 | 0:159d50728af0 | 9 | #include "stdlib.h" |
molorvida3 | 0:159d50728af0 | 10 | #include <stack> |
molorvida3 | 0:159d50728af0 | 11 | |
molorvida3 | 0:159d50728af0 | 12 | |
molorvida3 | 0:159d50728af0 | 13 | #define BROWN 0x663300 |
molorvida3 | 0:159d50728af0 | 14 | #define YELLOW 0xFFFF00 |
molorvida3 | 0:159d50728af0 | 15 | #define ORANGE 0xFFA500 |
molorvida3 | 0:159d50728af0 | 16 | |
molorvida3 | 0:159d50728af0 | 17 | using namespace std; |
molorvida3 | 0:159d50728af0 | 18 | |
molorvida3 | 0:159d50728af0 | 19 | class Nav_Switch |
molorvida3 | 0:159d50728af0 | 20 | { |
molorvida3 | 0:159d50728af0 | 21 | public: |
molorvida3 | 0:159d50728af0 | 22 | Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire); |
molorvida3 | 0:159d50728af0 | 23 | int read(); |
molorvida3 | 0:159d50728af0 | 24 | //boolean functions to test each switch |
molorvida3 | 0:159d50728af0 | 25 | bool up(); |
molorvida3 | 0:159d50728af0 | 26 | bool down(); |
molorvida3 | 0:159d50728af0 | 27 | bool left(); |
molorvida3 | 0:159d50728af0 | 28 | bool right(); |
molorvida3 | 0:159d50728af0 | 29 | bool fire(); |
molorvida3 | 0:159d50728af0 | 30 | //automatic read on RHS |
molorvida3 | 0:159d50728af0 | 31 | operator int (); |
molorvida3 | 0:159d50728af0 | 32 | //index to any switch array style |
molorvida3 | 0:159d50728af0 | 33 | bool operator[](int index) { |
molorvida3 | 0:159d50728af0 | 34 | return _pins[index]; |
molorvida3 | 0:159d50728af0 | 35 | }; |
molorvida3 | 0:159d50728af0 | 36 | private: |
molorvida3 | 0:159d50728af0 | 37 | BusIn _pins; |
molorvida3 | 0:159d50728af0 | 38 | |
molorvida3 | 0:159d50728af0 | 39 | }; |
molorvida3 | 0:159d50728af0 | 40 | Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire): |
molorvida3 | 0:159d50728af0 | 41 | _pins(up, down, left, right, fire) |
molorvida3 | 0:159d50728af0 | 42 | { |
molorvida3 | 0:159d50728af0 | 43 | _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise |
molorvida3 | 0:159d50728af0 | 44 | wait(0.001); //delays just a bit for pullups to pull inputs high |
molorvida3 | 0:159d50728af0 | 45 | } |
molorvida3 | 0:159d50728af0 | 46 | inline bool Nav_Switch::up() |
molorvida3 | 0:159d50728af0 | 47 | { |
molorvida3 | 0:159d50728af0 | 48 | return !(_pins[0]); |
molorvida3 | 0:159d50728af0 | 49 | } |
molorvida3 | 0:159d50728af0 | 50 | inline bool Nav_Switch::down() |
molorvida3 | 0:159d50728af0 | 51 | { |
molorvida3 | 0:159d50728af0 | 52 | return !(_pins[1]); |
molorvida3 | 0:159d50728af0 | 53 | } |
molorvida3 | 0:159d50728af0 | 54 | inline bool Nav_Switch::left() |
molorvida3 | 0:159d50728af0 | 55 | { |
molorvida3 | 0:159d50728af0 | 56 | return !(_pins[2]); |
molorvida3 | 0:159d50728af0 | 57 | } |
molorvida3 | 0:159d50728af0 | 58 | inline bool Nav_Switch::right() |
molorvida3 | 0:159d50728af0 | 59 | { |
molorvida3 | 0:159d50728af0 | 60 | return !(_pins[3]); |
molorvida3 | 0:159d50728af0 | 61 | } |
molorvida3 | 0:159d50728af0 | 62 | inline bool Nav_Switch::fire() |
molorvida3 | 0:159d50728af0 | 63 | { |
molorvida3 | 0:159d50728af0 | 64 | return !(_pins[4]); |
molorvida3 | 0:159d50728af0 | 65 | } |
molorvida3 | 0:159d50728af0 | 66 | inline int Nav_Switch::read() |
molorvida3 | 0:159d50728af0 | 67 | { |
molorvida3 | 0:159d50728af0 | 68 | return _pins.read(); |
molorvida3 | 0:159d50728af0 | 69 | } |
molorvida3 | 0:159d50728af0 | 70 | inline Nav_Switch::operator int () |
molorvida3 | 0:159d50728af0 | 71 | { |
molorvida3 | 0:159d50728af0 | 72 | return _pins.read(); |
molorvida3 | 0:159d50728af0 | 73 | } |
molorvida3 | 0:159d50728af0 | 74 | |
molorvida3 | 0:159d50728af0 | 75 | Nav_Switch myNav( p16, p13, p14, p12, p15); //up, down, left, right, fire |
molorvida3 | 0:159d50728af0 | 76 | |
molorvida3 | 0:159d50728af0 | 77 | uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin; |
molorvida3 | 0:159d50728af0 | 78 | |
molorvida3 | 0:159d50728af0 | 79 | SDFileSystem sd(p5, p6, p7, p8, "sd"); // sd(SPI mosi, SPI miso, SPI sck, digital out cs) |
molorvida3 | 0:159d50728af0 | 80 | |
molorvida3 | 0:159d50728af0 | 81 | Mutex stdio_mutex; //mutex for the uLCD |
molorvida3 | 0:159d50728af0 | 82 | |
molorvida3 | 0:159d50728af0 | 83 | AnalogOut DACout(p18); // used to play sound on speaker |
molorvida3 | 0:159d50728af0 | 84 | |
molorvida3 | 0:159d50728af0 | 85 | PwmOut Speaker(p21); |
molorvida3 | 0:159d50728af0 | 86 | |
molorvida3 | 0:159d50728af0 | 87 | //wave player plays a *.wav file to D/A and a PWM |
molorvida3 | 0:159d50728af0 | 88 | wave_player waver(&DACout); |
molorvida3 | 0:159d50728af0 | 89 | |
molorvida3 | 0:159d50728af0 | 90 | |
molorvida3 | 0:159d50728af0 | 91 | |
molorvida3 | 0:159d50728af0 | 92 | |
molorvida3 | 0:159d50728af0 | 93 | |
molorvida3 | 0:159d50728af0 | 94 | |
molorvida3 | 0:159d50728af0 | 95 | stack<int> col1; // |
molorvida3 | 0:159d50728af0 | 96 | stack<int> col2; |
molorvida3 | 0:159d50728af0 | 97 | stack<int> col3; |
molorvida3 | 0:159d50728af0 | 98 | |
molorvida3 | 0:159d50728af0 | 99 | |
molorvida3 | 0:159d50728af0 | 100 | |
molorvida3 | 0:159d50728af0 | 101 | int source; // Source of ring that is going to be moved |
molorvida3 | 0:159d50728af0 | 102 | int destination; // Destination of ring that is going to be moved |
molorvida3 | 0:159d50728af0 | 103 | int direction; // don't actually use this right now |
molorvida3 | 0:159d50728af0 | 104 | int numRings; |
molorvida3 | 0:159d50728af0 | 105 | bool select; // 0 if selecting source, 1 if selecting destination |
molorvida3 | 0:159d50728af0 | 106 | int cursor; // position of destination selecting cursor |
molorvida3 | 0:159d50728af0 | 107 | int count = 0; |
molorvida3 | 0:159d50728af0 | 108 | |
molorvida3 | 0:159d50728af0 | 109 | |
molorvida3 | 0:159d50728af0 | 110 | void move(); //move rectangles between columns |
molorvida3 | 0:159d50728af0 | 111 | void drawMove( int , int , int ); //draw the change in Rings i.e. moving Ring 1 from Src1 --> Src 2 results in col. 1 = 4 3 2 and col.2 = 1 |
molorvida3 | 0:159d50728af0 | 112 | bool checkVictory(); //function to check win condition (all rings move to a separate column from the starting column |
molorvida3 | 0:159d50728af0 | 113 | void drawCursor(int , int ); |
molorvida3 | 0:159d50728af0 | 114 | void drawSourceSelect(); |
molorvida3 | 0:159d50728af0 | 115 | void drawDestinationSelect(); |
molorvida3 | 0:159d50728af0 | 116 | void game(); //main game function |
molorvida3 | 0:159d50728af0 | 117 | |
molorvida3 | 0:159d50728af0 | 118 | int main() |
molorvida3 | 0:159d50728af0 | 119 | { |
molorvida3 | 0:159d50728af0 | 120 | //Title Screen |
molorvida3 | 0:159d50728af0 | 121 | |
molorvida3 | 0:159d50728af0 | 122 | uLCD.printf("\n Tower of Hanoi\n"); |
molorvida3 | 0:159d50728af0 | 123 | //3 vertical lines at x = 32, 64, 96 |
molorvida3 | 0:159d50728af0 | 124 | //have circles to mark the positions of columns |
molorvida3 | 0:159d50728af0 | 125 | uLCD.filled_circle(32, 110, 2, BLUE); |
molorvida3 | 0:159d50728af0 | 126 | uLCD.filled_circle(64, 110, 2, BLUE); |
molorvida3 | 0:159d50728af0 | 127 | uLCD.filled_circle(96, 110, 2, BLUE); |
molorvida3 | 0:159d50728af0 | 128 | //rectangles - each rectangle increases in width based on its number |
molorvida3 | 0:159d50728af0 | 129 | //rectangles go from 1-6 going down |
molorvida3 | 0:159d50728af0 | 130 | uLCD.filled_rectangle(32-2*1, 35+15*1-1, 32+2*1, 35+15*1, RED); //(filled_rectangle*(32(x-coordinate of vertical line)-2*(num_rectangle (1,2,3 or 4)), 35 + (60/num_rectangles)-1, first param but with addition, 2nd param but no extra 1 subtracted)) |
molorvida3 | 0:159d50728af0 | 131 | uLCD.filled_rectangle(32-2*2, 35+15*2-1, 32+2*2, 35+15*2, ORANGE); |
molorvida3 | 0:159d50728af0 | 132 | uLCD.filled_rectangle(32-2*3, 35+15*3-1, 32+2*3, 35+15*3, YELLOW); |
molorvida3 | 0:159d50728af0 | 133 | uLCD.filled_rectangle(32-2*4, 35+15*4-1, 32+2*4, 35+15*4, GREEN); |
molorvida3 | 0:159d50728af0 | 134 | |
molorvida3 | 0:159d50728af0 | 135 | //play intro wave file |
molorvida3 | 0:159d50728af0 | 136 | FILE *wave_file; |
molorvida3 | 0:159d50728af0 | 137 | //open file |
molorvida3 | 0:159d50728af0 | 138 | wave_file = fopen("/sd/wavfiles/intro.wav" ,"r"); |
molorvida3 | 0:159d50728af0 | 139 | if (wave_file == NULL){ |
molorvida3 | 0:159d50728af0 | 140 | error("Could not open file for read\n"); |
molorvida3 | 0:159d50728af0 | 141 | } |
molorvida3 | 0:159d50728af0 | 142 | //play file |
molorvida3 | 0:159d50728af0 | 143 | Speaker.period(1.0/400000.0); |
molorvida3 | 0:159d50728af0 | 144 | waver.play(wave_file); |
molorvida3 | 0:159d50728af0 | 145 | //close file |
molorvida3 | 0:159d50728af0 | 146 | fclose(wave_file); |
molorvida3 | 0:159d50728af0 | 147 | |
molorvida3 | 0:159d50728af0 | 148 | uLCD.cls(); // clear screen |
molorvida3 | 0:159d50728af0 | 149 | //tutorial |
molorvida3 | 0:159d50728af0 | 150 | uLCD.printf("\n HOW TO PLAY\n"); |
molorvida3 | 0:159d50728af0 | 151 | uLCD.printf("Goal: Move all rectangles to another pole.\n"); |
molorvida3 | 0:159d50728af0 | 152 | uLCD.printf("\n1. You can only move one rectangle at a time.\n"); |
molorvida3 | 0:159d50728af0 | 153 | uLCD.printf("\n2. Large rectangles can not be put on top of smaller rectangles.\n"); |
molorvida3 | 0:159d50728af0 | 154 | while(1){ //loop until user pushes left right or fire after reading tutorial |
molorvida3 | 0:159d50728af0 | 155 | if (myNav.left() or myNav.right() or myNav.fire()){ break;} |
molorvida3 | 0:159d50728af0 | 156 | else {} |
molorvida3 | 0:159d50728af0 | 157 | } |
molorvida3 | 0:159d50728af0 | 158 | uLCD.cls(); |
molorvida3 | 0:159d50728af0 | 159 | uLCD.printf("\n CONTROLS\n"); |
molorvida3 | 0:159d50728af0 | 160 | uLCD.printf("\nUse Left/Right to choose column \n"); |
molorvida3 | 0:159d50728af0 | 161 | uLCD.printf("-Red Circle = Source column\n"); |
molorvida3 | 0:159d50728af0 | 162 | uLCD.printf("-Yellow Cursor = Dest. column\n"); |
molorvida3 | 0:159d50728af0 | 163 | uLCD.printf("\nUse Center to select column.\n"); |
molorvida3 | 0:159d50728af0 | 164 | while(1){ //loop until user pushes left right or fire after reading tutorial |
molorvida3 | 0:159d50728af0 | 165 | if (myNav.left() or myNav.right() or myNav.fire()){ break;} |
molorvida3 | 0:159d50728af0 | 166 | else {} |
molorvida3 | 0:159d50728af0 | 167 | } |
molorvida3 | 0:159d50728af0 | 168 | game(); |
molorvida3 | 0:159d50728af0 | 169 | } |
molorvida3 | 0:159d50728af0 | 170 | void game() // main game function |
molorvida3 | 0:159d50728af0 | 171 | { |
molorvida3 | 0:159d50728af0 | 172 | uLCD.cls(); |
molorvida3 | 0:159d50728af0 | 173 | // Game init |
molorvida3 | 0:159d50728af0 | 174 | |
molorvida3 | 0:159d50728af0 | 175 | uLCD.filled_circle(32, 110, 2, BLUE); |
molorvida3 | 0:159d50728af0 | 176 | uLCD.filled_circle(64, 110, 2, BLUE); |
molorvida3 | 0:159d50728af0 | 177 | uLCD.filled_circle(96, 110, 2, BLUE); |
molorvida3 | 0:159d50728af0 | 178 | uLCD.filled_rectangle(32-2*1, 35+12*1-1, 32+2*1, 35+12*1, RED); |
molorvida3 | 0:159d50728af0 | 179 | uLCD.filled_rectangle(32-2*2, 35+12*2-1, 32+2*2, 35+12*2, ORANGE); |
molorvida3 | 0:159d50728af0 | 180 | uLCD.filled_rectangle(32-2*3, 35+12*3-1, 32+2*3, 35+12*3, YELLOW); |
molorvida3 | 0:159d50728af0 | 181 | uLCD.filled_rectangle(32-2*4, 35+12*4-1, 32+2*4, 35+12*4, GREEN); |
molorvida3 | 0:159d50728af0 | 182 | |
molorvida3 | 0:159d50728af0 | 183 | numRings = 4; |
molorvida3 | 0:159d50728af0 | 184 | col1.push(4); |
molorvida3 | 0:159d50728af0 | 185 | col1.push(3); |
molorvida3 | 0:159d50728af0 | 186 | col1.push(2); |
molorvida3 | 0:159d50728af0 | 187 | col1.push(1); |
molorvida3 | 0:159d50728af0 | 188 | |
molorvida3 | 0:159d50728af0 | 189 | // draw game |
molorvida3 | 0:159d50728af0 | 190 | source = 1; |
molorvida3 | 0:159d50728af0 | 191 | destination = 2; |
molorvida3 | 0:159d50728af0 | 192 | cursor = 2; |
molorvida3 | 0:159d50728af0 | 193 | drawSourceSelect(); |
molorvida3 | 0:159d50728af0 | 194 | drawDestinationSelect(); |
molorvida3 | 0:159d50728af0 | 195 | uLCD.filled_rectangle(32-2*1, 35+12*1-1, 32+2*1, 35+12*1, RED); |
molorvida3 | 0:159d50728af0 | 196 | uLCD.filled_rectangle(32-2*2, 35+12*2-1, 32+2*2, 35+12*2, ORANGE); |
molorvida3 | 0:159d50728af0 | 197 | uLCD.filled_rectangle(32-2*3, 35+12*3-1, 32+2*3, 35+12*3, YELLOW); |
molorvida3 | 0:159d50728af0 | 198 | uLCD.filled_rectangle(32-2*4, 35+12*4-1, 32+2*4, 35+12*4, GREEN); |
molorvida3 | 0:159d50728af0 | 199 | |
molorvida3 | 0:159d50728af0 | 200 | |
molorvida3 | 0:159d50728af0 | 201 | |
molorvida3 | 0:159d50728af0 | 202 | |
molorvida3 | 0:159d50728af0 | 203 | uLCD.locate(0,0); |
molorvida3 | 0:159d50728af0 | 204 | uLCD.printf("# of Moves: %i\n",count); //update move count |
molorvida3 | 0:159d50728af0 | 205 | while (1) { // Game loop |
molorvida3 | 0:159d50728af0 | 206 | |
molorvida3 | 0:159d50728af0 | 207 | if (checkVictory()) { // checks to see if the win condition has been met... will either reset, or go victory screen or something |
molorvida3 | 0:159d50728af0 | 208 | wait(1); |
molorvida3 | 0:159d50728af0 | 209 | uLCD.cls(); |
molorvida3 | 0:159d50728af0 | 210 | uLCD.locate(0,0); |
molorvida3 | 0:159d50728af0 | 211 | uLCD.printf("\n You won!\n"); |
molorvida3 | 0:159d50728af0 | 212 | uLCD.printf("\nMin. Moves: 15 \n"); |
molorvida3 | 0:159d50728af0 | 213 | uLCD.printf("\nYour # of moves : %i \n" , count ); |
molorvida3 | 0:159d50728af0 | 214 | //play intro wave file |
molorvida3 | 0:159d50728af0 | 215 | FILE *wave_file; |
molorvida3 | 0:159d50728af0 | 216 | //open file |
molorvida3 | 0:159d50728af0 | 217 | wave_file = fopen("/sd/wavfiles/outro.wav" ,"r"); |
molorvida3 | 0:159d50728af0 | 218 | if (wave_file == NULL) { |
molorvida3 | 0:159d50728af0 | 219 | error("Could not open file for read\n"); |
molorvida3 | 0:159d50728af0 | 220 | } |
molorvida3 | 0:159d50728af0 | 221 | //play file |
molorvida3 | 0:159d50728af0 | 222 | Speaker.period(1.0/400000.0); |
molorvida3 | 0:159d50728af0 | 223 | waver.play(wave_file); |
molorvida3 | 0:159d50728af0 | 224 | //close file |
molorvida3 | 0:159d50728af0 | 225 | fclose(wave_file); |
molorvida3 | 0:159d50728af0 | 226 | count = 0; //reset count |
molorvida3 | 0:159d50728af0 | 227 | break; |
molorvida3 | 0:159d50728af0 | 228 | } |
molorvida3 | 0:159d50728af0 | 229 | |
molorvida3 | 0:159d50728af0 | 230 | |
molorvida3 | 0:159d50728af0 | 231 | if ( myNav.left() ) { // moves either source or destination pointer to the left based on |
molorvida3 | 0:159d50728af0 | 232 | if (!select) { // the variable select |
molorvida3 | 0:159d50728af0 | 233 | if (source == 1) { |
molorvida3 | 0:159d50728af0 | 234 | source = 3; |
molorvida3 | 0:159d50728af0 | 235 | |
molorvida3 | 0:159d50728af0 | 236 | } else { |
molorvida3 | 0:159d50728af0 | 237 | source = source - 1; |
molorvida3 | 0:159d50728af0 | 238 | |
molorvida3 | 0:159d50728af0 | 239 | } |
molorvida3 | 0:159d50728af0 | 240 | drawSourceSelect(); |
molorvida3 | 0:159d50728af0 | 241 | } else { |
molorvida3 | 0:159d50728af0 | 242 | if (destination == 1) { |
molorvida3 | 0:159d50728af0 | 243 | destination = 3; |
molorvida3 | 0:159d50728af0 | 244 | |
molorvida3 | 0:159d50728af0 | 245 | } else { |
molorvida3 | 0:159d50728af0 | 246 | destination = destination - 1; |
molorvida3 | 0:159d50728af0 | 247 | |
molorvida3 | 0:159d50728af0 | 248 | } |
molorvida3 | 0:159d50728af0 | 249 | drawDestinationSelect(); |
molorvida3 | 0:159d50728af0 | 250 | } |
molorvida3 | 0:159d50728af0 | 251 | |
molorvida3 | 0:159d50728af0 | 252 | } |
molorvida3 | 0:159d50728af0 | 253 | |
molorvida3 | 0:159d50728af0 | 254 | else if ( myNav.right() ) { |
molorvida3 | 0:159d50728af0 | 255 | if (!select) { |
molorvida3 | 0:159d50728af0 | 256 | if (source == 3) { |
molorvida3 | 0:159d50728af0 | 257 | source = 1; |
molorvida3 | 0:159d50728af0 | 258 | |
molorvida3 | 0:159d50728af0 | 259 | } else { |
molorvida3 | 0:159d50728af0 | 260 | source = source + 1; |
molorvida3 | 0:159d50728af0 | 261 | } |
molorvida3 | 0:159d50728af0 | 262 | drawSourceSelect(); |
molorvida3 | 0:159d50728af0 | 263 | } else { |
molorvida3 | 0:159d50728af0 | 264 | if (destination == 3) { |
molorvida3 | 0:159d50728af0 | 265 | destination = 1; |
molorvida3 | 0:159d50728af0 | 266 | } else { |
molorvida3 | 0:159d50728af0 | 267 | destination = destination + 1; |
molorvida3 | 0:159d50728af0 | 268 | } |
molorvida3 | 0:159d50728af0 | 269 | drawDestinationSelect(); |
molorvida3 | 0:159d50728af0 | 270 | } |
molorvida3 | 0:159d50728af0 | 271 | } |
molorvida3 | 0:159d50728af0 | 272 | |
molorvida3 | 0:159d50728af0 | 273 | else if ( myNav.fire()) { |
molorvida3 | 0:159d50728af0 | 274 | if (!select) { // source chosen, toggle to choose destination |
molorvida3 | 0:159d50728af0 | 275 | select = !select; // toggles |
molorvida3 | 0:159d50728af0 | 276 | } else if (select) { // Destination chosen, move ring |
molorvida3 | 0:159d50728af0 | 277 | move(); |
molorvida3 | 0:159d50728af0 | 278 | count ++; |
molorvida3 | 0:159d50728af0 | 279 | uLCD.locate(0,0); |
molorvida3 | 0:159d50728af0 | 280 | uLCD.printf("# of Moves: %i\n",count); //update move count |
molorvida3 | 0:159d50728af0 | 281 | select = !select; // Go back to source selection regardless of the outcome of move |
molorvida3 | 0:159d50728af0 | 282 | } |
molorvida3 | 0:159d50728af0 | 283 | wait(.4); |
molorvida3 | 0:159d50728af0 | 284 | } |
molorvida3 | 0:159d50728af0 | 285 | |
molorvida3 | 0:159d50728af0 | 286 | } |
molorvida3 | 0:159d50728af0 | 287 | if (col3.size() == numRings){ //if col3 has numRings, pop all rings |
molorvida3 | 0:159d50728af0 | 288 | for (int x = 0; x < 4 ; x++){ |
molorvida3 | 0:159d50728af0 | 289 | col3.pop(); |
molorvida3 | 0:159d50728af0 | 290 | } |
molorvida3 | 0:159d50728af0 | 291 | } |
molorvida3 | 0:159d50728af0 | 292 | else if (col2.size() == numRings){ //same with col 2 |
molorvida3 | 0:159d50728af0 | 293 | for (int x = 0; x < 4 ; x++){ |
molorvida3 | 0:159d50728af0 | 294 | col2.pop(); |
molorvida3 | 0:159d50728af0 | 295 | } |
molorvida3 | 0:159d50728af0 | 296 | } |
molorvida3 | 0:159d50728af0 | 297 | game(); |
molorvida3 | 0:159d50728af0 | 298 | } |
molorvida3 | 0:159d50728af0 | 299 | void move() |
molorvida3 | 0:159d50728af0 | 300 | { |
molorvida3 | 0:159d50728af0 | 301 | int sourceSize, destSize, ringNum, top; |
molorvida3 | 0:159d50728af0 | 302 | |
molorvida3 | 0:159d50728af0 | 303 | |
molorvida3 | 0:159d50728af0 | 304 | |
molorvida3 | 0:159d50728af0 | 305 | switch (source) { |
molorvida3 | 0:159d50728af0 | 306 | |
molorvida3 | 0:159d50728af0 | 307 | case 1: |
molorvida3 | 0:159d50728af0 | 308 | sourceSize = col1.size(); // to figure out where on the Y axis to black out a ring |
molorvida3 | 0:159d50728af0 | 309 | if (sourceSize == 0) |
molorvida3 | 0:159d50728af0 | 310 | break; |
molorvida3 | 0:159d50728af0 | 311 | |
molorvida3 | 0:159d50728af0 | 312 | if ( destination == 2) { |
molorvida3 | 0:159d50728af0 | 313 | if (col2.empty()) { |
molorvida3 | 0:159d50728af0 | 314 | top = col1.top(); |
molorvida3 | 0:159d50728af0 | 315 | col2.push(top); // move the ring over |
molorvida3 | 0:159d50728af0 | 316 | |
molorvida3 | 0:159d50728af0 | 317 | col1.pop(); |
molorvida3 | 0:159d50728af0 | 318 | |
molorvida3 | 0:159d50728af0 | 319 | destSize = col2.size(); // to figure out where on Y axis to draw new ring |
molorvida3 | 0:159d50728af0 | 320 | ringNum = top; |
molorvida3 | 0:159d50728af0 | 321 | //uLCD.printf("Ring Number: %i " , ringNum); |
molorvida3 | 0:159d50728af0 | 322 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 323 | } |
molorvida3 | 0:159d50728af0 | 324 | |
molorvida3 | 0:159d50728af0 | 325 | |
molorvida3 | 0:159d50728af0 | 326 | else if ( col1.top() < col2.top()) { // if the ring on column 1 is smaller than the ring in column 2 |
molorvida3 | 0:159d50728af0 | 327 | top = col1.top(); |
molorvida3 | 0:159d50728af0 | 328 | col2.push(top); // move the ring over |
molorvida3 | 0:159d50728af0 | 329 | col1.pop(); |
molorvida3 | 0:159d50728af0 | 330 | destSize = col2.size(); // to figure out where on Y axis to draw new ring |
molorvida3 | 0:159d50728af0 | 331 | ringNum = top; |
molorvida3 | 0:159d50728af0 | 332 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 333 | |
molorvida3 | 0:159d50728af0 | 334 | } |
molorvida3 | 0:159d50728af0 | 335 | |
molorvida3 | 0:159d50728af0 | 336 | |
molorvida3 | 0:159d50728af0 | 337 | } |
molorvida3 | 0:159d50728af0 | 338 | |
molorvida3 | 0:159d50728af0 | 339 | else if ( destination == 3) { |
molorvida3 | 0:159d50728af0 | 340 | if (col3.empty()) { |
molorvida3 | 0:159d50728af0 | 341 | top = col1.top(); |
molorvida3 | 0:159d50728af0 | 342 | col3.push(top); // move the ring over |
molorvida3 | 0:159d50728af0 | 343 | col1.pop(); |
molorvida3 | 0:159d50728af0 | 344 | destSize = col3.size(); |
molorvida3 | 0:159d50728af0 | 345 | ringNum = top; |
molorvida3 | 0:159d50728af0 | 346 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 347 | } else if ( col1.top() < col3.top()) { // if the ring on column 1 is smaller than the ring in column 3 |
molorvida3 | 0:159d50728af0 | 348 | top = col1.top(); |
molorvida3 | 0:159d50728af0 | 349 | col3.push(top); // move the ring over |
molorvida3 | 0:159d50728af0 | 350 | col1.pop(); |
molorvida3 | 0:159d50728af0 | 351 | destSize = col3.size(); |
molorvida3 | 0:159d50728af0 | 352 | ringNum = top; |
molorvida3 | 0:159d50728af0 | 353 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 354 | } |
molorvida3 | 0:159d50728af0 | 355 | } |
molorvida3 | 0:159d50728af0 | 356 | |
molorvida3 | 0:159d50728af0 | 357 | |
molorvida3 | 0:159d50728af0 | 358 | break; |
molorvida3 | 0:159d50728af0 | 359 | |
molorvida3 | 0:159d50728af0 | 360 | |
molorvida3 | 0:159d50728af0 | 361 | |
molorvida3 | 0:159d50728af0 | 362 | |
molorvida3 | 0:159d50728af0 | 363 | case 2: |
molorvida3 | 0:159d50728af0 | 364 | sourceSize = col2.size(); |
molorvida3 | 0:159d50728af0 | 365 | if (sourceSize == 0) |
molorvida3 | 0:159d50728af0 | 366 | break; |
molorvida3 | 0:159d50728af0 | 367 | if ( destination == 1) { |
molorvida3 | 0:159d50728af0 | 368 | if (col1.empty()) { |
molorvida3 | 0:159d50728af0 | 369 | col1.push(col2.top()); |
molorvida3 | 0:159d50728af0 | 370 | col2.pop(); |
molorvida3 | 0:159d50728af0 | 371 | destSize = col1.size(); |
molorvida3 | 0:159d50728af0 | 372 | ringNum = col1.top(); |
molorvida3 | 0:159d50728af0 | 373 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 374 | } else if ( col2.top() < col1.top()) { |
molorvida3 | 0:159d50728af0 | 375 | col1.push(col2.top()); |
molorvida3 | 0:159d50728af0 | 376 | col2.pop(); |
molorvida3 | 0:159d50728af0 | 377 | destSize = col1.size(); |
molorvida3 | 0:159d50728af0 | 378 | ringNum = col1.top(); |
molorvida3 | 0:159d50728af0 | 379 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 380 | } |
molorvida3 | 0:159d50728af0 | 381 | } |
molorvida3 | 0:159d50728af0 | 382 | |
molorvida3 | 0:159d50728af0 | 383 | else if ( destination == 3) { |
molorvida3 | 0:159d50728af0 | 384 | if (col3.empty()) { |
molorvida3 | 0:159d50728af0 | 385 | col3.push(col2.top()); |
molorvida3 | 0:159d50728af0 | 386 | col2.pop(); |
molorvida3 | 0:159d50728af0 | 387 | destSize = col3.size(); |
molorvida3 | 0:159d50728af0 | 388 | ringNum = col3.top(); |
molorvida3 | 0:159d50728af0 | 389 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 390 | } else if ( col2.top() < col3.top()) { |
molorvida3 | 0:159d50728af0 | 391 | |
molorvida3 | 0:159d50728af0 | 392 | col3.push(col2.top()); |
molorvida3 | 0:159d50728af0 | 393 | col2.pop(); |
molorvida3 | 0:159d50728af0 | 394 | destSize = col3.size(); |
molorvida3 | 0:159d50728af0 | 395 | ringNum = col3.top(); |
molorvida3 | 0:159d50728af0 | 396 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 397 | } |
molorvida3 | 0:159d50728af0 | 398 | } |
molorvida3 | 0:159d50728af0 | 399 | break; |
molorvida3 | 0:159d50728af0 | 400 | |
molorvida3 | 0:159d50728af0 | 401 | case 3: |
molorvida3 | 0:159d50728af0 | 402 | sourceSize = col3.size(); |
molorvida3 | 0:159d50728af0 | 403 | if (sourceSize == 0) |
molorvida3 | 0:159d50728af0 | 404 | break; |
molorvida3 | 0:159d50728af0 | 405 | if ( destination == 1) { |
molorvida3 | 0:159d50728af0 | 406 | if ( col1.empty()) { |
molorvida3 | 0:159d50728af0 | 407 | col1.push(col3.top()); |
molorvida3 | 0:159d50728af0 | 408 | col3.pop(); |
molorvida3 | 0:159d50728af0 | 409 | destSize = col1.size(); |
molorvida3 | 0:159d50728af0 | 410 | ringNum = col1.top(); |
molorvida3 | 0:159d50728af0 | 411 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 412 | } else if ( col3.top() < col1.top()) { |
molorvida3 | 0:159d50728af0 | 413 | col1.push(col3.top()); |
molorvida3 | 0:159d50728af0 | 414 | col3.pop(); |
molorvida3 | 0:159d50728af0 | 415 | destSize = col1.size(); |
molorvida3 | 0:159d50728af0 | 416 | ringNum = col1.top(); |
molorvida3 | 0:159d50728af0 | 417 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 418 | } |
molorvida3 | 0:159d50728af0 | 419 | } |
molorvida3 | 0:159d50728af0 | 420 | |
molorvida3 | 0:159d50728af0 | 421 | else if ( destination == 2) { |
molorvida3 | 0:159d50728af0 | 422 | if (col2.empty()) { |
molorvida3 | 0:159d50728af0 | 423 | col2.push(col3.top()); |
molorvida3 | 0:159d50728af0 | 424 | col3.pop(); |
molorvida3 | 0:159d50728af0 | 425 | destSize = col2.size(); |
molorvida3 | 0:159d50728af0 | 426 | ringNum = col2.top(); |
molorvida3 | 0:159d50728af0 | 427 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 428 | } |
molorvida3 | 0:159d50728af0 | 429 | |
molorvida3 | 0:159d50728af0 | 430 | else if ( col3.top() < col2.top()) { |
molorvida3 | 0:159d50728af0 | 431 | col2.push(col3.top()); |
molorvida3 | 0:159d50728af0 | 432 | col3.pop(); |
molorvida3 | 0:159d50728af0 | 433 | destSize = col2.size(); |
molorvida3 | 0:159d50728af0 | 434 | ringNum = col2.top(); |
molorvida3 | 0:159d50728af0 | 435 | drawMove(sourceSize, destSize, ringNum); |
molorvida3 | 0:159d50728af0 | 436 | } |
molorvida3 | 0:159d50728af0 | 437 | } |
molorvida3 | 0:159d50728af0 | 438 | break; |
molorvida3 | 0:159d50728af0 | 439 | |
molorvida3 | 0:159d50728af0 | 440 | |
molorvida3 | 0:159d50728af0 | 441 | } |
molorvida3 | 0:159d50728af0 | 442 | |
molorvida3 | 0:159d50728af0 | 443 | |
molorvida3 | 0:159d50728af0 | 444 | |
molorvida3 | 0:159d50728af0 | 445 | |
molorvida3 | 0:159d50728af0 | 446 | |
molorvida3 | 0:159d50728af0 | 447 | } |
molorvida3 | 0:159d50728af0 | 448 | |
molorvida3 | 0:159d50728af0 | 449 | void drawMove( int sourceSize, int destSize, int numRing ) |
molorvida3 | 0:159d50728af0 | 450 | { |
molorvida3 | 0:159d50728af0 | 451 | |
molorvida3 | 0:159d50728af0 | 452 | int x1Source = 32 * source - 2*numRing; |
molorvida3 | 0:159d50728af0 | 453 | int y1Source = 35 + 12*(5- sourceSize) - 1; |
molorvida3 | 0:159d50728af0 | 454 | int x2Source = 32 * source + 2*numRing; |
molorvida3 | 0:159d50728af0 | 455 | int y2Source = 35 + 12*(5- sourceSize); |
molorvida3 | 0:159d50728af0 | 456 | |
molorvida3 | 0:159d50728af0 | 457 | int x1Dest = 32 * destination - 2*numRing; |
molorvida3 | 0:159d50728af0 | 458 | int y1Dest = 35 + 12*(5-destSize) - 1; |
molorvida3 | 0:159d50728af0 | 459 | int x2Dest = 32 * destination + 2*numRing; |
molorvida3 | 0:159d50728af0 | 460 | int y2Dest = 35 + 12*(5- destSize); |
molorvida3 | 0:159d50728af0 | 461 | |
molorvida3 | 0:159d50728af0 | 462 | |
molorvida3 | 0:159d50728af0 | 463 | switch (numRing) { |
molorvida3 | 0:159d50728af0 | 464 | case 1 : |
molorvida3 | 0:159d50728af0 | 465 | uLCD.filled_rectangle(x1Dest, y1Dest, x2Dest, y2Dest, RED); |
molorvida3 | 0:159d50728af0 | 466 | //uLCD.filled_rectangle(x1Dest, 35+12*4-1, x2Dest, 35+12*4, RED); |
molorvida3 | 0:159d50728af0 | 467 | break; |
molorvida3 | 0:159d50728af0 | 468 | case 2 : |
molorvida3 | 0:159d50728af0 | 469 | uLCD.filled_rectangle(x1Dest, y1Dest, x2Dest, y2Dest, ORANGE); |
molorvida3 | 0:159d50728af0 | 470 | break; |
molorvida3 | 0:159d50728af0 | 471 | case 3 : |
molorvida3 | 0:159d50728af0 | 472 | uLCD.filled_rectangle(x1Dest, y1Dest, x2Dest, y2Dest, YELLOW); |
molorvida3 | 0:159d50728af0 | 473 | break; |
molorvida3 | 0:159d50728af0 | 474 | case 4 : |
molorvida3 | 0:159d50728af0 | 475 | uLCD.filled_rectangle(x1Dest, y1Dest, x2Dest, y2Dest, GREEN); |
molorvida3 | 0:159d50728af0 | 476 | break; |
molorvida3 | 0:159d50728af0 | 477 | } |
molorvida3 | 0:159d50728af0 | 478 | |
molorvida3 | 0:159d50728af0 | 479 | uLCD.filled_rectangle(x1Source, y1Source, x2Source, y2Source, BLACK); |
molorvida3 | 0:159d50728af0 | 480 | |
molorvida3 | 0:159d50728af0 | 481 | } |
molorvida3 | 0:159d50728af0 | 482 | |
molorvida3 | 0:159d50728af0 | 483 | |
molorvida3 | 0:159d50728af0 | 484 | |
molorvida3 | 0:159d50728af0 | 485 | |
molorvida3 | 0:159d50728af0 | 486 | |
molorvida3 | 0:159d50728af0 | 487 | |
molorvida3 | 0:159d50728af0 | 488 | |
molorvida3 | 0:159d50728af0 | 489 | bool checkVictory() |
molorvida3 | 0:159d50728af0 | 490 | { |
molorvida3 | 0:159d50728af0 | 491 | return (col3.size() == numRings or col2.size() == numRings); // if column 3 has all the rings game is done. This should only be possible if it's correct |
molorvida3 | 0:159d50728af0 | 492 | } |
molorvida3 | 0:159d50728af0 | 493 | |
molorvida3 | 0:159d50728af0 | 494 | void drawCursor(int columnX, int color) //columnX = x-coordinate of column, color |
molorvida3 | 0:159d50728af0 | 495 | { |
molorvida3 | 0:159d50728af0 | 496 | //draws a 9 pixel triangle(5 on 1 row, 3 on row 2, 1 on row 3) |
molorvida3 | 0:159d50728af0 | 497 | uLCD.pixel(columnX,30,color); |
molorvida3 | 0:159d50728af0 | 498 | uLCD.pixel(columnX-1,29,color); |
molorvida3 | 0:159d50728af0 | 499 | uLCD.pixel(columnX,29,color); |
molorvida3 | 0:159d50728af0 | 500 | uLCD.pixel(columnX+1,29,color); |
molorvida3 | 0:159d50728af0 | 501 | uLCD.pixel(columnX-2,28,color); |
molorvida3 | 0:159d50728af0 | 502 | uLCD.pixel(columnX-1,28,color); |
molorvida3 | 0:159d50728af0 | 503 | uLCD.pixel(columnX,28,color); |
molorvida3 | 0:159d50728af0 | 504 | uLCD.pixel(columnX+1,28,color); |
molorvida3 | 0:159d50728af0 | 505 | uLCD.pixel(columnX+2,28,color); |
molorvida3 | 0:159d50728af0 | 506 | } |
molorvida3 | 0:159d50728af0 | 507 | |
molorvida3 | 0:159d50728af0 | 508 | void drawSourceSelect() |
molorvida3 | 0:159d50728af0 | 509 | { |
molorvida3 | 0:159d50728af0 | 510 | uLCD.filled_circle(32, 110, 2, BLUE); |
molorvida3 | 0:159d50728af0 | 511 | uLCD.filled_circle(64, 110, 2, BLUE); |
molorvida3 | 0:159d50728af0 | 512 | uLCD.filled_circle(96, 110, 2, BLUE); |
molorvida3 | 0:159d50728af0 | 513 | if (source == 1 ) |
molorvida3 | 0:159d50728af0 | 514 | uLCD.filled_circle(32, 110, 2, RED); |
molorvida3 | 0:159d50728af0 | 515 | else if ( source == 2 ) |
molorvida3 | 0:159d50728af0 | 516 | uLCD.filled_circle(64, 110, 2, RED); |
molorvida3 | 0:159d50728af0 | 517 | else if (source == 3 ) |
molorvida3 | 0:159d50728af0 | 518 | uLCD.filled_circle(96, 110, 2, RED); |
molorvida3 | 0:159d50728af0 | 519 | wait(.3); |
molorvida3 | 0:159d50728af0 | 520 | } |
molorvida3 | 0:159d50728af0 | 521 | |
molorvida3 | 0:159d50728af0 | 522 | void drawDestinationSelect() // also changes cursor global to new destination |
molorvida3 | 0:159d50728af0 | 523 | { |
molorvida3 | 0:159d50728af0 | 524 | drawCursor( cursor*32, BLACK); |
molorvida3 | 0:159d50728af0 | 525 | drawCursor( destination*32, YELLOW); |
molorvida3 | 0:159d50728af0 | 526 | cursor = destination; |
molorvida3 | 0:159d50728af0 | 527 | wait(.3); |
molorvida3 | 0:159d50728af0 | 528 | } |