Multi-game multiplayer arcade gaming system meant for the red X when playing Super Tic-Tac-Toe.
Dependencies: uLCD_4DGL_SE PinDetect SDFileSystem mbed wave_player
RedX.h@2:d35fde2d82cd, 2015-12-04 (annotated)
- Committer:
- soapy12312
- Date:
- Fri Dec 04 23:03:08 2015 +0000
- Revision:
- 2:d35fde2d82cd
Multi-game multiplayer arcade gaming system meant for the red X when playing Super Tic-Tac-Toe.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
soapy12312 | 2:d35fde2d82cd | 1 | /******************************************************* |
soapy12312 | 2:d35fde2d82cd | 2 | * This header program declares all of the functions and |
soapy12312 | 2:d35fde2d82cd | 3 | * variables used by the red X player in Super |
soapy12312 | 2:d35fde2d82cd | 4 | * Tic-Tac-Toe. |
soapy12312 | 2:d35fde2d82cd | 5 | *******************************************************/ |
soapy12312 | 2:d35fde2d82cd | 6 | |
soapy12312 | 2:d35fde2d82cd | 7 | |
soapy12312 | 2:d35fde2d82cd | 8 | #define FORWARDSLASH 0 |
soapy12312 | 2:d35fde2d82cd | 9 | #define BACKWARDSLASH 1 |
soapy12312 | 2:d35fde2d82cd | 10 | #define VERTICAL 2 |
soapy12312 | 2:d35fde2d82cd | 11 | #define HORIZONTAL 3 |
soapy12312 | 2:d35fde2d82cd | 12 | #define BOMB "/sd/wavfiles/bomb.wav" |
soapy12312 | 2:d35fde2d82cd | 13 | #define WIN "/sd/win.wav" |
soapy12312 | 2:d35fde2d82cd | 14 | #define MEH "/sd/Meh.wav" |
soapy12312 | 2:d35fde2d82cd | 15 | |
soapy12312 | 2:d35fde2d82cd | 16 | |
soapy12312 | 2:d35fde2d82cd | 17 | // Smaller Super Tic_Tac_Toe grid structure |
soapy12312 | 2:d35fde2d82cd | 18 | struct smallGrid { |
soapy12312 | 2:d35fde2d82cd | 19 | char individualGrid[3][3]; |
soapy12312 | 2:d35fde2d82cd | 20 | char done; |
soapy12312 | 2:d35fde2d82cd | 21 | }; |
soapy12312 | 2:d35fde2d82cd | 22 | |
soapy12312 | 2:d35fde2d82cd | 23 | // Entire Super Tic_Tac_Toe grid structure |
soapy12312 | 2:d35fde2d82cd | 24 | struct largeGrid { |
soapy12312 | 2:d35fde2d82cd | 25 | smallGrid smallGrid[3][3]; |
soapy12312 | 2:d35fde2d82cd | 26 | char done; |
soapy12312 | 2:d35fde2d82cd | 27 | }; |
soapy12312 | 2:d35fde2d82cd | 28 | |
soapy12312 | 2:d35fde2d82cd | 29 | |
soapy12312 | 2:d35fde2d82cd | 30 | class RedX { |
soapy12312 | 2:d35fde2d82cd | 31 | public: |
soapy12312 | 2:d35fde2d82cd | 32 | // Player X constructor |
soapy12312 | 2:d35fde2d82cd | 33 | RedX(DigitalOut &reset, InterruptIn &input, Mpr121 &MPR121, RGBLED &RGB, SDFileSystem &sd, Serial &XBee, uLCD_4DGL &uLCD, wave_player &waver) : |
soapy12312 | 2:d35fde2d82cd | 34 | reset(reset), input(input), MPR121(MPR121), RGB(RGB), sd(sd), XBee(XBee), uLCD(uLCD), waver(waver) { |
soapy12312 | 2:d35fde2d82cd | 35 | uLCD.baudrate(MAXBAUDRATE); |
soapy12312 | 2:d35fde2d82cd | 36 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 37 | |
soapy12312 | 2:d35fde2d82cd | 38 | // Set up XBee |
soapy12312 | 2:d35fde2d82cd | 39 | reset = 0; |
soapy12312 | 2:d35fde2d82cd | 40 | wait(0.001); |
soapy12312 | 2:d35fde2d82cd | 41 | reset = 1; |
soapy12312 | 2:d35fde2d82cd | 42 | wait(0.001); |
soapy12312 | 2:d35fde2d82cd | 43 | } |
soapy12312 | 2:d35fde2d82cd | 44 | |
soapy12312 | 2:d35fde2d82cd | 45 | void playSuperTicTacToe() { |
soapy12312 | 2:d35fde2d82cd | 46 | initializeInterrupt(); |
soapy12312 | 2:d35fde2d82cd | 47 | displayInstructions(); |
soapy12312 | 2:d35fde2d82cd | 48 | initializeGrid(); |
soapy12312 | 2:d35fde2d82cd | 49 | |
soapy12312 | 2:d35fde2d82cd | 50 | XBee.putc(true); |
soapy12312 | 2:d35fde2d82cd | 51 | bool readyToPlay = false; |
soapy12312 | 2:d35fde2d82cd | 52 | bool print = true; |
soapy12312 | 2:d35fde2d82cd | 53 | |
soapy12312 | 2:d35fde2d82cd | 54 | while (readyToPlay == false) { |
soapy12312 | 2:d35fde2d82cd | 55 | if (XBee.readable() == true) { |
soapy12312 | 2:d35fde2d82cd | 56 | readyToPlay = XBee.getc(); |
soapy12312 | 2:d35fde2d82cd | 57 | print = false; |
soapy12312 | 2:d35fde2d82cd | 58 | } |
soapy12312 | 2:d35fde2d82cd | 59 | |
soapy12312 | 2:d35fde2d82cd | 60 | if (print == true) { |
soapy12312 | 2:d35fde2d82cd | 61 | uLCD.cls(); |
soapy12312 | 2:d35fde2d82cd | 62 | uLCD.printf("Waiting for other player..."); |
soapy12312 | 2:d35fde2d82cd | 63 | print = false; |
soapy12312 | 2:d35fde2d82cd | 64 | } |
soapy12312 | 2:d35fde2d82cd | 65 | } |
soapy12312 | 2:d35fde2d82cd | 66 | |
soapy12312 | 2:d35fde2d82cd | 67 | uLCD.cls(); |
soapy12312 | 2:d35fde2d82cd | 68 | drawStage(); |
soapy12312 | 2:d35fde2d82cd | 69 | |
soapy12312 | 2:d35fde2d82cd | 70 | // False: player one's turn; true: player two's turn |
soapy12312 | 2:d35fde2d82cd | 71 | bool turn = true; |
soapy12312 | 2:d35fde2d82cd | 72 | |
soapy12312 | 2:d35fde2d82cd | 73 | // Loop through the game |
soapy12312 | 2:d35fde2d82cd | 74 | while (grid.done == (char)(-1)) { |
soapy12312 | 2:d35fde2d82cd | 75 | turn = !turn; |
soapy12312 | 2:d35fde2d82cd | 76 | takeTurn(turn); |
soapy12312 | 2:d35fde2d82cd | 77 | gameWin(turn); |
soapy12312 | 2:d35fde2d82cd | 78 | } |
soapy12312 | 2:d35fde2d82cd | 79 | |
soapy12312 | 2:d35fde2d82cd | 80 | uLCD.cls(); |
soapy12312 | 2:d35fde2d82cd | 81 | |
soapy12312 | 2:d35fde2d82cd | 82 | if (grid.done == 0) { |
soapy12312 | 2:d35fde2d82cd | 83 | uLCD.printf("You win!"); |
soapy12312 | 2:d35fde2d82cd | 84 | playSound(WIN); |
soapy12312 | 2:d35fde2d82cd | 85 | } else if (grid.done == 1) { |
soapy12312 | 2:d35fde2d82cd | 86 | uLCD.printf("The other player\nwins."); |
soapy12312 | 2:d35fde2d82cd | 87 | playSound(BOMB); |
soapy12312 | 2:d35fde2d82cd | 88 | } else if (grid.done == 128) { |
soapy12312 | 2:d35fde2d82cd | 89 | uLCD.printf("It's a draw!"); |
soapy12312 | 2:d35fde2d82cd | 90 | playSound(MEH); |
soapy12312 | 2:d35fde2d82cd | 91 | } |
soapy12312 | 2:d35fde2d82cd | 92 | |
soapy12312 | 2:d35fde2d82cd | 93 | wait(3); |
soapy12312 | 2:d35fde2d82cd | 94 | uLCD.cls(); |
soapy12312 | 2:d35fde2d82cd | 95 | } |
soapy12312 | 2:d35fde2d82cd | 96 | |
soapy12312 | 2:d35fde2d82cd | 97 | |
soapy12312 | 2:d35fde2d82cd | 98 | private: |
soapy12312 | 2:d35fde2d82cd | 99 | DigitalOut &reset; |
soapy12312 | 2:d35fde2d82cd | 100 | InterruptIn &input; |
soapy12312 | 2:d35fde2d82cd | 101 | Mpr121 &MPR121; |
soapy12312 | 2:d35fde2d82cd | 102 | RGBLED &RGB; |
soapy12312 | 2:d35fde2d82cd | 103 | SDFileSystem &sd; |
soapy12312 | 2:d35fde2d82cd | 104 | Serial &XBee; |
soapy12312 | 2:d35fde2d82cd | 105 | uLCD_4DGL &uLCD; |
soapy12312 | 2:d35fde2d82cd | 106 | wave_player &waver; |
soapy12312 | 2:d35fde2d82cd | 107 | bool keyAllowed; |
soapy12312 | 2:d35fde2d82cd | 108 | volatile int key; |
soapy12312 | 2:d35fde2d82cd | 109 | largeGrid grid; |
soapy12312 | 2:d35fde2d82cd | 110 | |
soapy12312 | 2:d35fde2d82cd | 111 | // Initialize the interrupt |
soapy12312 | 2:d35fde2d82cd | 112 | void initializeInterrupt() { |
soapy12312 | 2:d35fde2d82cd | 113 | input.fall(this, &RedX::keyInterrupt); |
soapy12312 | 2:d35fde2d82cd | 114 | wait(0.01); |
soapy12312 | 2:d35fde2d82cd | 115 | input.mode(PullUp); |
soapy12312 | 2:d35fde2d82cd | 116 | wait(0.01); |
soapy12312 | 2:d35fde2d82cd | 117 | } |
soapy12312 | 2:d35fde2d82cd | 118 | |
soapy12312 | 2:d35fde2d82cd | 119 | // Determine value of the key pressed |
soapy12312 | 2:d35fde2d82cd | 120 | void keyInterrupt() { |
soapy12312 | 2:d35fde2d82cd | 121 | if (keyAllowed == true) { |
soapy12312 | 2:d35fde2d82cd | 122 | int value = MPR121.read(0x00); |
soapy12312 | 2:d35fde2d82cd | 123 | value += MPR121.read(0x01) << 8; |
soapy12312 | 2:d35fde2d82cd | 124 | |
soapy12312 | 2:d35fde2d82cd | 125 | for (int i = 0; i < 12; i++) { |
soapy12312 | 2:d35fde2d82cd | 126 | if (((value >> i) & 0x01) == 1) { |
soapy12312 | 2:d35fde2d82cd | 127 | key = i; |
soapy12312 | 2:d35fde2d82cd | 128 | } |
soapy12312 | 2:d35fde2d82cd | 129 | } |
soapy12312 | 2:d35fde2d82cd | 130 | |
soapy12312 | 2:d35fde2d82cd | 131 | // Ununsed keys |
soapy12312 | 2:d35fde2d82cd | 132 | if ((key == 3) || (key == 7) || (key == 11)) { |
soapy12312 | 2:d35fde2d82cd | 133 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 134 | } |
soapy12312 | 2:d35fde2d82cd | 135 | } else { |
soapy12312 | 2:d35fde2d82cd | 136 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 137 | } |
soapy12312 | 2:d35fde2d82cd | 138 | } |
soapy12312 | 2:d35fde2d82cd | 139 | |
soapy12312 | 2:d35fde2d82cd | 140 | // Initialize the grid |
soapy12312 | 2:d35fde2d82cd | 141 | void initializeGrid() { |
soapy12312 | 2:d35fde2d82cd | 142 | grid.done = (char)(-1); |
soapy12312 | 2:d35fde2d82cd | 143 | |
soapy12312 | 2:d35fde2d82cd | 144 | for (int i = 0; i < 3; i++) { |
soapy12312 | 2:d35fde2d82cd | 145 | for (int j = 0; j < 3; j++) { |
soapy12312 | 2:d35fde2d82cd | 146 | grid.smallGrid[i][j].done = (char)(-1); |
soapy12312 | 2:d35fde2d82cd | 147 | |
soapy12312 | 2:d35fde2d82cd | 148 | for (int k = 0; k < 3; k++) { |
soapy12312 | 2:d35fde2d82cd | 149 | for (int l = 0; l < 3; l++) { |
soapy12312 | 2:d35fde2d82cd | 150 | grid.smallGrid[i][j].individualGrid[k][l] = (char)(-1); |
soapy12312 | 2:d35fde2d82cd | 151 | } |
soapy12312 | 2:d35fde2d82cd | 152 | } |
soapy12312 | 2:d35fde2d82cd | 153 | } |
soapy12312 | 2:d35fde2d82cd | 154 | } |
soapy12312 | 2:d35fde2d82cd | 155 | } |
soapy12312 | 2:d35fde2d82cd | 156 | |
soapy12312 | 2:d35fde2d82cd | 157 | // Display instructions |
soapy12312 | 2:d35fde2d82cd | 158 | void displayInstructions() { |
soapy12312 | 2:d35fde2d82cd | 159 | uLCD.printf("Hello, and welcome"); |
soapy12312 | 2:d35fde2d82cd | 160 | uLCD.printf("to a game of Super"); |
soapy12312 | 2:d35fde2d82cd | 161 | uLCD.printf("Tic-Tac-Toe. Use "); |
soapy12312 | 2:d35fde2d82cd | 162 | uLCD.printf("the bottom three "); |
soapy12312 | 2:d35fde2d82cd | 163 | uLCD.printf("rows of the touch "); |
soapy12312 | 2:d35fde2d82cd | 164 | uLCD.printf("keypad to select "); |
soapy12312 | 2:d35fde2d82cd | 165 | uLCD.printf("the large grid "); |
soapy12312 | 2:d35fde2d82cd | 166 | uLCD.printf("followed by the "); |
soapy12312 | 2:d35fde2d82cd | 167 | uLCD.printf("small grid. You "); |
soapy12312 | 2:d35fde2d82cd | 168 | uLCD.printf("are the red X.\n\n"); |
soapy12312 | 2:d35fde2d82cd | 169 | uLCD.printf("Press any key to "); |
soapy12312 | 2:d35fde2d82cd | 170 | uLCD.printf("begin playing."); |
soapy12312 | 2:d35fde2d82cd | 171 | wait(0.1); |
soapy12312 | 2:d35fde2d82cd | 172 | |
soapy12312 | 2:d35fde2d82cd | 173 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 174 | keyAllowed = true; |
soapy12312 | 2:d35fde2d82cd | 175 | |
soapy12312 | 2:d35fde2d82cd | 176 | while (key == -1) { |
soapy12312 | 2:d35fde2d82cd | 177 | wait(0.01); |
soapy12312 | 2:d35fde2d82cd | 178 | } |
soapy12312 | 2:d35fde2d82cd | 179 | |
soapy12312 | 2:d35fde2d82cd | 180 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 181 | uLCD.cls(); |
soapy12312 | 2:d35fde2d82cd | 182 | } |
soapy12312 | 2:d35fde2d82cd | 183 | |
soapy12312 | 2:d35fde2d82cd | 184 | // Play a sound file |
soapy12312 | 2:d35fde2d82cd | 185 | void playSound(char *wav) { |
soapy12312 | 2:d35fde2d82cd | 186 | // Open sound file |
soapy12312 | 2:d35fde2d82cd | 187 | FILE *wave_file; |
soapy12312 | 2:d35fde2d82cd | 188 | wave_file = fopen(wav, "r"); |
soapy12312 | 2:d35fde2d82cd | 189 | |
soapy12312 | 2:d35fde2d82cd | 190 | // Play wav file |
soapy12312 | 2:d35fde2d82cd | 191 | waver.play(wave_file); |
soapy12312 | 2:d35fde2d82cd | 192 | |
soapy12312 | 2:d35fde2d82cd | 193 | // Close wav file |
soapy12312 | 2:d35fde2d82cd | 194 | fclose(wave_file); |
soapy12312 | 2:d35fde2d82cd | 195 | } |
soapy12312 | 2:d35fde2d82cd | 196 | |
soapy12312 | 2:d35fde2d82cd | 197 | // Draw the stage |
soapy12312 | 2:d35fde2d82cd | 198 | void drawStage() { |
soapy12312 | 2:d35fde2d82cd | 199 | for (int i = 15; i < 120; i += 14) { |
soapy12312 | 2:d35fde2d82cd | 200 | uLCD.line(i, 2, i, 127, YELLOW); |
soapy12312 | 2:d35fde2d82cd | 201 | uLCD.line(2, i, 127, i, YELLOW); |
soapy12312 | 2:d35fde2d82cd | 202 | } |
soapy12312 | 2:d35fde2d82cd | 203 | |
soapy12312 | 2:d35fde2d82cd | 204 | for (int i = 43; i < 120; i += 42) { |
soapy12312 | 2:d35fde2d82cd | 205 | uLCD.line(i, 2, i, 127, WHITE); |
soapy12312 | 2:d35fde2d82cd | 206 | uLCD.line(2, i, 127, i, WHITE); |
soapy12312 | 2:d35fde2d82cd | 207 | } |
soapy12312 | 2:d35fde2d82cd | 208 | } |
soapy12312 | 2:d35fde2d82cd | 209 | |
soapy12312 | 2:d35fde2d82cd | 210 | // Draw small X |
soapy12312 | 2:d35fde2d82cd | 211 | void drawSmallX(int largeX, int largeY, int smallX, int smallY) { |
soapy12312 | 2:d35fde2d82cd | 212 | int xCoordinate = 1 + (largeX * 42) + (smallX * 14) + 7; |
soapy12312 | 2:d35fde2d82cd | 213 | int yCoordinate = 1 + (largeY * 42) + (smallY * 14) + 7; |
soapy12312 | 2:d35fde2d82cd | 214 | |
soapy12312 | 2:d35fde2d82cd | 215 | int x1 = xCoordinate - 6; |
soapy12312 | 2:d35fde2d82cd | 216 | int x2 = xCoordinate + 6; |
soapy12312 | 2:d35fde2d82cd | 217 | int y1 = yCoordinate - 6; |
soapy12312 | 2:d35fde2d82cd | 218 | int y2 = yCoordinate + 6; |
soapy12312 | 2:d35fde2d82cd | 219 | |
soapy12312 | 2:d35fde2d82cd | 220 | uLCD.line(x1 + 1, y1 + 1, x2, y2, RED); |
soapy12312 | 2:d35fde2d82cd | 221 | uLCD.line(x1 + 1, y2 - 1, x2, y1, RED); |
soapy12312 | 2:d35fde2d82cd | 222 | } |
soapy12312 | 2:d35fde2d82cd | 223 | |
soapy12312 | 2:d35fde2d82cd | 224 | // Draw small O |
soapy12312 | 2:d35fde2d82cd | 225 | void drawSmallO(int largeX, int largeY, int smallX, int smallY) { |
soapy12312 | 2:d35fde2d82cd | 226 | int xCoordinate = 1 + (largeX * 42) + (smallX * 14) + 7; |
soapy12312 | 2:d35fde2d82cd | 227 | int yCoordinate = 1 + (largeY * 42) + (smallY * 14) + 7; |
soapy12312 | 2:d35fde2d82cd | 228 | |
soapy12312 | 2:d35fde2d82cd | 229 | uLCD.circle(xCoordinate, yCoordinate, 5, BLUE); |
soapy12312 | 2:d35fde2d82cd | 230 | } |
soapy12312 | 2:d35fde2d82cd | 231 | |
soapy12312 | 2:d35fde2d82cd | 232 | // Draw large X |
soapy12312 | 2:d35fde2d82cd | 233 | void drawLargeX(int largeX, int largeY) { |
soapy12312 | 2:d35fde2d82cd | 234 | int xCoordinate = 1 + (largeX * 42) + 21; |
soapy12312 | 2:d35fde2d82cd | 235 | int yCoordinate = 1 + (largeY * 42) + 21; |
soapy12312 | 2:d35fde2d82cd | 236 | |
soapy12312 | 2:d35fde2d82cd | 237 | int x1 = xCoordinate - 20; |
soapy12312 | 2:d35fde2d82cd | 238 | int x2 = xCoordinate + 20; |
soapy12312 | 2:d35fde2d82cd | 239 | int y1 = yCoordinate - 20; |
soapy12312 | 2:d35fde2d82cd | 240 | int y2 = yCoordinate + 20; |
soapy12312 | 2:d35fde2d82cd | 241 | |
soapy12312 | 2:d35fde2d82cd | 242 | uLCD.filled_rectangle(x1, y1, x2, y2, BLACK); |
soapy12312 | 2:d35fde2d82cd | 243 | |
soapy12312 | 2:d35fde2d82cd | 244 | uLCD.line(x1 + 1, y1 + 1, x2, y2, RED); |
soapy12312 | 2:d35fde2d82cd | 245 | uLCD.line(x1 + 1, y2 - 1, x2, y1, RED); |
soapy12312 | 2:d35fde2d82cd | 246 | } |
soapy12312 | 2:d35fde2d82cd | 247 | |
soapy12312 | 2:d35fde2d82cd | 248 | // Draw large O |
soapy12312 | 2:d35fde2d82cd | 249 | void drawLargeO(int largeX, int largeY) { |
soapy12312 | 2:d35fde2d82cd | 250 | int xCoordinate = 1 + (largeX * 42) + 21; |
soapy12312 | 2:d35fde2d82cd | 251 | int yCoordinate = 1 + (largeY * 42) + 21; |
soapy12312 | 2:d35fde2d82cd | 252 | |
soapy12312 | 2:d35fde2d82cd | 253 | int x1 = xCoordinate - 20; |
soapy12312 | 2:d35fde2d82cd | 254 | int x2 = xCoordinate + 20; |
soapy12312 | 2:d35fde2d82cd | 255 | int y1 = yCoordinate - 20; |
soapy12312 | 2:d35fde2d82cd | 256 | int y2 = yCoordinate + 20; |
soapy12312 | 2:d35fde2d82cd | 257 | |
soapy12312 | 2:d35fde2d82cd | 258 | uLCD.filled_rectangle(x1, y1, x2, y2, BLACK); |
soapy12312 | 2:d35fde2d82cd | 259 | |
soapy12312 | 2:d35fde2d82cd | 260 | uLCD.circle(xCoordinate, yCoordinate, 19, BLUE); |
soapy12312 | 2:d35fde2d82cd | 261 | } |
soapy12312 | 2:d35fde2d82cd | 262 | |
soapy12312 | 2:d35fde2d82cd | 263 | // Find x-coordinate based on key input |
soapy12312 | 2:d35fde2d82cd | 264 | int xGrid() { |
soapy12312 | 2:d35fde2d82cd | 265 | int x; |
soapy12312 | 2:d35fde2d82cd | 266 | |
soapy12312 | 2:d35fde2d82cd | 267 | if ((key == 0) || (key == 1) || (key == 2)) { |
soapy12312 | 2:d35fde2d82cd | 268 | x = 0; |
soapy12312 | 2:d35fde2d82cd | 269 | } else if ((key == 4) || (key == 5) || (key == 6)) { |
soapy12312 | 2:d35fde2d82cd | 270 | x = 1; |
soapy12312 | 2:d35fde2d82cd | 271 | } else if ((key == 8) || (key == 9) || (key == 10)) { |
soapy12312 | 2:d35fde2d82cd | 272 | x = 2; |
soapy12312 | 2:d35fde2d82cd | 273 | } else { |
soapy12312 | 2:d35fde2d82cd | 274 | x = -1; |
soapy12312 | 2:d35fde2d82cd | 275 | } |
soapy12312 | 2:d35fde2d82cd | 276 | |
soapy12312 | 2:d35fde2d82cd | 277 | return x; |
soapy12312 | 2:d35fde2d82cd | 278 | } |
soapy12312 | 2:d35fde2d82cd | 279 | |
soapy12312 | 2:d35fde2d82cd | 280 | // Find y-coordinate based on key input |
soapy12312 | 2:d35fde2d82cd | 281 | int yGrid() { |
soapy12312 | 2:d35fde2d82cd | 282 | int y; |
soapy12312 | 2:d35fde2d82cd | 283 | |
soapy12312 | 2:d35fde2d82cd | 284 | if ((key == 2) || (key == 6) || (key == 10)) { |
soapy12312 | 2:d35fde2d82cd | 285 | y = 0; |
soapy12312 | 2:d35fde2d82cd | 286 | } else if ((key == 1) || (key == 5) || (key == 9)) { |
soapy12312 | 2:d35fde2d82cd | 287 | y = 1; |
soapy12312 | 2:d35fde2d82cd | 288 | } else if ((key == 0) || (key == 4) || (key == 8)) { |
soapy12312 | 2:d35fde2d82cd | 289 | y = 2; |
soapy12312 | 2:d35fde2d82cd | 290 | } else { |
soapy12312 | 2:d35fde2d82cd | 291 | y = -1; |
soapy12312 | 2:d35fde2d82cd | 292 | } |
soapy12312 | 2:d35fde2d82cd | 293 | |
soapy12312 | 2:d35fde2d82cd | 294 | return y; |
soapy12312 | 2:d35fde2d82cd | 295 | } |
soapy12312 | 2:d35fde2d82cd | 296 | |
soapy12312 | 2:d35fde2d82cd | 297 | // Display a certain small grid in a set color |
soapy12312 | 2:d35fde2d82cd | 298 | void drawSmallGrid(int x, int y, int color) { |
soapy12312 | 2:d35fde2d82cd | 299 | int x1 = 1 + (x * 42) + 1; |
soapy12312 | 2:d35fde2d82cd | 300 | int x2 = x1 + 40; |
soapy12312 | 2:d35fde2d82cd | 301 | int y1 = 1 + (y * 42) + 1; |
soapy12312 | 2:d35fde2d82cd | 302 | int y2 = y1 + 40; |
soapy12312 | 2:d35fde2d82cd | 303 | |
soapy12312 | 2:d35fde2d82cd | 304 | for (int i = x1; i < x2; i += 14) { |
soapy12312 | 2:d35fde2d82cd | 305 | for (int j = y1; j < y2; j += 14) { |
soapy12312 | 2:d35fde2d82cd | 306 | uLCD.filled_rectangle(i, j, i + 12, j + 12, color); |
soapy12312 | 2:d35fde2d82cd | 307 | } |
soapy12312 | 2:d35fde2d82cd | 308 | } |
soapy12312 | 2:d35fde2d82cd | 309 | |
soapy12312 | 2:d35fde2d82cd | 310 | for (int i = 0; i < 3; i++) { |
soapy12312 | 2:d35fde2d82cd | 311 | for (int j = 0; j < 3; j++) { |
soapy12312 | 2:d35fde2d82cd | 312 | if (grid.smallGrid[x][y].individualGrid[i][j] == 0) { |
soapy12312 | 2:d35fde2d82cd | 313 | drawSmallX(x, y, i, j); |
soapy12312 | 2:d35fde2d82cd | 314 | } else if (grid.smallGrid[x][y].individualGrid[i][j] == 1) { |
soapy12312 | 2:d35fde2d82cd | 315 | drawSmallO(x, y, i, j); |
soapy12312 | 2:d35fde2d82cd | 316 | } |
soapy12312 | 2:d35fde2d82cd | 317 | } |
soapy12312 | 2:d35fde2d82cd | 318 | } |
soapy12312 | 2:d35fde2d82cd | 319 | } |
soapy12312 | 2:d35fde2d82cd | 320 | |
soapy12312 | 2:d35fde2d82cd | 321 | // Draw a line if a player takes a small grid |
soapy12312 | 2:d35fde2d82cd | 322 | void drawSmallWinLine(int x1, int y1, int orientation) { |
soapy12312 | 2:d35fde2d82cd | 323 | int x2 = x1; |
soapy12312 | 2:d35fde2d82cd | 324 | int y2 = y1; |
soapy12312 | 2:d35fde2d82cd | 325 | |
soapy12312 | 2:d35fde2d82cd | 326 | if (orientation == FORWARDSLASH) { |
soapy12312 | 2:d35fde2d82cd | 327 | x2 = x1 - 41; |
soapy12312 | 2:d35fde2d82cd | 328 | y2 = y1 + 41; |
soapy12312 | 2:d35fde2d82cd | 329 | } else if (orientation == BACKWARDSLASH) { |
soapy12312 | 2:d35fde2d82cd | 330 | x2 = x1 + 41; |
soapy12312 | 2:d35fde2d82cd | 331 | y2 = y1 + 41; |
soapy12312 | 2:d35fde2d82cd | 332 | } else if (orientation == VERTICAL) { |
soapy12312 | 2:d35fde2d82cd | 333 | y2 = y1 + 41; |
soapy12312 | 2:d35fde2d82cd | 334 | } else if (orientation == HORIZONTAL) { |
soapy12312 | 2:d35fde2d82cd | 335 | x2 = x1 + 41; |
soapy12312 | 2:d35fde2d82cd | 336 | } |
soapy12312 | 2:d35fde2d82cd | 337 | |
soapy12312 | 2:d35fde2d82cd | 338 | uLCD.line(x1, y1, x2, y2, GREEN); |
soapy12312 | 2:d35fde2d82cd | 339 | wait(1); |
soapy12312 | 2:d35fde2d82cd | 340 | } |
soapy12312 | 2:d35fde2d82cd | 341 | |
soapy12312 | 2:d35fde2d82cd | 342 | // Check whether a player has taken a small grid |
soapy12312 | 2:d35fde2d82cd | 343 | bool smallGridWin(int largeX, int largeY, int smallX, int smallY) { |
soapy12312 | 2:d35fde2d82cd | 344 | bool taken = false; |
soapy12312 | 2:d35fde2d82cd | 345 | char individual[3][3]; |
soapy12312 | 2:d35fde2d82cd | 346 | |
soapy12312 | 2:d35fde2d82cd | 347 | for (int i = 0; i < 3; i++) { |
soapy12312 | 2:d35fde2d82cd | 348 | for (int j = 0; j < 3; j++) { |
soapy12312 | 2:d35fde2d82cd | 349 | individual[i][j] = grid.smallGrid[largeX][largeY].individualGrid[i][j]; |
soapy12312 | 2:d35fde2d82cd | 350 | } |
soapy12312 | 2:d35fde2d82cd | 351 | } |
soapy12312 | 2:d35fde2d82cd | 352 | |
soapy12312 | 2:d35fde2d82cd | 353 | int x1 = 1 + (largeX * 42) + 1; |
soapy12312 | 2:d35fde2d82cd | 354 | int y1 = 1 + (largeY * 42) + 1; |
soapy12312 | 2:d35fde2d82cd | 355 | int orientation = -1; |
soapy12312 | 2:d35fde2d82cd | 356 | |
soapy12312 | 2:d35fde2d82cd | 357 | if ((individual[0][0] == individual[1][1]) && (individual[1][1] == individual[2][2]) && |
soapy12312 | 2:d35fde2d82cd | 358 | (individual[0][0] != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 359 | orientation = BACKWARDSLASH; |
soapy12312 | 2:d35fde2d82cd | 360 | taken = true; |
soapy12312 | 2:d35fde2d82cd | 361 | } else if ((individual[2][0] == individual[1][1]) && (individual[1][1] == individual[0][2]) && |
soapy12312 | 2:d35fde2d82cd | 362 | (individual[2][0] != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 363 | orientation = FORWARDSLASH; |
soapy12312 | 2:d35fde2d82cd | 364 | x1 += 40; |
soapy12312 | 2:d35fde2d82cd | 365 | taken = true; |
soapy12312 | 2:d35fde2d82cd | 366 | } else if ((individual[0][0] == individual[1][0]) && (individual[1][0] == individual[2][0]) && |
soapy12312 | 2:d35fde2d82cd | 367 | (individual[0][0] != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 368 | orientation = HORIZONTAL; |
soapy12312 | 2:d35fde2d82cd | 369 | y1 += 6; |
soapy12312 | 2:d35fde2d82cd | 370 | taken = true; |
soapy12312 | 2:d35fde2d82cd | 371 | } else if ((individual[0][1] == individual[1][1]) && (individual[1][1] == individual[2][1]) && |
soapy12312 | 2:d35fde2d82cd | 372 | (individual[0][1] != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 373 | orientation = HORIZONTAL; |
soapy12312 | 2:d35fde2d82cd | 374 | y1 += 20; |
soapy12312 | 2:d35fde2d82cd | 375 | taken = true; |
soapy12312 | 2:d35fde2d82cd | 376 | } else if ((individual[0][2] == individual[1][2]) && (individual[1][2] == individual[2][2]) && |
soapy12312 | 2:d35fde2d82cd | 377 | (individual[0][2] != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 378 | orientation = HORIZONTAL; |
soapy12312 | 2:d35fde2d82cd | 379 | y1 += 34; |
soapy12312 | 2:d35fde2d82cd | 380 | taken = true; |
soapy12312 | 2:d35fde2d82cd | 381 | } else if ((individual[0][0] == individual[0][1]) && (individual[0][1] == individual[0][2]) && |
soapy12312 | 2:d35fde2d82cd | 382 | (individual[0][0] != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 383 | orientation = VERTICAL; |
soapy12312 | 2:d35fde2d82cd | 384 | x1 += 6; |
soapy12312 | 2:d35fde2d82cd | 385 | taken = true; |
soapy12312 | 2:d35fde2d82cd | 386 | } else if ((individual[1][0] == individual[1][1]) && (individual[1][1] == individual[1][2]) && |
soapy12312 | 2:d35fde2d82cd | 387 | (individual[1][0] != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 388 | orientation = VERTICAL; |
soapy12312 | 2:d35fde2d82cd | 389 | x1 += 20; |
soapy12312 | 2:d35fde2d82cd | 390 | taken = true; |
soapy12312 | 2:d35fde2d82cd | 391 | } else if ((individual[2][0] == individual[2][1]) && (individual[2][1] == individual[2][2]) && |
soapy12312 | 2:d35fde2d82cd | 392 | (individual[2][0] != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 393 | orientation = VERTICAL; |
soapy12312 | 2:d35fde2d82cd | 394 | x1 += 34; |
soapy12312 | 2:d35fde2d82cd | 395 | taken = true; |
soapy12312 | 2:d35fde2d82cd | 396 | } else { |
soapy12312 | 2:d35fde2d82cd | 397 | orientation = -1; |
soapy12312 | 2:d35fde2d82cd | 398 | taken = false; |
soapy12312 | 2:d35fde2d82cd | 399 | } |
soapy12312 | 2:d35fde2d82cd | 400 | |
soapy12312 | 2:d35fde2d82cd | 401 | // Check to see if there is a draw |
soapy12312 | 2:d35fde2d82cd | 402 | if (taken == false) { |
soapy12312 | 2:d35fde2d82cd | 403 | bool draw = true; |
soapy12312 | 2:d35fde2d82cd | 404 | |
soapy12312 | 2:d35fde2d82cd | 405 | for (int i = 0; i < 3; i++) { |
soapy12312 | 2:d35fde2d82cd | 406 | for (int j = 0; j < 3; j++) { |
soapy12312 | 2:d35fde2d82cd | 407 | if (individual[i][j] != (char)(-1)) { |
soapy12312 | 2:d35fde2d82cd | 408 | draw = false; |
soapy12312 | 2:d35fde2d82cd | 409 | } |
soapy12312 | 2:d35fde2d82cd | 410 | } |
soapy12312 | 2:d35fde2d82cd | 411 | } |
soapy12312 | 2:d35fde2d82cd | 412 | |
soapy12312 | 2:d35fde2d82cd | 413 | if (draw == true) { |
soapy12312 | 2:d35fde2d82cd | 414 | grid.smallGrid[largeX][largeY].done = 128; |
soapy12312 | 2:d35fde2d82cd | 415 | } |
soapy12312 | 2:d35fde2d82cd | 416 | } |
soapy12312 | 2:d35fde2d82cd | 417 | |
soapy12312 | 2:d35fde2d82cd | 418 | drawSmallWinLine(x1, y1, orientation); |
soapy12312 | 2:d35fde2d82cd | 419 | |
soapy12312 | 2:d35fde2d82cd | 420 | return taken; |
soapy12312 | 2:d35fde2d82cd | 421 | } |
soapy12312 | 2:d35fde2d82cd | 422 | |
soapy12312 | 2:d35fde2d82cd | 423 | // Take a turn |
soapy12312 | 2:d35fde2d82cd | 424 | void takeTurn(bool turn) { |
soapy12312 | 2:d35fde2d82cd | 425 | // Player selects small grid, then individual grid |
soapy12312 | 2:d35fde2d82cd | 426 | int keyInputs[2] = {-1, -1}; |
soapy12312 | 2:d35fde2d82cd | 427 | |
soapy12312 | 2:d35fde2d82cd | 428 | // If it is player one's turn |
soapy12312 | 2:d35fde2d82cd | 429 | if (turn == false) { |
soapy12312 | 2:d35fde2d82cd | 430 | RGB = RED; |
soapy12312 | 2:d35fde2d82cd | 431 | |
soapy12312 | 2:d35fde2d82cd | 432 | // Allow user input |
soapy12312 | 2:d35fde2d82cd | 433 | keyAllowed = true; |
soapy12312 | 2:d35fde2d82cd | 434 | |
soapy12312 | 2:d35fde2d82cd | 435 | int largeX = 0; |
soapy12312 | 2:d35fde2d82cd | 436 | int largeY = 0; |
soapy12312 | 2:d35fde2d82cd | 437 | |
soapy12312 | 2:d35fde2d82cd | 438 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 439 | |
soapy12312 | 2:d35fde2d82cd | 440 | // Check if the other player is ready to proceed |
soapy12312 | 2:d35fde2d82cd | 441 | bool ready = false; |
soapy12312 | 2:d35fde2d82cd | 442 | |
soapy12312 | 2:d35fde2d82cd | 443 | while (ready == false) { |
soapy12312 | 2:d35fde2d82cd | 444 | if (XBee.readable() == true) { |
soapy12312 | 2:d35fde2d82cd | 445 | ready = XBee.getc(); |
soapy12312 | 2:d35fde2d82cd | 446 | } |
soapy12312 | 2:d35fde2d82cd | 447 | } |
soapy12312 | 2:d35fde2d82cd | 448 | |
soapy12312 | 2:d35fde2d82cd | 449 | // Wait for player to select small grid |
soapy12312 | 2:d35fde2d82cd | 450 | while ((keyInputs[0] == -1) || (grid.smallGrid[largeX][largeY].done != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 451 | wait(0.01); |
soapy12312 | 2:d35fde2d82cd | 452 | keyInputs[0] = key; |
soapy12312 | 2:d35fde2d82cd | 453 | largeX = xGrid(); |
soapy12312 | 2:d35fde2d82cd | 454 | largeY = yGrid(); |
soapy12312 | 2:d35fde2d82cd | 455 | } |
soapy12312 | 2:d35fde2d82cd | 456 | |
soapy12312 | 2:d35fde2d82cd | 457 | // Send out the small grid value through the XBee |
soapy12312 | 2:d35fde2d82cd | 458 | XBee.putc(keyInputs[0]); |
soapy12312 | 2:d35fde2d82cd | 459 | |
soapy12312 | 2:d35fde2d82cd | 460 | // Highlight selected grid |
soapy12312 | 2:d35fde2d82cd | 461 | drawSmallGrid(largeX, largeY, PINK); |
soapy12312 | 2:d35fde2d82cd | 462 | |
soapy12312 | 2:d35fde2d82cd | 463 | playSound("/sd/select.wav"); |
soapy12312 | 2:d35fde2d82cd | 464 | |
soapy12312 | 2:d35fde2d82cd | 465 | // Allow user input |
soapy12312 | 2:d35fde2d82cd | 466 | keyAllowed = true; |
soapy12312 | 2:d35fde2d82cd | 467 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 468 | |
soapy12312 | 2:d35fde2d82cd | 469 | // Check if the other player is ready to proceed |
soapy12312 | 2:d35fde2d82cd | 470 | ready = false; |
soapy12312 | 2:d35fde2d82cd | 471 | |
soapy12312 | 2:d35fde2d82cd | 472 | while (ready == false) { |
soapy12312 | 2:d35fde2d82cd | 473 | if (XBee.readable() == true) { |
soapy12312 | 2:d35fde2d82cd | 474 | ready = XBee.getc(); |
soapy12312 | 2:d35fde2d82cd | 475 | } |
soapy12312 | 2:d35fde2d82cd | 476 | } |
soapy12312 | 2:d35fde2d82cd | 477 | |
soapy12312 | 2:d35fde2d82cd | 478 | wait(0.5); |
soapy12312 | 2:d35fde2d82cd | 479 | |
soapy12312 | 2:d35fde2d82cd | 480 | // Wait for player to select individual grid |
soapy12312 | 2:d35fde2d82cd | 481 | while (keyInputs[1] == -1) { |
soapy12312 | 2:d35fde2d82cd | 482 | wait(0.01); |
soapy12312 | 2:d35fde2d82cd | 483 | |
soapy12312 | 2:d35fde2d82cd | 484 | if (grid.smallGrid[largeX][largeY].individualGrid[xGrid()][yGrid()] == (char)(-1)) { |
soapy12312 | 2:d35fde2d82cd | 485 | keyInputs[1] = key; |
soapy12312 | 2:d35fde2d82cd | 486 | } |
soapy12312 | 2:d35fde2d82cd | 487 | } |
soapy12312 | 2:d35fde2d82cd | 488 | |
soapy12312 | 2:d35fde2d82cd | 489 | // Send out the individual grid value through the XBee |
soapy12312 | 2:d35fde2d82cd | 490 | XBee.putc(keyInputs[1]); |
soapy12312 | 2:d35fde2d82cd | 491 | |
soapy12312 | 2:d35fde2d82cd | 492 | int smallX = xGrid(); |
soapy12312 | 2:d35fde2d82cd | 493 | int smallY = yGrid(); |
soapy12312 | 2:d35fde2d82cd | 494 | |
soapy12312 | 2:d35fde2d82cd | 495 | grid.smallGrid[largeX][largeY].individualGrid[smallX][smallY] = 0; |
soapy12312 | 2:d35fde2d82cd | 496 | drawSmallGrid(largeX, largeY, BLACK); |
soapy12312 | 2:d35fde2d82cd | 497 | drawSmallX(largeX, largeY, smallX, smallY); |
soapy12312 | 2:d35fde2d82cd | 498 | |
soapy12312 | 2:d35fde2d82cd | 499 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 500 | playSound("/sd/select.wav"); |
soapy12312 | 2:d35fde2d82cd | 501 | |
soapy12312 | 2:d35fde2d82cd | 502 | // Check if player one has taken a small grid |
soapy12312 | 2:d35fde2d82cd | 503 | if (smallGridWin(largeX, largeY, smallX, smallY) == true) { |
soapy12312 | 2:d35fde2d82cd | 504 | grid.smallGrid[largeX][largeY].done = 0; |
soapy12312 | 2:d35fde2d82cd | 505 | drawLargeX(largeX, largeY); |
soapy12312 | 2:d35fde2d82cd | 506 | } else { |
soapy12312 | 2:d35fde2d82cd | 507 | bool draw = true; |
soapy12312 | 2:d35fde2d82cd | 508 | |
soapy12312 | 2:d35fde2d82cd | 509 | for (int i = 0; i < 3; i++) { |
soapy12312 | 2:d35fde2d82cd | 510 | for (int j = 0; j < 3; j++) { |
soapy12312 | 2:d35fde2d82cd | 511 | if (grid.smallGrid[largeX][largeY].individualGrid[i][j] == (char)(-1)) { |
soapy12312 | 2:d35fde2d82cd | 512 | draw = false; |
soapy12312 | 2:d35fde2d82cd | 513 | } |
soapy12312 | 2:d35fde2d82cd | 514 | } |
soapy12312 | 2:d35fde2d82cd | 515 | } |
soapy12312 | 2:d35fde2d82cd | 516 | |
soapy12312 | 2:d35fde2d82cd | 517 | if (draw == true) { |
soapy12312 | 2:d35fde2d82cd | 518 | grid.smallGrid[largeX][largeY].done = 128; |
soapy12312 | 2:d35fde2d82cd | 519 | } |
soapy12312 | 2:d35fde2d82cd | 520 | } |
soapy12312 | 2:d35fde2d82cd | 521 | |
soapy12312 | 2:d35fde2d82cd | 522 | // Check if the other player is ready to proceed |
soapy12312 | 2:d35fde2d82cd | 523 | ready = false; |
soapy12312 | 2:d35fde2d82cd | 524 | |
soapy12312 | 2:d35fde2d82cd | 525 | while (ready == false) { |
soapy12312 | 2:d35fde2d82cd | 526 | if (XBee.readable() == true) { |
soapy12312 | 2:d35fde2d82cd | 527 | ready = XBee.getc(); |
soapy12312 | 2:d35fde2d82cd | 528 | } |
soapy12312 | 2:d35fde2d82cd | 529 | } |
soapy12312 | 2:d35fde2d82cd | 530 | // If it is player two's turn |
soapy12312 | 2:d35fde2d82cd | 531 | } else { |
soapy12312 | 2:d35fde2d82cd | 532 | RGB = BLUE; |
soapy12312 | 2:d35fde2d82cd | 533 | |
soapy12312 | 2:d35fde2d82cd | 534 | // Allow user input |
soapy12312 | 2:d35fde2d82cd | 535 | keyAllowed = true; |
soapy12312 | 2:d35fde2d82cd | 536 | |
soapy12312 | 2:d35fde2d82cd | 537 | int largeX = 0; |
soapy12312 | 2:d35fde2d82cd | 538 | int largeY = 0; |
soapy12312 | 2:d35fde2d82cd | 539 | |
soapy12312 | 2:d35fde2d82cd | 540 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 541 | |
soapy12312 | 2:d35fde2d82cd | 542 | // Ready to proceed |
soapy12312 | 2:d35fde2d82cd | 543 | XBee.putc(true); |
soapy12312 | 2:d35fde2d82cd | 544 | |
soapy12312 | 2:d35fde2d82cd | 545 | // Wait for player to select small grid |
soapy12312 | 2:d35fde2d82cd | 546 | while ((keyInputs[0] == -1) || (grid.smallGrid[largeX][largeY].done != (char)(-1))) { |
soapy12312 | 2:d35fde2d82cd | 547 | // Read in the value through the XBee |
soapy12312 | 2:d35fde2d82cd | 548 | if (XBee.readable() == true) { |
soapy12312 | 2:d35fde2d82cd | 549 | key = XBee.getc(); |
soapy12312 | 2:d35fde2d82cd | 550 | keyInputs[0] = key; |
soapy12312 | 2:d35fde2d82cd | 551 | largeX = xGrid(); |
soapy12312 | 2:d35fde2d82cd | 552 | largeY = yGrid(); |
soapy12312 | 2:d35fde2d82cd | 553 | } |
soapy12312 | 2:d35fde2d82cd | 554 | } |
soapy12312 | 2:d35fde2d82cd | 555 | |
soapy12312 | 2:d35fde2d82cd | 556 | // Highlight selected grid |
soapy12312 | 2:d35fde2d82cd | 557 | drawSmallGrid(largeX, largeY, CYAN); |
soapy12312 | 2:d35fde2d82cd | 558 | |
soapy12312 | 2:d35fde2d82cd | 559 | playSound("/sd/select.wav"); |
soapy12312 | 2:d35fde2d82cd | 560 | |
soapy12312 | 2:d35fde2d82cd | 561 | // Allow user input |
soapy12312 | 2:d35fde2d82cd | 562 | keyAllowed = true; |
soapy12312 | 2:d35fde2d82cd | 563 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 564 | |
soapy12312 | 2:d35fde2d82cd | 565 | // Ready to proceed |
soapy12312 | 2:d35fde2d82cd | 566 | XBee.putc(true); |
soapy12312 | 2:d35fde2d82cd | 567 | |
soapy12312 | 2:d35fde2d82cd | 568 | // Wait for player to select individual grid |
soapy12312 | 2:d35fde2d82cd | 569 | while (keyInputs[1] == -1) { |
soapy12312 | 2:d35fde2d82cd | 570 | wait(0.01); |
soapy12312 | 2:d35fde2d82cd | 571 | |
soapy12312 | 2:d35fde2d82cd | 572 | // Read in the value through the XBee |
soapy12312 | 2:d35fde2d82cd | 573 | if (XBee.readable() == true) { |
soapy12312 | 2:d35fde2d82cd | 574 | key = XBee.getc(); |
soapy12312 | 2:d35fde2d82cd | 575 | keyInputs[1] = key; |
soapy12312 | 2:d35fde2d82cd | 576 | } |
soapy12312 | 2:d35fde2d82cd | 577 | } |
soapy12312 | 2:d35fde2d82cd | 578 | |
soapy12312 | 2:d35fde2d82cd | 579 | int smallX = xGrid(); |
soapy12312 | 2:d35fde2d82cd | 580 | int smallY = yGrid(); |
soapy12312 | 2:d35fde2d82cd | 581 | |
soapy12312 | 2:d35fde2d82cd | 582 | grid.smallGrid[largeX][largeY].individualGrid[smallX][smallY] = 1; |
soapy12312 | 2:d35fde2d82cd | 583 | drawSmallGrid(largeX, largeY, BLACK); |
soapy12312 | 2:d35fde2d82cd | 584 | drawSmallO(largeX, largeY, smallX, smallY); |
soapy12312 | 2:d35fde2d82cd | 585 | |
soapy12312 | 2:d35fde2d82cd | 586 | key = -1; |
soapy12312 | 2:d35fde2d82cd | 587 | playSound("/sd/select.wav"); |
soapy12312 | 2:d35fde2d82cd | 588 | |
soapy12312 | 2:d35fde2d82cd | 589 | // Check if player two has taken a small grid |
soapy12312 | 2:d35fde2d82cd | 590 | if (smallGridWin(largeX, largeY, smallX, smallY) == true) { |
soapy12312 | 2:d35fde2d82cd | 591 | grid.smallGrid[largeX][largeY].done = 1; |
soapy12312 | 2:d35fde2d82cd | 592 | drawLargeO(largeX, largeY); |
soapy12312 | 2:d35fde2d82cd | 593 | } else { |
soapy12312 | 2:d35fde2d82cd | 594 | bool draw = true; |
soapy12312 | 2:d35fde2d82cd | 595 | |
soapy12312 | 2:d35fde2d82cd | 596 | for (int i = 0; i < 3; i++) { |
soapy12312 | 2:d35fde2d82cd | 597 | for (int j = 0; j < 3; j++) { |
soapy12312 | 2:d35fde2d82cd | 598 | if (grid.smallGrid[largeX][largeY].individualGrid[i][j] == (char)(-1)) { |
soapy12312 | 2:d35fde2d82cd | 599 | draw = false; |
soapy12312 | 2:d35fde2d82cd | 600 | } |
soapy12312 | 2:d35fde2d82cd | 601 | } |
soapy12312 | 2:d35fde2d82cd | 602 | } |
soapy12312 | 2:d35fde2d82cd | 603 | |
soapy12312 | 2:d35fde2d82cd | 604 | if (draw == true) { |
soapy12312 | 2:d35fde2d82cd | 605 | grid.smallGrid[largeX][largeY].done = 128; |
soapy12312 | 2:d35fde2d82cd | 606 | } |
soapy12312 | 2:d35fde2d82cd | 607 | } |
soapy12312 | 2:d35fde2d82cd | 608 | |
soapy12312 | 2:d35fde2d82cd | 609 | // Ready to proceed |
soapy12312 | 2:d35fde2d82cd | 610 | XBee.putc(true); |
soapy12312 | 2:d35fde2d82cd | 611 | } |
soapy12312 | 2:d35fde2d82cd | 612 | } |
soapy12312 | 2:d35fde2d82cd | 613 | |
soapy12312 | 2:d35fde2d82cd | 614 | // Draw final line when a player wins |
soapy12312 | 2:d35fde2d82cd | 615 | void drawLargeWinLine(int x1, int y1, int orientation) { |
soapy12312 | 2:d35fde2d82cd | 616 | int x2 = 127; |
soapy12312 | 2:d35fde2d82cd | 617 | int y2 = 127; |
soapy12312 | 2:d35fde2d82cd | 618 | |
soapy12312 | 2:d35fde2d82cd | 619 | if (orientation == FORWARDSLASH) { |
soapy12312 | 2:d35fde2d82cd | 620 | x2 = 0; |
soapy12312 | 2:d35fde2d82cd | 621 | } else if (orientation == HORIZONTAL) { |
soapy12312 | 2:d35fde2d82cd | 622 | y2 = y1; |
soapy12312 | 2:d35fde2d82cd | 623 | } else if (orientation == VERTICAL) { |
soapy12312 | 2:d35fde2d82cd | 624 | x2 = x1; |
soapy12312 | 2:d35fde2d82cd | 625 | } |
soapy12312 | 2:d35fde2d82cd | 626 | |
soapy12312 | 2:d35fde2d82cd | 627 | wait(1); |
soapy12312 | 2:d35fde2d82cd | 628 | uLCD.line(x1, y1, x2, y2, GREEN); |
soapy12312 | 2:d35fde2d82cd | 629 | wait(3); |
soapy12312 | 2:d35fde2d82cd | 630 | } |
soapy12312 | 2:d35fde2d82cd | 631 | |
soapy12312 | 2:d35fde2d82cd | 632 | // Check whether a player has won |
soapy12312 | 2:d35fde2d82cd | 633 | void gameWin(bool turn) { |
soapy12312 | 2:d35fde2d82cd | 634 | bool won = false; |
soapy12312 | 2:d35fde2d82cd | 635 | char small[3][3]; |
soapy12312 | 2:d35fde2d82cd | 636 | |
soapy12312 | 2:d35fde2d82cd | 637 | for (int i = 0; i < 3; i++) { |
soapy12312 | 2:d35fde2d82cd | 638 | for (int j = 0; j < 3; j++) { |
soapy12312 | 2:d35fde2d82cd | 639 | small[i][j] = grid.smallGrid[i][j].done; |
soapy12312 | 2:d35fde2d82cd | 640 | } |
soapy12312 | 2:d35fde2d82cd | 641 | } |
soapy12312 | 2:d35fde2d82cd | 642 | |
soapy12312 | 2:d35fde2d82cd | 643 | int x1 = 2; |
soapy12312 | 2:d35fde2d82cd | 644 | int y1 = 2; |
soapy12312 | 2:d35fde2d82cd | 645 | int orientation = -1; |
soapy12312 | 2:d35fde2d82cd | 646 | |
soapy12312 | 2:d35fde2d82cd | 647 | if ((small[0][0] == small[1][1]) && (small[1][1] == small[2][2]) && |
soapy12312 | 2:d35fde2d82cd | 648 | (small[0][0] != (char)(-1)) && (small[0][0] != 128)) { |
soapy12312 | 2:d35fde2d82cd | 649 | orientation = BACKWARDSLASH; |
soapy12312 | 2:d35fde2d82cd | 650 | won = true; |
soapy12312 | 2:d35fde2d82cd | 651 | } else if ((small[2][0] == small[1][1]) && (small[1][1] == small[0][2]) && |
soapy12312 | 2:d35fde2d82cd | 652 | (small[2][0] != (char)(-1)) && (small[2][0] != 128)) { |
soapy12312 | 2:d35fde2d82cd | 653 | orientation = FORWARDSLASH; |
soapy12312 | 2:d35fde2d82cd | 654 | x1 = 126; |
soapy12312 | 2:d35fde2d82cd | 655 | won = true; |
soapy12312 | 2:d35fde2d82cd | 656 | } else if ((small[0][0] == small[1][0]) && (small[1][0] == small[2][0]) && |
soapy12312 | 2:d35fde2d82cd | 657 | (small[0][0] != (char)(-1)) && (small[0][0] != 128)) { |
soapy12312 | 2:d35fde2d82cd | 658 | orientation = HORIZONTAL; |
soapy12312 | 2:d35fde2d82cd | 659 | y1 += 21; |
soapy12312 | 2:d35fde2d82cd | 660 | won = true; |
soapy12312 | 2:d35fde2d82cd | 661 | } else if ((small[0][1] == small[1][1]) && (small[1][1] == small[2][1]) && |
soapy12312 | 2:d35fde2d82cd | 662 | (small[0][1] != (char)(-1)) && (small[0][1] != 128)) { |
soapy12312 | 2:d35fde2d82cd | 663 | orientation = HORIZONTAL; |
soapy12312 | 2:d35fde2d82cd | 664 | y1 += 63; |
soapy12312 | 2:d35fde2d82cd | 665 | won = true; |
soapy12312 | 2:d35fde2d82cd | 666 | } else if ((small[0][2] == small[1][2]) && (small[1][2] == small[2][2]) && |
soapy12312 | 2:d35fde2d82cd | 667 | (small[0][2] != (char)(-1)) && (small[0][2] != 128)) { |
soapy12312 | 2:d35fde2d82cd | 668 | orientation = HORIZONTAL; |
soapy12312 | 2:d35fde2d82cd | 669 | y1 += 105; |
soapy12312 | 2:d35fde2d82cd | 670 | won = true; |
soapy12312 | 2:d35fde2d82cd | 671 | } else if ((small[0][0] == small[0][1]) && (small[0][1] == small[0][2]) && |
soapy12312 | 2:d35fde2d82cd | 672 | (small[0][0] != (char)(-1)) && (small[0][0] != 128)) { |
soapy12312 | 2:d35fde2d82cd | 673 | orientation = VERTICAL; |
soapy12312 | 2:d35fde2d82cd | 674 | x1 += 21; |
soapy12312 | 2:d35fde2d82cd | 675 | won = true; |
soapy12312 | 2:d35fde2d82cd | 676 | } else if ((small[1][0] == small[1][1]) && (small[1][1] == small[1][2]) && |
soapy12312 | 2:d35fde2d82cd | 677 | (small[1][0] != (char)(-1)) && (small[1][0] != 128)) { |
soapy12312 | 2:d35fde2d82cd | 678 | orientation = VERTICAL; |
soapy12312 | 2:d35fde2d82cd | 679 | x1 += 63; |
soapy12312 | 2:d35fde2d82cd | 680 | won = true; |
soapy12312 | 2:d35fde2d82cd | 681 | } else if ((small[2][0] == small[2][1]) && (small[2][1] == small[2][2]) && |
soapy12312 | 2:d35fde2d82cd | 682 | (small[2][0] != (char)(-1)) && (small[2][0] != 128)) { |
soapy12312 | 2:d35fde2d82cd | 683 | orientation = VERTICAL; |
soapy12312 | 2:d35fde2d82cd | 684 | x1 += 105; |
soapy12312 | 2:d35fde2d82cd | 685 | won = true; |
soapy12312 | 2:d35fde2d82cd | 686 | } else { |
soapy12312 | 2:d35fde2d82cd | 687 | orientation = -1; |
soapy12312 | 2:d35fde2d82cd | 688 | won = false; |
soapy12312 | 2:d35fde2d82cd | 689 | } |
soapy12312 | 2:d35fde2d82cd | 690 | |
soapy12312 | 2:d35fde2d82cd | 691 | // Check to see if there is a draw |
soapy12312 | 2:d35fde2d82cd | 692 | if (won == false) { |
soapy12312 | 2:d35fde2d82cd | 693 | bool draw = true; |
soapy12312 | 2:d35fde2d82cd | 694 | |
soapy12312 | 2:d35fde2d82cd | 695 | for (int i = 0; i < 3; i++) { |
soapy12312 | 2:d35fde2d82cd | 696 | for (int j = 0; j < 3; j++) { |
soapy12312 | 2:d35fde2d82cd | 697 | if (small[i][j] == (char)(-1)) { |
soapy12312 | 2:d35fde2d82cd | 698 | draw = false; |
soapy12312 | 2:d35fde2d82cd | 699 | } |
soapy12312 | 2:d35fde2d82cd | 700 | } |
soapy12312 | 2:d35fde2d82cd | 701 | } |
soapy12312 | 2:d35fde2d82cd | 702 | |
soapy12312 | 2:d35fde2d82cd | 703 | if (draw == true) { |
soapy12312 | 2:d35fde2d82cd | 704 | grid.done = 128; |
soapy12312 | 2:d35fde2d82cd | 705 | wait(3); |
soapy12312 | 2:d35fde2d82cd | 706 | } |
soapy12312 | 2:d35fde2d82cd | 707 | } else { |
soapy12312 | 2:d35fde2d82cd | 708 | if (turn == false) { |
soapy12312 | 2:d35fde2d82cd | 709 | grid.done = 0; |
soapy12312 | 2:d35fde2d82cd | 710 | } else { |
soapy12312 | 2:d35fde2d82cd | 711 | grid.done = 1; |
soapy12312 | 2:d35fde2d82cd | 712 | } |
soapy12312 | 2:d35fde2d82cd | 713 | |
soapy12312 | 2:d35fde2d82cd | 714 | drawLargeWinLine(x1, y1, orientation); |
soapy12312 | 2:d35fde2d82cd | 715 | } |
soapy12312 | 2:d35fde2d82cd | 716 | } |
soapy12312 | 2:d35fde2d82cd | 717 | }; |