J.P. Armstrong
/
FourInARow_NokiaLCD
Connect Four style game. More information can be found here... http://www.armtronics.com/tag/mbedpg
main.cpp
- Committer:
- jp
- Date:
- 2012-01-29
- Revision:
- 0:2fa346a91818
File content as of revision 0:2fa346a91818:
// Hello World! for Nokia LCD, sford // - LCD6610 is for newest Sparkfun breakout #include "mbed.h" #include "NokiaLCD.h" #define PIECE_GAP 18 #define PIECE_SIZE 6 #define PI 3.1415 #define RED 0xFF0000 #define GREEN 0x00FF00 InterruptIn button1(p21); InterruptIn button2(p22); InterruptIn button3(p23); DigitalOut ledRed(p24); DigitalOut ledGreen(p25); void refreshMovingPiece(); void displaySplash(); bool scanForWinner(); void lcdAlert(const char*); void drawCircle(int,int,int,int); void fillCircle(int,int,int,int); void drawLine(int,int,int,int,int); NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type int board[6][7]; int board_stop_row[7] = {5,5,5,5,5,5,5}; int player_active = RED; int player_position = 3; int next_step = false; void buttonMoveRight() { player_position = (++player_position % 7); refreshMovingPiece(); wait(0.2); } void buttonMoveLeft() { player_position = (--player_position % 7); refreshMovingPiece(); wait(0.2); } void refreshMovingPiece() { for(int i = 0; i < 7; i++) fillCircle(10 + PIECE_GAP * i, 8, PIECE_SIZE, 0x000000); fillCircle(10 + PIECE_GAP * player_position, 8, PIECE_SIZE, player_active); } void buttonSelect() { // PLACE CHIP WHERE IT'S MEANT TO BE if (board_stop_row[player_position] < 0) { lcdAlert("Illegal Move"); return; } board[board_stop_row[player_position]][player_position] = player_active; board_stop_row[player_position]--; // RESET FOR NEXT PLAYER player_active = ( player_active == RED ) ? GREEN : RED; player_position = 3; refreshMovingPiece(); next_step = true; wait(0.2); } int main() { displaySplash(); button3.rise(&buttonMoveLeft); button2.rise(&buttonMoveRight); button1.rise(&buttonSelect); lcd.cls(); lcd.background(0x000000); lcd.fill(2, 16, 126, 110, 0xFFFF00); player_position = 3; refreshMovingPiece(); int cnt = 0; int color = 0x0; do { for(cnt = 0; cnt < 42; cnt++) { color = board[(cnt / 7)][(cnt % 7)]; fillCircle(10 + PIECE_GAP * (cnt % 7), 24 + PIECE_GAP * (cnt / 7), PIECE_SIZE, color); } /* if (scanForWinner()) { for(cnt = 0; cnt < 42; cnt++) { board[(cnt / 7)][(cnt % 7)] = NULL; } } */ while (true) { if (next_step) break; wait(0.25); } next_step = false; } while(true); } bool scanForWinner() { int winner = 0; for (int y = 0; y < 6; y++) { int lead = 0; int count = 0; for (int x = 0; x < 7; x++) { if (board[y][x] == 0) break; if (board[y][x] != lead) { lead = board[y][x]; count = 0; } count++; if (count == 4) { winner = lead; goto someone_won; } } for (int x = 6; x >= 0; x--) { if (board[x][y] == 0) break; if (board[x][y] != lead) { lead = board[x][y]; count = 0; } count++; if (count == 4) goto someone_won; } } return false; someone_won: if (winner == RED) lcdAlert("RED WON!"); else lcdAlert("GREEN WON!"); return true; } void lcdAlert(const char* msg) { lcd.fill(7, 49, 112, 62, 0xFF0000); lcd.fill(8, 50, 110, 60, 0x0); lcd.locate(2,9); lcd.printf(msg); wait(2); lcd.cls(); lcd.background(0x000000); lcd.fill(2, 16, 126, 110, 0xFFFF00); refreshMovingPiece(); next_step = true; } void displaySplash() { lcd.cls(); lcd.background(0x000000); lcd.foreground(0xFF0000); lcd.locate(2, 4); lcd.printf("FOUR"); lcd.foreground(0x00FF00); lcd.locate(6, 5); lcd.printf("IN A"); lcd.foreground(0x0000FF); lcd.locate(10, 6); lcd.printf("ROW!"); lcd.foreground(0xFFFFFF); lcd.locate(2, 10); lcd.printf("JP ARMSTRONG"); lcd.locate(1, 12); lcd.printf("ARMTRONICS.COM"); wait(3); } /**********************************************************************************/ // From: http://free.pages.at/easyfilter/bresenham.html void drawCircle(int xm, int ym, int r, int color) { int x = -r, y = 0, err = 2-2*r; /* II. Quadrant */ do { lcd.pixel(xm-x, ym+y, color); /* I. Quadrant */ lcd.pixel(xm-y, ym-x, color); /* II. Quadrant */ lcd.pixel(xm+x, ym-y, color); /* III. Quadrant */ lcd.pixel(xm+y, ym+x, color); /* IV. Quadrant */ r = err; if (r > x) err += ++x*2+1; /* e_xy+e_x > 0 */ if (r <= y) err += ++y*2+1; /* e_xy+e_y < 0 */ } while (x < 0); } void fillCircle(int xm, int ym, int r, int color) { int x = -r, y = 0, err = 2-2*r; // II. Quadrant do { drawLine(xm-x, ym+y, xm+x, ym-y, color); drawLine(xm-y, ym-x, xm+y, ym+x, color); r = err; if (r > x) err += ++x*2+1; /* e_xy+e_x > 0 */ if (r <= y) err += ++y*2+1; /* e_xy+e_y < 0 */ } while (x < 0); } // From http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C.2B.2B void drawLine(int x0, int y0, int x1, int y1, int color) { int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; int err = (dx>dy ? dx : -dy)/2, e2; for(;;){ lcd.pixel(x0,y0, color); if (x0==x1 && y0==y1) break; e2 = err; if (e2 >-dx) { err -= dy; x0 += sx; } if (e2 < dy) { err += dx; y0 += sy; } } } /* void drawCircle(int x, int y, int ox, int oy, int color) { int lx, rx, ly, ry; for(int i = 0; i < ox; i++) { lcd.pixel(x + ox * cos((i*2*PI)/ox) ,y + oy * sin((i*2*PI)/oy), color); } } */