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

Dependencies:   mbed

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);
    }
}
*/