completed with EvolutionOfWar

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player

Fork of Lab4-Reversi by Timothy Li

Revision:
1:cc72ad58982b
Parent:
0:fce0f9489de3
--- a/Reversi.cpp	Mon Oct 31 19:22:51 2016 +0000
+++ b/Reversi.cpp	Tue Nov 01 11:46:09 2016 +0000
@@ -1,9 +1,13 @@
 #include "mbed.h"
 #include "uLCD_4DGL.h"
+#include "SDFileSystem.h"
+#include "wave_player.h"
 uLCD_4DGL uLCD(p28, p27, p29); // create a global lcd object
+SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
+PwmOut Speaker(p21);
+AnalogOut DACout(p18);
 
-// black <=> 2
-// white <=> 1
+wave_player waver(&DACout);
 
 class Nav_Switch
 {
@@ -63,41 +67,17 @@
  
 Nav_Switch myNav( p14, p11, p12, p10, p13); //pin order on Sparkfun breakout
  
-int whosTurn = 1;
+int turn = 1; // black goes on 1, white goes on 2 (or 0)
 int gb[8][8];
 int NUM_COLS = 8;
 int NUM_ROWS = 8;
- /*var isEmpty = function(r,c) {
-    return board[r][c] == 0;
-}
-var score = function(boardIn) {
-    var blackScore = 0;
-    var whiteScore = 0;
-    for(var r=0; r<8; r++)
-    {
-        for(var c=0; c<8; c++)
-        {
-            var current = board[r][c];
-            if(current === 1)
-            {
-                whiteScore++;
-            }
-            if(current === -1)
-            {
-                blackScore++;
-            }
-        }
-    }
-    var score = {black: blackScore, white: whiteScore};
-    return score;
-}
-var displayScore = function() {
-    var currentScore = score(board);
-    textSize(20);
-    fill(255, 0, 0);
-    text(currentScore.black+" - "+currentScore.white,180,390);
-}
- */
+int xCoor = 3;
+int yCoor = 4;
+int numBlack = 0;
+int numWhite = 0;
+bool moved = false;
+bool gameover = false;
+
 void initialize_game_board()
 {
     //This is a nested loop to make sure every cell is empty
@@ -113,7 +93,7 @@
     gb[4][3] = 2;//Put down black piece
     
     uLCD.cls();
-    uLCD.background_color(0x007f00);
+    uLCD.filled_rectangle(0,0,127,127,0x007f00);
     
     uLCD.rectangle(7,7,120,120,DGREY);
     uLCD.rectangle(8,8,119,119,DGREY);
@@ -129,63 +109,30 @@
     }
 }
 
-void drawCursor(int xCoor, int yCoor) //Expecting x ={0,7} and y ={0,7}
+void drawCursor(int x, int y) //Expecting x ={0,7} and y ={0,7}
 {
-    uLCD.filled_rectangle(7 + 14*xCoor, 7 + 14*yCoor,8 + 14*xCoor,22 + 14*yCoor,RED);
-    uLCD.filled_rectangle(7 + 14*xCoor, 7 + 14*yCoor,22 + 14*xCoor,8 + 14*yCoor,RED);
-    uLCD.filled_rectangle(7 + 14*xCoor, 21 + 14*yCoor,22 + 14*xCoor,22 + 14*yCoor,RED);
-    uLCD.filled_rectangle(21 + 14*xCoor, 7 + 14*yCoor,22 + 14*xCoor,22 + 14*yCoor,RED);
+    uLCD.filled_rectangle(7 + 14*x, 7 + 14*y,8 + 14*x,22 + 14*y,RED);
+    uLCD.filled_rectangle(7 + 14*x, 7 + 14*y,22 + 14*x,8 + 14*y,RED);
+    uLCD.filled_rectangle(7 + 14*x, 21 + 14*y,22 + 14*x,22 + 14*y,RED);
+    uLCD.filled_rectangle(21 + 14*x, 7 + 14*y,22 + 14*x,22 + 14*y,RED);
 }
     
