J.P. Armstrong
/
FourInARow_NokiaLCD
Connect Four style game. More information can be found here... http://www.armtronics.com/tag/mbedpg
Diff: main.cpp
- Revision:
- 0:2fa346a91818
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Jan 29 19:14:37 2012 +0000 @@ -0,0 +1,275 @@ +// 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); + } +} +*/ \ No newline at end of file