Final
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player
Fork of Lab4-Reversi-v2 by
Reversi.cpp
- Committer:
- aolmenki
- Date:
- 2016-11-01
- Revision:
- 1:cc72ad58982b
- Parent:
- 0:fce0f9489de3
- Child:
- 2:1f7c6cc19a9a
File content as of revision 1:cc72ad58982b:
#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); wave_player waver(&DACout); class Nav_Switch { public: Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire); int read(); //boolean functions to test each switch bool up(); bool down(); bool left(); bool right(); bool fire(); //automatic read on RHS operator int (); //index to any switch array style bool operator[](int index) { return _pins[index]; }; private: BusIn _pins; }; Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire): _pins(up, down, left, right, fire) { _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise wait(0.001); //delays just a bit for pullups to pull inputs high } inline bool Nav_Switch::up() { return !(_pins[0]); } inline bool Nav_Switch::down() { return !(_pins[1]); } inline bool Nav_Switch::left() { return !(_pins[2]); } inline bool Nav_Switch::right() { return !(_pins[3]); } inline bool Nav_Switch::fire() { return !(_pins[4]); } inline int Nav_Switch::read() { return _pins.read(); } inline Nav_Switch::operator int () { return _pins.read(); } Nav_Switch myNav( p14, p11, p12, p10, p13); //pin order on Sparkfun breakout 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; 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 //Cell Codes: 0 = empty, 1 = white piece, 2 = black piece for (int i = 0; i < NUM_ROWS; i++) { for (int j = 0; j < NUM_COLS; j++) gb[i][j] = 0; } gb[3][3] = 1;//Put down white piece gb[4][4] = 1;//Put down white piece gb[3][4] = 2;//Put down black piece gb[4][3] = 2;//Put down black piece uLCD.cls(); uLCD.filled_rectangle(0,0,127,127,0x007f00); uLCD.rectangle(7,7,120,120,DGREY); uLCD.rectangle(8,8,119,119,DGREY); //uLCD.filled_rectangle(8,20,120,21,DGREY); for( int i = 1; i< 9; i++) { uLCD.filled_rectangle(8, 7 + 14*i,119,8 + 14*i,DGREY); } for( int j = 1; j<9; j++) { uLCD.filled_rectangle(7 + 14*j, 8, 8+14*j, 119, DGREY); } } void drawCursor(int x, int y) //Expecting x ={0,7} and y ={0,7} { 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 x,int y) { 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); } 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); } if(gb[i][j] == 2){ uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , BLACK); } } } } 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); } if(gb[i][j] == 2){ uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , BLACK); } } void flippingPiece(int i, int j) { //xCoor, yCoor, animation 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); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 3 , 0x4c4c4c); wait(0.1); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 1 , 0xffffff); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 3 , 0xb2b2b2); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , 0x4c4c4c); wait(0.1); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 3 , 0xffffff); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , 0xb2b2b2); wait(0.1); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , 0xffffff); wait(0.1); } 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); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 3 , 0xb2b2b2); wait(0.1); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 1 , 0x000000); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 3 , 0x4c4c4c); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , 0xb2b2b2); wait(0.1); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 3 , 0x000000); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , 0x4c4c4c); wait(0.1); uLCD.filled_circle(14 * (i + 1), 14 * (j + 1), 5 , 0x000000); wait(0.1); } } /*var fillBoard = function() { for(var r=0; r<8; r++) { for(var c=0; c<8; c++) { drawPiece(r,c,board[r][c]); } } }; var drawBoard = function() { drawEmptyBoard(); fillBoard(); }; --------------------------------------------WAS NOT USED VVVVV ---------------------------- var flipFromInDir = function(r,c,player,rDir,cDir) { //debug("Checking direction rDir: "+rDir+" cDir: "+cDir+" for player "+player); var currentR = r; var currentC = c; var current = board[currentR][currentC]; var toBeFlipped = []; var withinRBounds = 0<=currentR && currentR<8; var withinCBounds = 0<=currentC && currentC<8; var oppositePieces = true; var samePlayerEncounterred = false; while(withinRBounds && withinCBounds && oppositePieces) { //debug(" oh, sweet! "+currentR+", "+currentC+" looks good!"); toBeFlipped.push({r:currentR, c:currentC}); currentR += rDir; currentC += cDir; withinRBounds = 0<=currentR && currentR<8; withinCBounds = 0<=currentC && currentC<8; if(withinCBounds && withinRBounds) { current = board[currentR][currentC]; oppositePieces = (current===-player); //debug(" current at "+currentR+", "+currentC+" is "+current); //debug(" oppositePieces at "+currentR+", "+currentC+" is "+oppositePieces); if(current===player) { samePlayerEncounterred = true; } } } //debug(" we found "+toBeFlipped.length); if(toBeFlipped.length > 1 && samePlayerEncounterred) { for(var i=1; i<toBeFlipped.length; i++) { var flipMe = toBeFlipped[i]; drawPiece(flipMe.r, flipMe.c, player); board[flipMe.r][flipMe.c] = player; } } }; -------------------------------WAS NOT USED ^^^^-------------------- var flipFromInDir = function(r,c,player,rDir,cDir) { var potentialBoard = copyBoard(); var currentR = r+rDir; var currentC = c+cDir; var withinRBounds = 0<=currentR && currentR<8; var withinCBounds = 0<=currentC && currentC<8; while(withinRBounds && withinCBounds) { debug("r,c: "+r+", "+c+" direction: "+rDir+", "+cDir+" current: "+currentR+", "+currentC); var current = board[currentR][currentC]; if(current === 0) { return board; } else if(current === player) { //board = potentialBoard; return potentialBoard; } else { potentialBoard[currentR][currentC] = player; currentR = currentR+rDir; currentC = currentC+cDir; withinRBounds = 0<=currentR && currentR<8; withinCBounds = 0<=currentC && currentC<8; } } return board; }; var flipFrom = function(r,c,player) { for(var rDir = -1; rDir<2; rDir++) { for(var cDir = -1; cDir<2; cDir++) { board = flipFromInDir(r, c, player, rDir, cDir); } } }; var placePiece = function(r,c,player) { //debug("placing piece for player "+player); drawPiece(r,c,player); board[r][c] = player; flipFrom(r,c,player); drawBoard(); }; var move = function(r,c) { placePiece(r,c,whosTurn); whosTurn *= -1; }; var isValidInDir = function(r,c,player,rDir,cDir) { //debug("Checking direction rDir: "+rDir+" cDir: "+cDir+" for player "+player); var currentR = r; var currentC = c; var current = board[currentR][currentC]; var toBeFlipped = []; var withinRBounds = 0<=currentR && currentR<8; var withinCBounds = 0<=currentC && currentC<8; var oppositePieces = true; var samePlayerEncounterred = false; while(withinRBounds && withinCBounds && oppositePieces) { //debug(" oh, sweet! "+currentR+", "+currentC+" looks good!"); toBeFlipped.push({r:currentR, c:currentC}); currentR += rDir; currentC += cDir; withinRBounds = 0<=currentR && currentR<8; withinCBounds = 0<=currentC && currentC<8; if(withinCBounds && withinRBounds) { current = board[currentR][currentC]; oppositePieces = (current===-player); //debug(" current at "+currentR+", "+currentC+" is "+current); //debug(" oppositePieces at "+currentR+", "+currentC+" is "+oppositePieces); if(current===player) { samePlayerEncounterred = true; } } } //debug(" we found "+toBeFlipped.length); if(toBeFlipped.length > 1 && samePlayerEncounterred) { return true; } return false; }; var isValidMove = function(r,c,player) { if(!isEmpty(r,c)) { return false; } for(var rDir = -1; rDir<2; rDir++) { for(var cDir = -1; cDir<2; cDir++) { if(isValidInDir(r, c, player, rDir, cDir)) { return true; } } } return false; }; */ 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; } 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() { 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(); //displayScore();