-void removeCursor(int xCoor,int yCoor)
+void removeCursor(int x,int y)
 {
-    uLCD.filled_rectangle(7 + 14*xCoor, 7 + 14*yCoor,8 + 14*xCoor,22 + 14*yCoor,DGREY);
-    uLCD.filled_rectangle(7 + 14*xCoor, 7 + 14*yCoor,22 + 14*xCoor,8 + 14*yCoor,DGREY);
-    uLCD.filled_rectangle(7 + 14*xCoor, 21 + 14*yCoor,22 + 14*xCoor,22 + 14*yCoor,DGREY);
-    uLCD.filled_rectangle(21 + 14*xCoor, 7 + 14*yCoor,22 + 14*xCoor,22 + 14*yCoor,DGREY);
+    uLCD.filled_rectangle(7 + 14*x, 7 + 14*y,8 + 14*x,22 + 14*y,DGREY);
+    uLCD.filled_rectangle(7 + 14*x, 7 + 14*y,22 + 14*x,8 + 14*y,DGREY);
+    uLCD.filled_rectangle(7 + 14*x, 21 + 14*y,22 + 14*x,22 + 14*y,DGREY);
+    uLCD.filled_rectangle(21 + 14*x, 7 + 14*y,22 + 14*x,22 + 14*y,DGREY);
 }
 
-/*
-var copyBoard = function() {
-    var boardCopy = [[0,0,0,0,0,0,0,0],
-             [0,0,0,0,0,0,0,0],
-             [0,0,0,0,0,0,0,0],
-             [0,0,0,0,0,0,0,0],
-             [0,0,0,0,0,0,0,0],
-             [0,0,0,0,0,0,0,0],
-             [0,0,0,0,0,0,0,0],
-             [0,0,0,0,0,0,0,0]];
-    for(var r=0; r<8; r++)
-    {
-        for(var c=0; c<8; c++)
-        {
-            boardCopy[r][c] = board[r][c];
-        }
-    }
-    return boardCopy;
-}; */
-//Removed DrawEmptyBoard function
-
-/*var drawPiece = function(r,c,player) {
-    var xPos = 400/8*c+400/16;
-    var yPos = 400/8*r+400/16;
-    if(player === 0)
-    {
-        return;
-    }
-    fill(0, 0, 0);
-    if(player===1)
-    {
-        fill(255, 255, 255);
-    }
-    ellipse(xPos,yPos,40,40);
-}; */
-
 void drawPieces(){
     for (int i = 0; i < NUM_ROWS; i++)
     {
         for (int j = 0; j < NUM_COLS; j++)
         {
+            if(gb[i][j] == 0){
+                uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , 0x007f00);
+            }
             if(gb[i][j] == 1){
                 uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , WHITE);
             }
@@ -197,6 +144,11 @@
 }
 
 void drawPiece(int i, int j) { //xCoor, yCoor
+    if (turn == 0) {
+        gb[i][j] = 1;
+    } else {
+        gb[i][j] = 2;
+    }
     if(gb[i][j] == 1){
         uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , WHITE);
     }
@@ -206,7 +158,9 @@
 }
 
 void flippingPiece(int i, int j) { //xCoor, yCoor, animation
-    if(gb[i][j] == 1){ //Gradually changes a piece White
+    
+    if(gb[i][j] == 2){ //Gradually changes a piece White
+        gb[i][j] = 1;
         uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 1 , 0x4c4c4c);
         wait(0.1);
         uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 1 , 0xb2b2b2);
@@ -221,8 +175,8 @@
         wait(0.1);
         uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , 0xffffff);
         wait(0.1);
-    }
-    if(gb[i][j] == 2){ //Gradually changes a piece Black
+    } else if(gb[i][j] == 1){ //Gradually changes a piece Black
+        gb[i][j] = 2;
         uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 1 , 0xb2b2b2);
         wait(0.1);
         uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 1 , 0x4c4c4c);
