Hardware components | ||||||
![]() |
| × | 1 | |||
| × | 1 | ||||
| × | 2 | ||||
![]() |
| × | 1 | |||
Software apps and online services | ||||||
![]() |
|
Omok, a traditional eastern game, is enjoyed by everyone. Whether you are old or young, you will enjoy this game of eastern Tic Tac Toe.
We have made an Arduino board that makes you able to do Omok with a friend. This device uses a 32*32 LED panel with multiple colors to show each player's moves and two joysticks for you to move.
The rules are simple. Green, player 1, places the first move. Blue, player 2, places the stone in the empty location. And two players alternate their turns to place the stone. If you move to a location where a color is already set, your cursor will turn red and you won't be able to place your move. If you have 'five-in-a-row', you win the game and the screen turns the color of the winner. The screen prints "Green Wins!" or "Blue Wins!" and it starts over.
In order for you not to delay your turn endlessly, we made a timer at each side of the LED panel. Players have to choose a location to place your stone, and place the stone within 10 seconds. Otherwise that player will lose the game. The time limit will make the game go speedily.
Enjoy the game!
Gameplay videoOmok circuit picture
#include <Adafruit_GFX.h>
#include <RGBmatrixPanel.h>
#define CLK 11
#define OE 9
#define LAT 10
#define A A0
#define B A1
#define C A2
#define D A3
RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);
const int SW0_pin = 50;
const int X_pin = A8;
const int Y_pin = A9;
const int SW1_pin=51;
const int Z_pin=A10;
const int W_pin=A11;
typedef struct coor{
byte x;
byte y;
}coor;
int i=0;
coor cr[100]={{0,0}};
int x=16;
int y=16;
int sw=0;
int j=0;
void setup() {
pinMode(SW0_pin, INPUT);
digitalWrite(SW0_pin, HIGH);
pinMode(SW1_pin, INPUT);
digitalWrite(SW1_pin, HIGH);
Serial.begin(9600);
matrix.begin();
matrix.println("Let's");
matrix.println("start");
matrix.println("5 mok");
delay(1000);
matrix.fillRect(0, 0, 32, 32, matrix.Color333(0, 0, 0));
delay(1000);
setuptimer1();
setuptimer2();
delay(500);
}
void loop() {
if(sw==0){
cursour_x(analogRead(X_pin));
cursour_y(analogRead(Y_pin));
for(int k=0;k<31-j;k++) matrix.drawPixel(31,31-k,matrix.Color333((7*j/31)+2,0,2));
matrix.drawPixel(31,j,matrix.Color333(0,0,0));
j++;
if(j==31) printwin(1-sw);
color(x,y,0);
}
if(sw==1){
cursour_z(analogRead(Z_pin));
cursour_w(analogRead(W_pin));
for(int k=0;k<31-j;k++) matrix.drawPixel(0,31-k,matrix.Color333(0,2,(7*j/31)+2));
matrix.drawPixel(0,j,matrix.Color333(0,0,0));
j++;
if(j==31) printwin(1-sw);
color(x,y,1);
}
omok(x,y);
delay(300);
}
void cursour_x(int z){
if(z>1000){
int j;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(0, 7*(1-(cr[j].x)%2),7*(cr[j].x%2)));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(0, 0,0));
x=(x+31)%32;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2) {
matrix.drawPixel(x, y, matrix.Color333(7,0,0));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(7, 7,7));
}
if(z<30){
int j;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(0, 7*(1-(cr[j].x)%2),7*(cr[j].x%2)));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(0, 0,0));
x=(x+1)%32;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){ matrix.drawPixel(x, y, matrix.Color333(7,0,0));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(7, 7,7));
}
}// 1번 플레이어가 조이스틱을 x방향으로 움직이면 이동하게 된 칸에 하얀색을 칠하는 함수
void cursour_z(int z){
if(z>1000){
int j;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(0, 7*(1-(cr[j].x)%2),7*(cr[j].x%2)));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(0, 0,0));
x=(x+31)%32;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2) {
matrix.drawPixel(x, y, matrix.Color333(7,0,0));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(7, 7,7));
}
if(z<30){
int j;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(0, 7*(1-(cr[j].x)%2),7*(cr[j].x%2)));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(0, 0,0));
x=(x+1)%32;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){ matrix.drawPixel(x, y, matrix.Color333(7,0,0));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(7, 7,7));
}
}// 2번 플레이어가 조이스틱을 x방향으로 움직이면 이동하게 된 칸에 하얀색을 칠하는 함수
void cursour_y(int z){
if(z>1000){
int j=0;
for(j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(0, 7*(1-(cr[j].x)%2),7*(cr[j].x%2)));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(0, 0,0));
y=(y+31)%32;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(7,0,0));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(7, 7,7));
}
if(z<30){
int j;
for(j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(0, 7*(1-(cr[j].x)%2),7*(cr[j].x%2)));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(0, 0,0));
y=(y+1)%32;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(7,0,0));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(7, 7,7));
}
} // 1번 플레이어가 조이스틱을 y방향으로 움직이면 이동하게 된 칸에 하얀색을 칠하는 함수
void cursour_w(int z) {
if(z>1000){
int j=0;
for(j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(0, 7*(1-(cr[j].x)%2),7*(cr[j].x%2)));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(0, 0,0));
y=(y+31)%32;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(7,0,0));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(7, 7,7));
}
if(z<30){
int j;
for(j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(0, 7*(1-(cr[j].x)%2),7*(cr[j].x%2)));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(0, 0,0));
y=(y+1)%32;
for( j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2){
matrix.drawPixel(x, y, matrix.Color333(7,0,0));
break;
}
}
if(j==100) matrix.drawPixel(x, y, matrix.Color333(7, 7,7));
}
} // 2번 플레이어가 조이스틱을 y방향으로 움직이면 이동하게 된 칸에 하얀색을 칠하는 함수
void color(int x, int y, int z){
if(z==0){
if(digitalRead(SW0_pin)==0)
{
if(printcolor(x,y)==-1){
matrix.drawPixel(x,y,matrix.Color333(0,7*(1-sw),7*sw));
cr[i].x=2*x+sw, cr[i].y=2*y+sw, i++;
sw=1-sw;
j=0;
setuptimer1();
}
}
}
if(z==1){
if(digitalRead(SW1_pin)==0)
{
if(printcolor(x,y)==-1){
matrix.drawPixel(x,y,matrix.Color333(0,7*(1-sw),7*sw));
cr[i].x=2*x+sw, cr[i].y=2*y+sw, i++;
sw=1-sw;
j=0;
setuptimer2();
}
}
}
}// 조이스틱을 누르면 해당 칸을 플레이어의 턴 색으로 칠하는 함수
int printcolor(int x, int y){
for(int j=0;j<100;j++){
if(x==(cr[j].x)/2 && y==(cr[j].y)/2)
return (cr[j].x)%2;
}
return -1;
} // 각 색의 정보를 출력하는 함수
void omok(int x, int y){
int temp=printcolor(x,y);
if(temp!=-1){
for(int p=-4;p<1;p++){
if(printcolor(x+p,y)==temp && printcolor(x+p+1,y)==temp && printcolor(x+p+2,y)==temp && printcolor(x+p+3,y)==temp && printcolor(x+p+4,y)==temp) printwin(temp);
} // x축 방향 오목 확인
for(int p=-4;p<1;p++){
if(printcolor(x,y+p)==temp && printcolor(x,y+p+1)==temp && printcolor(x,y+p+2)==temp && printcolor(x,y+p+3)==temp && printcolor(x,y+p+4)==temp) printwin(temp);
} // y축 방향 오목 확인
for(int p=-4;p<1;p++){
if(printcolor(x+p,y+p)==temp && printcolor(x+p+1,y+p+1)==temp && printcolor(x+p+2,y+p+2)==temp && printcolor(x+p+3,y+p+3)==temp && printcolor(x+p+4,y+p+4)==temp) printwin(temp);
}// 대각선 방향 오목 확인
for(int p=-4;p<1;p++){
if(printcolor(x+p,y-p)==temp && printcolor(x+p+1,y-p-1)==temp && printcolor(x+p+2,y-p-2)==temp && printcolor(x+p+3,y-p-3)==temp && printcolor(x+p+4,y-p-4)==temp) printwin(temp);
}// 대각선 방향 오목 확인
}
}
void printwin(int temp){
matrix.fillRect(0, 0, 32, 32, matrix.Color333(0, 7*(1-temp), 7*temp));
delay(2000);
matrix.fillRect(0, 0, 32, 32, matrix.Color333(0, 0, 0));
matrix.setCursor(1, 0); // start at top left, with one pixel of spacing
matrix.setTextSize(1); // size 1 == 8 pixels high
matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves
matrix.setTextColor(matrix.Color333(7,7,7));
if(temp){
matrix.setTextColor(matrix.Color333(0,0,7));
matrix.println("Blue");
}
if(!temp){
matrix.setTextColor(matrix.Color333(0,7,0));
matrix.println("Green");
}
matrix.println("Wins!");
delay(5000);
matrix.fillRect(0, 0, 32, 32, matrix.Color333(0, 0, 0));
i=0;
x=16;
y=16;
sw=0;
for(int i=0; i<100;i++){
cr[i].x=0; cr[i].y=0;
}
} // 게임 끝내고 모든 변수 초기화
void setuptimer1(){
for(int i=0;i<32;i++){
matrix.drawPixel(31, i, matrix.Color333(3, 0,2));
}
}
void setuptimer2(){
for(int i=0;i<32;i++){
matrix.drawPixel(0, i, matrix.Color333(0, 3,3));
}
}
Comments