Connect Four style game. More information can be found here... http://www.armtronics.com/tag/mbedpg

Dependencies:   mbed

Committer:
jp
Date:
Sun Jan 29 19:14:37 2012 +0000
Revision:
0:2fa346a91818
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jp 0:2fa346a91818 1 // Hello World! for Nokia LCD, sford
jp 0:2fa346a91818 2 // - LCD6610 is for newest Sparkfun breakout
jp 0:2fa346a91818 3
jp 0:2fa346a91818 4 #include "mbed.h"
jp 0:2fa346a91818 5 #include "NokiaLCD.h"
jp 0:2fa346a91818 6 #define PIECE_GAP 18
jp 0:2fa346a91818 7 #define PIECE_SIZE 6
jp 0:2fa346a91818 8 #define PI 3.1415
jp 0:2fa346a91818 9 #define RED 0xFF0000
jp 0:2fa346a91818 10 #define GREEN 0x00FF00
jp 0:2fa346a91818 11
jp 0:2fa346a91818 12 InterruptIn button1(p21);
jp 0:2fa346a91818 13 InterruptIn button2(p22);
jp 0:2fa346a91818 14 InterruptIn button3(p23);
jp 0:2fa346a91818 15
jp 0:2fa346a91818 16 DigitalOut ledRed(p24);
jp 0:2fa346a91818 17 DigitalOut ledGreen(p25);
jp 0:2fa346a91818 18
jp 0:2fa346a91818 19 void refreshMovingPiece();
jp 0:2fa346a91818 20 void displaySplash();
jp 0:2fa346a91818 21 bool scanForWinner();
jp 0:2fa346a91818 22 void lcdAlert(const char*);
jp 0:2fa346a91818 23
jp 0:2fa346a91818 24 void drawCircle(int,int,int,int);
jp 0:2fa346a91818 25 void fillCircle(int,int,int,int);
jp 0:2fa346a91818 26 void drawLine(int,int,int,int,int);
jp 0:2fa346a91818 27
jp 0:2fa346a91818 28 NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type
jp 0:2fa346a91818 29 int board[6][7];
jp 0:2fa346a91818 30 int board_stop_row[7] = {5,5,5,5,5,5,5};
jp 0:2fa346a91818 31
jp 0:2fa346a91818 32 int player_active = RED;
jp 0:2fa346a91818 33 int player_position = 3;
jp 0:2fa346a91818 34 int next_step = false;
jp 0:2fa346a91818 35
jp 0:2fa346a91818 36
jp 0:2fa346a91818 37 void buttonMoveRight() {
jp 0:2fa346a91818 38 player_position = (++player_position % 7);
jp 0:2fa346a91818 39 refreshMovingPiece();
jp 0:2fa346a91818 40 wait(0.2);
jp 0:2fa346a91818 41 }
jp 0:2fa346a91818 42
jp 0:2fa346a91818 43 void buttonMoveLeft() {
jp 0:2fa346a91818 44 player_position = (--player_position % 7);
jp 0:2fa346a91818 45 refreshMovingPiece();
jp 0:2fa346a91818 46 wait(0.2);
jp 0:2fa346a91818 47 }
jp 0:2fa346a91818 48
jp 0:2fa346a91818 49 void refreshMovingPiece() {
jp 0:2fa346a91818 50
jp 0:2fa346a91818 51 for(int i = 0; i < 7; i++)
jp 0:2fa346a91818 52 fillCircle(10 + PIECE_GAP * i, 8, PIECE_SIZE, 0x000000);
jp 0:2fa346a91818 53
jp 0:2fa346a91818 54 fillCircle(10 + PIECE_GAP * player_position, 8, PIECE_SIZE, player_active);
jp 0:2fa346a91818 55 }
jp 0:2fa346a91818 56
jp 0:2fa346a91818 57 void buttonSelect() {
jp 0:2fa346a91818 58
jp 0:2fa346a91818 59 // PLACE CHIP WHERE IT'S MEANT TO BE
jp 0:2fa346a91818 60
jp 0:2fa346a91818 61 if (board_stop_row[player_position] < 0) {
jp 0:2fa346a91818 62 lcdAlert("Illegal Move");
jp 0:2fa346a91818 63 return;
jp 0:2fa346a91818 64 }
jp 0:2fa346a91818 65
jp 0:2fa346a91818 66 board[board_stop_row[player_position]][player_position] = player_active;
jp 0:2fa346a91818 67 board_stop_row[player_position]--;
jp 0:2fa346a91818 68
jp 0:2fa346a91818 69 // RESET FOR NEXT PLAYER
jp 0:2fa346a91818 70 player_active = ( player_active == RED ) ? GREEN : RED;
jp 0:2fa346a91818 71 player_position = 3;
jp 0:2fa346a91818 72 refreshMovingPiece();
jp 0:2fa346a91818 73 next_step = true;
jp 0:2fa346a91818 74
jp 0:2fa346a91818 75 wait(0.2);
jp 0:2fa346a91818 76 }
jp 0:2fa346a91818 77
jp 0:2fa346a91818 78 int main() {
jp 0:2fa346a91818 79
jp 0:2fa346a91818 80 displaySplash();
jp 0:2fa346a91818 81
jp 0:2fa346a91818 82 button3.rise(&buttonMoveLeft);
jp 0:2fa346a91818 83 button2.rise(&buttonMoveRight);
jp 0:2fa346a91818 84 button1.rise(&buttonSelect);
jp 0:2fa346a91818 85
jp 0:2fa346a91818 86 lcd.cls();
jp 0:2fa346a91818 87 lcd.background(0x000000);
jp 0:2fa346a91818 88 lcd.fill(2, 16, 126, 110, 0xFFFF00);
jp 0:2fa346a91818 89
jp 0:2fa346a91818 90 player_position = 3;
jp 0:2fa346a91818 91 refreshMovingPiece();
jp 0:2fa346a91818 92
jp 0:2fa346a91818 93 int cnt = 0;
jp 0:2fa346a91818 94 int color = 0x0;
jp 0:2fa346a91818 95
jp 0:2fa346a91818 96 do {
jp 0:2fa346a91818 97
jp 0:2fa346a91818 98 for(cnt = 0; cnt < 42; cnt++) {
jp 0:2fa346a91818 99 color = board[(cnt / 7)][(cnt % 7)];
jp 0:2fa346a91818 100 fillCircle(10 + PIECE_GAP * (cnt % 7), 24 + PIECE_GAP * (cnt / 7), PIECE_SIZE, color);
jp 0:2fa346a91818 101 }
jp 0:2fa346a91818 102 /*
jp 0:2fa346a91818 103 if (scanForWinner()) {
jp 0:2fa346a91818 104 for(cnt = 0; cnt < 42; cnt++) {
jp 0:2fa346a91818 105 board[(cnt / 7)][(cnt % 7)] = NULL;
jp 0:2fa346a91818 106 }
jp 0:2fa346a91818 107 }
jp 0:2fa346a91818 108 */
jp 0:2fa346a91818 109 while (true) {
jp 0:2fa346a91818 110 if (next_step) break;
jp 0:2fa346a91818 111 wait(0.25);
jp 0:2fa346a91818 112 }
jp 0:2fa346a91818 113
jp 0:2fa346a91818 114 next_step = false;
jp 0:2fa346a91818 115
jp 0:2fa346a91818 116 }
jp 0:2fa346a91818 117 while(true);
jp 0:2fa346a91818 118 }
jp 0:2fa346a91818 119
jp 0:2fa346a91818 120
jp 0:2fa346a91818 121 bool scanForWinner() {
jp 0:2fa346a91818 122
jp 0:2fa346a91818 123 int winner = 0;
jp 0:2fa346a91818 124
jp 0:2fa346a91818 125 for (int y = 0; y < 6; y++) {
jp 0:2fa346a91818 126
jp 0:2fa346a91818 127 int lead = 0;
jp 0:2fa346a91818 128 int count = 0;
jp 0:2fa346a91818 129
jp 0:2fa346a91818 130 for (int x = 0; x < 7; x++) {
jp 0:2fa346a91818 131
jp 0:2fa346a91818 132 if (board[y][x] == 0)
jp 0:2fa346a91818 133 break;
jp 0:2fa346a91818 134
jp 0:2fa346a91818 135 if (board[y][x] != lead) {
jp 0:2fa346a91818 136 lead = board[y][x];
jp 0:2fa346a91818 137 count = 0;
jp 0:2fa346a91818 138 }
jp 0:2fa346a91818 139
jp 0:2fa346a91818 140 count++;
jp 0:2fa346a91818 141
jp 0:2fa346a91818 142 if (count == 4) {
jp 0:2fa346a91818 143 winner = lead;
jp 0:2fa346a91818 144 goto someone_won;
jp 0:2fa346a91818 145 }
jp 0:2fa346a91818 146 }
jp 0:2fa346a91818 147
jp 0:2fa346a91818 148 for (int x = 6; x >= 0; x--) {
jp 0:2fa346a91818 149
jp 0:2fa346a91818 150 if (board[x][y] == 0)
jp 0:2fa346a91818 151 break;
jp 0:2fa346a91818 152
jp 0:2fa346a91818 153 if (board[x][y] != lead) {
jp 0:2fa346a91818 154 lead = board[x][y];
jp 0:2fa346a91818 155 count = 0;
jp 0:2fa346a91818 156 }
jp 0:2fa346a91818 157
jp 0:2fa346a91818 158 count++;
jp 0:2fa346a91818 159
jp 0:2fa346a91818 160 if (count == 4)
jp 0:2fa346a91818 161 goto someone_won;
jp 0:2fa346a91818 162
jp 0:2fa346a91818 163 }
jp 0:2fa346a91818 164 }
jp 0:2fa346a91818 165
jp 0:2fa346a91818 166 return false;
jp 0:2fa346a91818 167
jp 0:2fa346a91818 168 someone_won:
jp 0:2fa346a91818 169
jp 0:2fa346a91818 170 if (winner == RED)
jp 0:2fa346a91818 171 lcdAlert("RED WON!");
jp 0:2fa346a91818 172 else
jp 0:2fa346a91818 173 lcdAlert("GREEN WON!");
jp 0:2fa346a91818 174
jp 0:2fa346a91818 175 return true;
jp 0:2fa346a91818 176 }
jp 0:2fa346a91818 177 void lcdAlert(const char* msg) {
jp 0:2fa346a91818 178
jp 0:2fa346a91818 179 lcd.fill(7, 49, 112, 62, 0xFF0000);
jp 0:2fa346a91818 180 lcd.fill(8, 50, 110, 60, 0x0);
jp 0:2fa346a91818 181 lcd.locate(2,9);
jp 0:2fa346a91818 182 lcd.printf(msg);
jp 0:2fa346a91818 183 wait(2);
jp 0:2fa346a91818 184
jp 0:2fa346a91818 185 lcd.cls();
jp 0:2fa346a91818 186 lcd.background(0x000000);
jp 0:2fa346a91818 187 lcd.fill(2, 16, 126, 110, 0xFFFF00);
jp 0:2fa346a91818 188
jp 0:2fa346a91818 189 refreshMovingPiece();
jp 0:2fa346a91818 190 next_step = true;
jp 0:2fa346a91818 191
jp 0:2fa346a91818 192 }
jp 0:2fa346a91818 193 void displaySplash() {
jp 0:2fa346a91818 194 lcd.cls();
jp 0:2fa346a91818 195 lcd.background(0x000000);
jp 0:2fa346a91818 196
jp 0:2fa346a91818 197 lcd.foreground(0xFF0000);
jp 0:2fa346a91818 198 lcd.locate(2, 4);
jp 0:2fa346a91818 199 lcd.printf("FOUR");
jp 0:2fa346a91818 200
jp 0:2fa346a91818 201 lcd.foreground(0x00FF00);
jp 0:2fa346a91818 202 lcd.locate(6, 5);
jp 0:2fa346a91818 203 lcd.printf("IN A");
jp 0:2fa346a91818 204
jp 0:2fa346a91818 205 lcd.foreground(0x0000FF);
jp 0:2fa346a91818 206 lcd.locate(10, 6);
jp 0:2fa346a91818 207 lcd.printf("ROW!");
jp 0:2fa346a91818 208
jp 0:2fa346a91818 209 lcd.foreground(0xFFFFFF);
jp 0:2fa346a91818 210 lcd.locate(2, 10);
jp 0:2fa346a91818 211 lcd.printf("JP ARMSTRONG");
jp 0:2fa346a91818 212 lcd.locate(1, 12);
jp 0:2fa346a91818 213 lcd.printf("ARMTRONICS.COM");
jp 0:2fa346a91818 214 wait(3);
jp 0:2fa346a91818 215 }
jp 0:2fa346a91818 216
jp 0:2fa346a91818 217 /**********************************************************************************/
jp 0:2fa346a91818 218
jp 0:2fa346a91818 219 // From: http://free.pages.at/easyfilter/bresenham.html
jp 0:2fa346a91818 220 void drawCircle(int xm, int ym, int r, int color)
jp 0:2fa346a91818 221 {
jp 0:2fa346a91818 222 int x = -r, y = 0, err = 2-2*r; /* II. Quadrant */
jp 0:2fa346a91818 223 do {
jp 0:2fa346a91818 224 lcd.pixel(xm-x, ym+y, color); /* I. Quadrant */
jp 0:2fa346a91818 225 lcd.pixel(xm-y, ym-x, color); /* II. Quadrant */
jp 0:2fa346a91818 226 lcd.pixel(xm+x, ym-y, color); /* III. Quadrant */
jp 0:2fa346a91818 227 lcd.pixel(xm+y, ym+x, color); /* IV. Quadrant */
jp 0:2fa346a91818 228
jp 0:2fa346a91818 229 r = err;
jp 0:2fa346a91818 230 if (r > x) err += ++x*2+1; /* e_xy+e_x > 0 */
jp 0:2fa346a91818 231 if (r <= y) err += ++y*2+1; /* e_xy+e_y < 0 */
jp 0:2fa346a91818 232 } while (x < 0);
jp 0:2fa346a91818 233
jp 0:2fa346a91818 234 }
jp 0:2fa346a91818 235
jp 0:2fa346a91818 236 void fillCircle(int xm, int ym, int r, int color)
jp 0:2fa346a91818 237 {
jp 0:2fa346a91818 238 int x = -r, y = 0, err = 2-2*r; // II. Quadrant
jp 0:2fa346a91818 239 do {
jp 0:2fa346a91818 240 drawLine(xm-x, ym+y, xm+x, ym-y, color);
jp 0:2fa346a91818 241 drawLine(xm-y, ym-x, xm+y, ym+x, color);
jp 0:2fa346a91818 242
jp 0:2fa346a91818 243 r = err;
jp 0:2fa346a91818 244 if (r > x) err += ++x*2+1; /* e_xy+e_x > 0 */
jp 0:2fa346a91818 245 if (r <= y) err += ++y*2+1; /* e_xy+e_y < 0 */
jp 0:2fa346a91818 246 } while (x < 0);
jp 0:2fa346a91818 247
jp 0:2fa346a91818 248 }
jp 0:2fa346a91818 249
jp 0:2fa346a91818 250 // From http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C.2B.2B
jp 0:2fa346a91818 251 void drawLine(int x0, int y0, int x1, int y1, int color) {
jp 0:2fa346a91818 252
jp 0:2fa346a91818 253 int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
jp 0:2fa346a91818 254 int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
jp 0:2fa346a91818 255 int err = (dx>dy ? dx : -dy)/2, e2;
jp 0:2fa346a91818 256
jp 0:2fa346a91818 257 for(;;){
jp 0:2fa346a91818 258 lcd.pixel(x0,y0, color);
jp 0:2fa346a91818 259 if (x0==x1 && y0==y1) break;
jp 0:2fa346a91818 260 e2 = err;
jp 0:2fa346a91818 261 if (e2 >-dx) { err -= dy; x0 += sx; }
jp 0:2fa346a91818 262 if (e2 < dy) { err += dx; y0 += sy; }
jp 0:2fa346a91818 263 }
jp 0:2fa346a91818 264 }
jp 0:2fa346a91818 265
jp 0:2fa346a91818 266 /*
jp 0:2fa346a91818 267 void drawCircle(int x, int y, int ox, int oy, int color) {
jp 0:2fa346a91818 268
jp 0:2fa346a91818 269 int lx, rx, ly, ry;
jp 0:2fa346a91818 270
jp 0:2fa346a91818 271 for(int i = 0; i < ox; i++) {
jp 0:2fa346a91818 272 lcd.pixel(x + ox * cos((i*2*PI)/ox) ,y + oy * sin((i*2*PI)/oy), color);
jp 0:2fa346a91818 273 }
jp 0:2fa346a91818 274 }
jp 0:2fa346a91818 275 */