@@ -240,23 +194,6 @@
     }  
 }
 
-void Select(int xCoor, int yCoor){ //function should determine what happens when joy stick pressed
-    if(whosTurn%2 == 0) ( //Whites Turn
-        //Valid Check, see if move is possible
-        
-        //Place Piece
-        drawPiece(xCoor, yCoor);
-        //Convert pieces in 2D Array
-        int counter; //Count number of converted pieces
-        
-        
-        //Flip pieces on screen
-        for( int m = 0; m<counter; m++) {
-                
-        }
-    }      
-}
-
 /*var fillBoard = function() {
     for(var r=0; r<8; r++)
     {
@@ -270,7 +207,7 @@
     drawEmptyBoard();
     fillBoard();
 };  --------------------------------------------WAS NOT USED VVVVV ----------------------------
-/*var flipFromInDir = function(r,c,player,rDir,cDir)
+var flipFromInDir = function(r,c,player,rDir,cDir)
 {
     //debug("Checking direction rDir: "+rDir+"    cDir: "+cDir+" for player "+player);
     var currentR = r;
@@ -420,34 +357,318 @@
     }
     return false;
 };
-var mouseClicked = function() {
-    var r = floor(mouseY*8/400);
-    var c = floor(mouseX*8/400);
-    if(isValidMove(r,c,whosTurn))
-    {
-        move(r,c);
+*/
+void invalid(int x, int y, int oldColor){
+    gb[x][y] = oldColor;
+    drawPieces();
+    uLCD.line(9 + 14 * xCoor, 11+ 14 * yCoor, 11+ 14 * xCoor, 9+ 14 * yCoor, RED);
+    uLCD.line(11+ 14 * xCoor, 9+ 14 * yCoor, 20+ 14 * xCoor, 18+ 14 * yCoor, RED);
+    uLCD.line(20+ 14 * xCoor, 18+ 14 * yCoor, 18+ 14 * xCoor, 20+ 14 * yCoor, RED);
+    uLCD.line(18+ 14 * xCoor, 20+ 14 * yCoor, 9+ 14 * xCoor, 11+ 14 * yCoor, RED);
+    uLCD.line(9+ 14 * xCoor, 18+ 14 * yCoor, 18+ 14 * xCoor, 9+ 14 * yCoor, RED);
+    uLCD.line(18+ 14 * xCoor, 9+ 14 * yCoor, 20+ 14 * xCoor, 11+ 14 * yCoor, RED);
+    uLCD.line(20+ 14 * xCoor, 11+ 14 * yCoor, 11+ 14 * xCoor, 20+ 14 * yCoor, RED);
+    uLCD.line(11+ 14 * xCoor, 20+ 14 * yCoor, 9+ 14 * xCoor, 18+ 14 * yCoor, RED);
+    wait(1);
+    uLCD.line(9 + 14 * xCoor, 11+ 14 * yCoor, 11+ 14 * xCoor, 9+ 14 * yCoor, 0x007F00);
+    uLCD.line(11+ 14 * xCoor, 9+ 14 * yCoor, 20+ 14 * xCoor, 18+ 14 * yCoor, 0x007F00);
+    uLCD.line(20+ 14 * xCoor, 18+ 14 * yCoor, 18+ 14 * xCoor, 20+ 14 * yCoor, 0x007F00);
+    uLCD.line(18+ 14 * xCoor, 20+ 14 * yCoor, 9+ 14 * xCoor, 11+ 14 * yCoor, 0x007F00);
+    uLCD.line(9+ 14 * xCoor, 18+ 14 * yCoor, 18+ 14 * xCoor, 9+ 14 * yCoor, 0x007F00);
+    uLCD.line(18+ 14 * xCoor, 9+ 14 * yCoor, 20+ 14 * xCoor, 11+ 14 * yCoor, 0x007F00);
+    uLCD.line(20+ 14 * xCoor, 11+ 14 * yCoor, 11+ 14 * xCoor, 20+ 14 * yCoor, 0x007F00);
+    uLCD.line(11+ 14 * xCoor, 20+ 14 * yCoor, 9+ 14 * xCoor, 18+ 14 * yCoor, 0x007F00);
+    drawPieces();
+}
+
+void valid_move(int x, int y) {
+    int opp, pl;
+    bool invalidD[] = {false, false, false, false, false, false, false, false}; //flip checker
+    if (turn == 1) { //pl is black
+        opp = 1;
+        pl = 2;
+    } else { // pl is white
+        opp = 2;
+        pl = 1;
     }
-    displayScore();
-}; 
-*/
+    int oldColor = gb[x][y]; //save old color for drawing over X
+    bool flipped = false;
+    if (gb[x][y] == 0) { // check empty space
+        drawPiece(x, y); // emtpy so draw
+        for (int i = 0; i < 8; i++) { // check for opponent around emtpy space and fill
+            if (i == 0) { // right
+                if (x + 1 < 7 && gb[x + 1][y] == opp) { //check to see if not beyond board and has to be next to the opponent
+                    for (int j = x + 2; j < 8; j++) {
+                        if (gb[j][y] == pl && !flipped) {
+                            for (int k = x + 1; k < j; k++) {
+                                flippingPiece(k, y);
+                            }
+                            flipped = true;
+                        } else if (gb[j][y] == 0) {
+                            j = 8;
+                        }
+                    }
+                    if (flipped) {
+                        flipped = false;
+                    } else {
+                        invalidD[0] = true;
+                    }
+                } else {
+                    invalidD[0] = true;
+                }
+            } else if (i == 1) { // down-right
+                if (x + 1 < 7 && y + 1 < 7 && gb[x + 1][y + 1] == opp) { // check if within margin and next to other color
+                    for (int j = 2; j < 8 - x && j < 8 - y; j++) { // start finding next same color
+                        if (gb[x + j][y + j] == pl && !flipped) { // if same color and not already been flipping
+                            for (int k = 1; k < j; k++) { // between other color to this same color
+                                flippingPiece(x + k, y + k); // flip
+                            }
+                            flipped = true; // marked flipped
+                        } else if (gb[x + j][y + j] == 0) { // if you find an empty instead
+                            j = 8; // skip for loop
+                        }
+                    }
+                    if (flipped) { // if flipped
+                        flipped = false; // set variable back to false
+                    } else {
+                        invalidD[1] = true; // no flip happened, so set invalid tracker to true
+                    }
+                } else {
+                    invalidD[1] = true; // not within margin or next to other color
+                }
+            } else if (i == 2) { // down
+                if (y + 1 < 7 && gb[x][y + 1] == opp) {
+                    for (int j = y + 2; j < 8; j++) {
+                        if (gb[x][j] == pl && !flipped) {
+                            for (int k = y + 1; k < j; k++) {
+                                flippingPiece(x, k);
+                            }
+                            flipped = true;
+                        } else if (gb[x][j] == 0) {
+                            j = 8;
+                        }
+                    }
+                    if (flipped) {
+                        flipped = false;
+                    } else {
+                        invalidD[2] = true;
+                    }
+                } else {
+                    invalidD[2] = true;
+                }
+            } else if (i == 3) { // down-left
+                if (x - 1 > 0 && y + 1 < 7 && gb[x - 1][y + 1] == opp) {
+                    for (int j = 2; j < x + 1 && j < 8 - y; j++) {
+                        if (gb[x - j][y + j] == pl && !flipped) {
+                            for (int k = 1; k < j; k++) {
+                                flippingPiece(x - k, y + k);
+                            }
+                            flipped = true;
+                        } else if (gb[x - j][y + j] == 0) {
+                            j = 5;
+                        }
+                    }
+                    if (flipped) {
+                        flipped = false;
+                    } else {
+                        invalidD[3] = true;
+                    }
+                } else {
+                    invalidD[3] = true;
+                }
+            } else if (i == 4) { // left
+                if (x - 1 > 0 && gb[x - 1][y] == opp) {
+                    for (int j = x - 2; j > -1; j--) {
+                        if (gb[j][y] == pl && !flipped) {
+                            for (int k = x - 1; k > j; k--) {
+                                flippingPiece(k, y);
+                            }
+                            flipped = true;
+                        } else if (gb[j][y] == 0) {
+                            j = -1;
+                        }
+                    }
+                    if (flipped) {
+                        flipped = false;
+                    } else {
+                        invalidD[4] = true;
+                    }
+                } else {
+                    invalidD[4] = true;
+                }
+            } else if (i == 5) { // up-left
+                if (x - 1 > 0 && y - 1 > 0 && gb[x - 1][y - 1] == opp) {
+                    for (int j = 2; j < x + 1 && j < y + 1; j++) {
+                        if (gb[x - j][y - j] == pl && !flipped) {
+                            for (int k = 1; k < j; k++) {
+                                flippingPiece(x - k, y - k);
+                            }
+                            flipped = true;
+                        } else if (gb[x - j][y - j] == 0) {
+                            j = 8;
+                        }
+                    }
+                    if (flipped) {
+                        flipped = false;
+                    } else {
+                        invalidD[5] = true;
+                    }
+                } else {
+                    invalidD[5] = true;
+                }
+            } else if (i == 6) { // up
+                if (y - 1 > 0 && gb[x][y - 1] == opp) {
+                    for (int j = y - 2; j > -1; j--) {
+                        if (gb[x][j] == pl && !flipped) {
+                            for (int k = y - 1; k > j; k--) {
+                                flippingPiece(x, k);
+                            }
+                            flipped = true;
+                        } else if (gb[x][j] == 0) {
+                            j = -1;
+                        }
+                    }
+                    if (flipped) {
+                        flipped = false;
+                    } else {
+                        invalidD[6] = true;
+                    }
+                } else {
+                    invalidD[6] = true;
+                }
+            } else if (i == 7) { // up-right
+                if (x + 1 < 7 && y - 1 > 0 && gb[x + 1][y - 1] == opp) {
+                    for (int j = 2; j < 8 - x && j < y + 1; j++) {
+                        if (gb[x + j][y - j] == pl && !flipped) {
+                            for (int k = 1; k < j; k++) {
+                                flippingPiece(x + k, y - k);
+                            }
+                            flipped = true;
+                        } else if (gb[x + j][y - j] == 0) {
+                            j = 8;
+                        }
+                    }
+                    if (flipped) {
+                        flipped = false;
+                    } else {
+                        invalidD[7] = true;
+                    }
+                } else {
+                    invalidD[7] = true;
+                }
+            }
+        } // finish checking around
+        flipped = false;
+        for (int i = 0; i < 8; i++) {
+            if (!invalidD[i] && !flipped) { // if a move is found, and only once
+                moved = true; // has moved
+                turn = ++turn%2; // increment turn
+                flipped = true; // check flip
+            }
+        }
+        if (!flipped) { // no changes were made
+            invalid(x, y, oldColor); // change back to old color and revert changes
+        }
+    } else { //invalid
+        invalid(x, y, oldColor); // not empty space
+    }
+}
+
+
+void countPieces()
+{
+    numBlack = 0;
+    numWhite = 0;
+    for(int row = 0; row < 8; row++){
+        for(int col = 0; col < 8; col++){
+            if(gb[row][col]==2)
+            {
+                numBlack++;
+            }
+            if(gb[row][col]==1)
+            {
+                numWhite++;
+            }
+        }
+    } 
+}
+void result() {
+    uLCD.cls(); // THIS CODE ASSUMES BACKGROUND CORRECTLY RESETS TO 0x007F00
+    
+    countPieces();
+    uLCD.color(RED);
+    uLCD.printf("Score\n");
+    uLCD.color(BLACK);
+    uLCD.printf("%D, numBlack");
+    uLCD.color(RED);
+    uLCD.printf(" - ");
+    uLCD.color(WHITE);
+    uLCD.printf("%D \n", numWhite);
+    uLCD.color(RED);
+    uLCD.printf("\n Play again? \n");
+    
+    uLCD.text_char('Y', 4, 9, BLUE);
+    uLCD.text_char('E', 5, 9, BLUE);
+    uLCD.text_char('S', 6, 9, BLUE);
+    uLCD.text_char('N', 11, 9, RED);
+    uLCD.text_char('O', 12, 9, RED);
+    
+    uLCD.rectangle(20,90, 40, 110, 0xffff00); //Default over Yes
+    bool optionSelected = false;
+    int choice = 1; //Default choice Yes
+    while(optionSelected ==false){
+        if(myNav[2] == 0 ){
+            uLCD.rectangle(20,90, 40, 110, 0xffff00);
+            uLCD.rectangle(80,90, 100, 110, 0x007F00);
+            choice = 1;
+            }
+        if(myNav[3] == 0 ){
+            uLCD.rectangle(20,90, 40, 110, 0x007F00);
+            uLCD.rectangle(80,90, 100, 110, 0xffff00);
+            choice = 2;
+            }
+        if(myNav[4] == 0){ //Joystick pressed to Select
+            if(choice == 1) {
+                //Restart and play again
+                initialize_game_board();
+                xCoor = 3;
+                yCoor = 4;
+                }
+            else{ //choice == 0
+                //Quit?
+            }
+        }       
+    } 
+}
+
 int main() {
-    initialize_game_board();
-    int xCoor = 3;
-    int yCoor = 4;
-    
-    
-    while(1) {
-        //with pullups a button hit is a "0" - "~" inverts data to leds
-        //~(myNav & 0x0F); //update leds with nav switch direction inputs
-        if(myNav[0] == 0 && xCoor != 0){xCoor --;}
-        if(myNav[1] == 0 && xCoor != 7){xCoor ++;}
-        if(myNav[2] == 0 && yCoor != 0){xCoor --;}
-        if(myNav[3] == 0 && yCoor != 7){xCoor ++;}
-        if(myNav.fire()) {Select(xCoor, yCoor);} // Press Down Joystick for Select
-        //or use - if(myNav[4]==0) mbedleds = 0x0F; //can index a switch bit like this
-        wait(0.02);
+    while (1) {
+       
+        initialize_game_board();
+        drawPieces();
+        while(!gameover) { //active game, checks game over
+            
+            // check inputs
+            while (!moved) {
+                drawCursor(xCoor, yCoor);
+                wait(0.02);
+                removeCursor(xCoor, yCoor);
+                //with pullups a button hit is a "0" - "~" inverts data to leds
+                //~(myNav & 0x0F); //update leds with nav switch direction inputs
+                if(myNav[0] == 0 && xCoor != 0){xCoor --;}
+                if(myNav[1] == 0 && xCoor != 7){xCoor ++;}
+                if(myNav[2] == 0 && yCoor != 7){yCoor ++;}
+                if(myNav[3] == 0 && yCoor != 0){yCoor --;}
+                if(myNav.fire()) {valid_move(xCoor, yCoor);} // Press Down Joystick for Select
+                //or use - if(myNav[4]==0) mbedleds = 0x0F; //can index a switch bit like this
+            }
+            moved = false;
+            // check game over
+            countPieces();
+            gameover = numBlack + numWhite == 64;
+        }
+        result();
     }
-
 }
 //initializeBoard();
 //drawBoard();