Omok
Project By:
Nakyoung Kim and Robert Choi
Overview:
A popular strategy game played by several different countries around the world was implemented using an Mbed microcontroller. This game is traditionally played with Go pieces (black and white stones on a go board with 19 x 19 intersections.) The black player plays first, and players alternate, placing a stone of their color on an empty intersection. The winner is the first player to get 5 stones in a row horizontally, vertically, or diagonally. In the result of a tie, the game will end in a tie. For more instruction and details about the game, please visit the following Wikipedia page: http://en.wikipedia.org/wiki/Gomoku. For our implementation, the Go board consists of 10 x 10 intersections, displayed on a Serial Miniature LCD module from 4D systems. The user will have push buttons to locate and place the black or white stone. The same rules apply for our implementation.
Components Used:
- uLCD-144-G2: The serial Miniature LCD module for 4D systems was used to display the Go board, providing the user interface for the game. Instructions and references for the uLCD and Mbed board interface can be found here: http://developer.mbed.org/users/4180_1/notebook/ulcd-144-g2-128-by-128-color-lcd/
- Pushbuttons: 2 pushbuttons were used to provide 2 different instructions for the game. The left pushbutton provides the user to go to the main menu and the right pushbutton provides the user to the reset the game without going back the main menu. More information about the pushbuttons can be found here: http://developer.mbed.org/users/4180_1/notebook/pushbuttons/
- Speaker: Speaker was used to make peripheral noise during game play. Different noises were made to determine the start of the game, the switch between players, and if a placement of a piece was legal on the board. More information on connecting the speaker to the Mbed can be found here: http://developer.mbed.org/users/4180_1/notebook/using-a-speaker-for-audio-output/
- Joystick: A joystick was used to move the Go piece in the up, right, down, and left direction. To place the Go piece, the user presses down on the joystick. Please visit this module for more information on the joystick: https://developer.mbed.org/users/4180_1/notebook/user-input-devices/
- RGB LED: An RGB led was another peripheral to display if a move was legal and when a winner was determined. The RGB led turns blue if the placement of the GO piece was legal and the RGB led turns red if the place of the GO piece was illegal. The RGB led flashes red and blue when the game is over. For more information on the RGB LED, please visit the following site: http://developer.mbed.org/users/4180_1/notebook/rgb-leds/
Pin Connections:
Mbed | uLCD-144-G2 |
---|---|
5v | +5v |
p9 | Tx |
p10 | Rx |
GND | GND |
p11 | RES |
Mbed | Pushbuttons | Command |
---|---|---|
p24 | pb7 | Main Menu |
p25 | pb6 | Reset the Game |
Mbed | Speaker |
---|---|
3.3v | Speaker + |
p21 | Speaker - |
Mbed | Joystick | Command |
---|---|---|
p26 | C | Place a Go Piece |
p27 | L | Move Left |
p28 | R | Move Right |
p29 | U | Move Up |
p30 | D | Move Down |
GND | GND | -- |
3.3v | + | -- |
Mbed | RGB LED |
---|---|
p21 | LED Red |
p22 | LED Blue |
GND | GND |
Photos:
Overview:
Game Menu:
Game in Play:
Video Tutorial:
Code:
main.cpp
#include "mbed.h" #include "PinDetect.h" #include "uLCD_4DGL.h" #include "Speaker.h" #define YELLOW 0xFFFF00 uLCD_4DGL uLCD(p9, p10, p11); DigitalOut myled1(LED1); DigitalOut myled2(LED2); DigitalOut myled3(LED3); DigitalOut myled4(LED4); DigitalIn pb1(p27); DigitalIn pb2(p28); DigitalIn pb3(p29); DigitalIn pb4(p30); DigitalIn pb5(p26); DigitalIn pb6(p25); DigitalIn pb7(p24); Speaker mySpeaker(p21); PwmOut R(p22); PwmOut B(p23); int volatile col_value=4; int volatile temp_col=3; int volatile row_value=4; int volatile temp_row=3; int volatile player=1; int volatile tmp=0; int volatile init = 0; void game_init(void); void board_init(void); void location(int colunm, int row, int temp_x, int temp_y); void check(int, int); void win(int); void tied(int); void reset(); int current_x=0; int current_y=0; int board[10][10]; int status; int main() { game_init(); pb1.mode(PullUp); pb2.mode(PullUp); pb3.mode(PullUp); pb4.mode(PullUp); pb5.mode(PullUp); pb6.mode(PullUp); pb7.mode(PullUp); while(1){ wait(0.5); while(pb7) { if((pb1==0)&&(pb2==1)&&(pb3==1)&&(pb4==1)&&(pb5==1)) { uLCD.cls(); uLCD.printf("pb1(Left):\n Main menu\n\n"); uLCD.printf("Instructions:\n"); uLCD.printf("\n"); uLCD.printf("Players alternate,"); uLCD.printf("placing a stone of"); uLCD.printf("their color on an\n"); uLCD.printf("empty intersection"); uLCD.printf("The winner is the\n"); uLCD.printf("first player to\n"); uLCD.printf("get 5 stones in a\n"); uLCD.printf("row in any\n"); uLCD.printf("direction.The game"); uLCD.printf("can result in a\n"); uLCD.printf("tie."); wait(0.5); while(pb1){} game_init(); } if((pb1==1)&&(pb2==0)&&(pb3==1)&&(pb4==1)&&(pb5==1)) { board_init(); break; } } init = 0; while((!init)&pb7) { while(pb6&pb7) { if((pb1==0)&&(pb2==1)&&(pb3==1)&&(pb4==1)&&(pb5==1)) { //wait(0.15); temp_col = col_value; temp_row = row_value; if(col_value==0) col_value = 9; else col_value= col_value-1; wait(0.1); } if((pb1==1)&&(pb2==0)&&(pb3==1)&&(pb4==1)&&(pb5==1)) { //wait(0.15); temp_col = col_value; temp_row = row_value; if(col_value==9) col_value = 0; else col_value= col_value+1; wait(0.1); } if((pb1==1)&&(pb2==1)&&(pb3==0)&&(pb4==1)&&(pb5==1)) { //wait(0.15); temp_col = col_value; temp_row = row_value; if(row_value==0) row_value = 9; else row_value= row_value-1; wait(0.1); } if((pb1==1)&&(pb2==1)&&(pb3==1)&&(pb4==0)&&(pb5==1)) { //wait(0.15); temp_col = col_value; temp_row = row_value; if(row_value==9) row_value = 0; else row_value = row_value+1; wait(0.1); } if((pb1==1)&&(pb2==1)&&(pb3==1)&&(pb4==1)&&(pb5==0)) { wait(0.1); int boardcheck = board[col_value][row_value]; if(boardcheck == 0){ board[col_value][row_value] = player; if (player == 1) { mySpeaker.PlayNote(400,0.05,0.05); uLCD.filled_circle(current_x, current_y , 5.5, BLACK); player = 2; check(col_value, row_value); } else { mySpeaker.PlayNote(600,0.05,0.05); uLCD.filled_circle(current_x, current_y , 5.5, WHITE); player = 1; check(col_value, row_value); } B = 0.5; wait(0.05); B = 0; wait(0.05); B = 0.5; wait(0.05); B = 0; wait(0.05); }else{ mySpeaker.PlayNote(1000,0.1,0.1); R = 0.5; wait(0.05); R = 0; wait(0.05); mySpeaker.PlayNote(1000,0.1,0.1); R = 0.5; wait(0.05); R = 0; wait(0.05); } } if((pb1==1)&&(pb2==1)&&(pb3==1)&&(pb4==1)&&(pb5==1)&&(pb6==0)&&(pb7==1)) { board_init(); } if((pb1==1)&&(pb2==1)&&(pb3==1)&&(pb4==1)&&(pb5==1)&&(pb6==1)&&(pb7==0)) { game_init(); break; } if (player == 1) { myled2 = 0; myled1 = 1; } else if (player == 2) { myled1 = 0; myled2 = 1; } location(col_value, row_value, temp_col, temp_row) ; myled3 = !pb6; } while(!pb6){ board_init(); } } while(!pb7){ game_init(); } } } void game_init(void) { init = 1; reset(); uLCD.baudrate(3000000); uLCD.cls(); uLCD.background_color(0); uLCD.color(RED); uLCD.set_font(FONT_8X12); uLCD.text_mode(OPAQUE); uLCD.locate(7,3); uLCD.set_font(FONT_8X12); uLCD.printf("OMOK\n"); uLCD.circle(53, 100, 8, WHITE); uLCD.filled_circle(73, 100, 8, WHITE); uLCD.locate(3,6); uLCD.printf("pb1(Left):"); uLCD.locate(5,7); uLCD.printf("Instruction"); uLCD.locate(3,8); uLCD.printf("pb2(Right):"); uLCD.locate(5,9); uLCD.printf("Start Game"); } void board_init(void) { init = 0; reset(); uLCD.baudrate(3000000); uLCD.cls(); uLCD.filled_rectangle(0, 0 , 128, 128, YELLOW); for(int j=0; j<10; j++) { current_y=10+j*12; for(int i=0; i<10; i++) { board[i][j] = 0; current_x=10+i*12; uLCD.line(current_x,current_y-3,current_x,121, BLACK); uLCD.line(current_x-3,current_y,121,current_y, BLACK); } } player=1; } void location(int column, int row, int temp_x, int temp_y) { current_x=10+column*12; current_y=10+row*12; temp_x=10+temp_col*12; temp_y=10+temp_row*12; uLCD.filled_circle(current_x, current_y , 2, RED); status = board[temp_col][temp_row]; if(status==1) uLCD.filled_circle(temp_x, temp_y , 2, BLACK); else if(status==2) uLCD.filled_circle(temp_x, temp_y , 2, WHITE); else if(status==0) { uLCD.filled_circle(temp_x, temp_y , 2, YELLOW); uLCD.line(temp_x-2.5,temp_y,temp_x+3,temp_y, BLACK); uLCD.line(temp_x,temp_y-2.5,temp_x,temp_y+3, BLACK); } wait(0.05); } void check(int a, int b) { //vertical if(player==1){tmp = 2;} else if(player==2){tmp =1;} int num = 1; for(int i=1; i<=4; i++) {if(board[a][b+i]==tmp) num++; else break; } for(int j=1; j<=4; j++) { if(board[a][b-j]==tmp) num++; else break; } if (num==5) { wait(1); win(tmp); } //Horizontal num = 1; for(int i=1; i<=4; i++) {if(board[a+i][b]==tmp) num++; else break; } for(int j=1; j<=4; j++) { if(board[a-j][b]==tmp) num++; else break; } if (num==5) { wait(1); win(tmp); } //Diagonal(/directional) num = 1; for(int i=1; i<=4; i++) { if(board[a+i][b+i]==tmp) num++; else break; } for(int j=1; j<=4; j++) { if(board[a-j][b-j]==tmp) num++; else break; } if (num==5) { wait(1); win(tmp); } //Diagonal(\ direction) num = 1; for(int i=1; i<=4; i++) { if(board[a-i][b+i]==tmp) num++; else break; } for(int j=1; j<=4; j++) { if(board[a+j][b-j]==tmp) num++; else break; } if (num==5) { wait(1); win(tmp); } //Check Tie int count = 0; for(int i=0;i<=9;i++){ for(int j=0;j<=9;j++){ int a = board[i][j]; if((a==1)||(a==2)){count++;} if(count==100){tied(tmp);} } } } void win(int a) { uLCD.cls(); mySpeaker.PlayNote(523.251,0.1,0.1); mySpeaker.PlayNote(659.255,0.1,0.1); mySpeaker.PlayNote(783.991,0.1,0.1); while(pb6&pb7) { uLCD.background_color(0); if(a==1){ uLCD.locate(4,5); uLCD.printf("[PLAYER 1]"); uLCD.locate(4,6); uLCD.printf("BLACK WINS"); uLCD.circle(60, 80, 8, WHITE); myled1=1; myled2=0; }else if(a==2){ uLCD.locate(4,5); uLCD.printf("[PLAYER 2]"); uLCD.locate(4,6); uLCD.printf("WHITE WINS"); uLCD.filled_circle(60, 80, 8, WHITE); myled1=0; myled2=1; } R=0.5; B=0; wait(0.1); R=0; B=0.5; } while(!pb6){ board_init(); } } void tied(int a){ uLCD.cls(); mySpeaker.PlayNote(659.255,0.1,0.1); wait(0.1); mySpeaker.PlayNote(659.255,0.1,0.1); while(pb6&pb7) { myled1=0; myled2=0; uLCD.background_color(0); uLCD.locate(7,7); uLCD.printf("TIED\n"); uLCD.circle(53, 80, 8, WHITE); uLCD.filled_circle(73, 80, 8, WHITE); uLCD.printf("TIED"); wait(0.2); } while(!pb6){ board_init(); init = 0; } } void reset(){ mySpeaker.PlayNote(900,0.25,0.1); for(int j=0; j<10; j++) { current_y=10+j*12; for(int i=0; i<10; i++) { board[i][j] = 0; } } wait(0.1); uLCD.cls(); myled1=0; myled2=0; col_value=4; temp_col=3; row_value=4; temp_row=3; R=0; B=0; player=1; }
Please log in to post comments.