Sabtu, 03 Mei 2014

Tic-Tac-Toe menggunakan Arduino

Tic-Tac-Toe atau X dan O adalah permainan yang dilakukan oleh dua orang pada suatu bidang persegi berukuran 3x3. Pemain secara bergantian mengisi tanda X atau O pada satu kotak setiap giliran sampai ada yang menang atau semua kotak sudah diisi. Pemain dikatakan menang jika pemain dapat membuat pola garis lurus, baik vertikal, horizontal, atau diagonal.


Kita akan mencoba membuat tic-tac-toe pada Arduino. Komponen yang digunakan adalah sebagai berikut.
  • Arduino Uno
  • LED 11 buah
  • Pushbutton
  • Keypad 3x3
  • Breadboard
  • Kabel tembaga
Berikut adalah skematik dan foto dari percobaan ini.

Skematik

Foto Percobaan
Percobaan ini membutuhkan 11 LED. Sembilan LED digunakan untuk merepresentasikan papan permainan yang berukuran 3x3 dan dua LED digunakan sebagai indikator pemain mana yang sedang mendapat giliran. Untuk memilih kotak yang diinginkan, digunakan keypad berukuran 3X3. Setiap tombol pada keypad merepresentasikan 1 dari 9  LED pada papan permainan. Selain itu terdapat satu pushbutton yang berfungsi untuk me-reset permainan.

Berikut adalah diagram alur pada percobaan.

Diagram Alur


Ketika pertama kali dijalankan, program masuk ke mode pilihan untuk player 1, kemudian player 2,  dan seterusnya sampai ada yang menang atau draw. Setelah itu permainan diulang.

Berikut adalah source code pada percobaan


const int numRows = 3;
const int numCols = 3;
const int debounceTime = 200;
const char keymap[numRows][numCols] = {
  { '1', '2', '3'} ,
  { '4', '5', '6'} ,
  { '7', '8', '9'}
};

//===========================================
const int rowPins[numRows] = { 10, 9, 8};
const int colPins[numCols] = { 7, 6, 5};
const int LedPIN1 = A0; //LAMPU 1-6 DI ANALOG
const int LedPIN2 = A1;
const int LedPIN3 = A2;
const int LedPIN4 = A3;
const int LedPIN5 = A4;
const int LedPIN6 = A5;
const int LedPIN7 = 13; //LAMPU 7-9 DI DIGITAL
const int LedPIN8 = 12;
const int LedPIN9 = 11;
const int player1LedPin = 4; // Indikator player 1 atau 2 yang mendapat giliran
const int player2LedPin = 3;
const int resetButton = 2;

const int ledmap[numRows][numCols] = {
  { LedPIN1, LedPIN2, LedPIN3} ,
  { LedPIN4, LedPIN5, LedPIN6} ,
  { LedPIN7, LedPIN8, LedPIN9}
};

const int blinkInterval =50;
int lastBlink = 0;

//============================================

int player = 1;
int winner = 0;
int line = 0;
int i = 0;

char A[3][3] = {{'1','2','3'},{'4','5','6'},{'7','8','9'}};

void setup(){
  pinMode(LedPIN1,OUTPUT);
  pinMode(LedPIN2,OUTPUT);
  pinMode(LedPIN3,OUTPUT);
  pinMode(LedPIN4,OUTPUT);
  pinMode(LedPIN5,OUTPUT);
  pinMode(LedPIN6,OUTPUT);
  pinMode(LedPIN7,OUTPUT);
  pinMode(LedPIN8,OUTPUT);
  pinMode(LedPIN9,OUTPUT);
  pinMode(player1LedPin,OUTPUT);
  pinMode(player2LedPin,OUTPUT);
  pinMode(resetButton,INPUT);
  digitalWrite(resetButton,HIGH);
 
  //untuk keypad
  Serial.begin(9600);
  for (int row = 0; row < numRows; row++)
  {
    pinMode(rowPins[row],INPUT);
    digitalWrite(rowPins[row],255);
  }
  for (int column = 0; column < numCols; column++)
  {
    pinMode(colPins[column],OUTPUT);
    digitalWrite(colPins[column],255);
  }
   
   //untuk matriks tic tac toe
    //==================
    Serial.println("+ - + - + - +");Serial.print("+ ");Serial.print(A[0][0]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[0][1]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[0][2]);Serial.println(" + ");
    Serial.println("+ - + - + - +");Serial.print("+ ");Serial.print(A[1][0]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[1][1]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[1][2]);Serial.println(" + ");
    Serial.println("+ - + - + - +");Serial.print("+ ");Serial.print(A[2][0]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[2][1]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[2][2]);Serial.println(" + ");
    Serial.println("+ - + - + - +");
    Serial.println();
    Serial.println("Player 1 silahkan duluan : ");
   
    //==================
    //Cek LED
    digitalWrite(LedPIN1, 255);
    digitalWrite(LedPIN2, 255);
    digitalWrite(LedPIN3, 255);   
    digitalWrite(LedPIN4, 255);   
    digitalWrite(LedPIN5, 255);   
    digitalWrite(LedPIN6, 255);   
    digitalWrite(LedPIN7, 255);   
    digitalWrite(LedPIN8, 255);   
    digitalWrite(LedPIN9, 255);
    delay(1500);
    digitalWrite(LedPIN1, 0);
    digitalWrite(LedPIN2, 0);
    digitalWrite(LedPIN3, 0);   
    digitalWrite(LedPIN4, 0);   
    digitalWrite(LedPIN5, 0);   
    digitalWrite(LedPIN6, 0);   
    digitalWrite(LedPIN7, 0);   
    digitalWrite(LedPIN8, 0);   
    digitalWrite(LedPIN9, 0);
}


void loop(){
 zzz :
  int currentTime = millis();
  if (digitalRead(resetButton)==LOW){
    resetGame();
    goto zzz;
  }
  boolean isBlink = false;
    for (int i = 0; i<3;i++){
      for (int j = 0; j<3;j++){
        if (A[i][j]== 'X'){
          digitalWrite(ledmap[i][j], 255);
        } else if (A[i][j]== 'O'){
          if (currentTime-lastBlink>=blinkInterval){
            if (digitalRead(ledmap[i][j])==0){
              digitalWrite(ledmap[i][j], 255);
            } else {
              digitalWrite(ledmap[i][j], 0);
            }
            isBlink = true;
          }
         
        } else {
          digitalWrite(ledmap[i][j], 0);
        }

      }
    }
    if (isBlink==true){
      lastBlink = currentTime; 
    }
   
    if (player == 1){
      digitalWrite(player1LedPin, 255);
      digitalWrite(player2LedPin, 0);
    } else {
      digitalWrite(player1LedPin, 0);
      digitalWrite(player2LedPin, 255);    
    }
   
  char key = getKey();
  if ( key != 0 && winner == 0 && i < 9) {
              if (player == 1) {
               if (key == '1' && A[0][0] != 'X' && A[0][0] != 'O')  {
                A[0][0] = 'X';               
               } else if (key == '2' && A[0][1] != 'X' && A[0][1] != 'O') {
                A[0][1] = 'X';          
               } else if (key == '3' && A[0][2] != 'X' && A[0][2] != 'O') {
                A[0][2] = 'X';
               } else if (key == '4' && A[1][0] != 'X' && A[1][0] != 'O') {
                A[1][0] = 'X';
               } else if (key == '5' && A[1][1] != 'X' && A[1][1] != 'O') {
                A[1][1] = 'X';
               } else if (key == '6' && A[1][2] != 'X' && A[1][2] != 'O') {
                A[1][2] = 'X';
               } else if (key == '7' && A[2][0] != 'X' && A[2][0] != 'O') {
                A[2][0] = 'X';
               } else if (key == '8' && A[2][1] != 'X' && A[2][1] != 'O') {
                A[2][1] = 'X';
               } else if (key == '9' && A[2][2] != 'X' && A[2][2] != 'O') {
                A[2][2] = 'X';
               } else {
                Serial.print("Player ");
                Serial.print(player);
                Serial.println(", coba masukkan kembali : ");
                goto zzz;
               } 
                   Serial.println("+ - + - + - +");Serial.print("+ ");Serial.print(A[0][0]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[0][1]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[0][2]);Serial.println(" + ");
                   Serial.println("+ - + - + - +");Serial.print("+ ");Serial.print(A[1][0]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[1][1]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[1][2]);Serial.println(" + ");
                   Serial.println("+ - + - + - +");Serial.print("+ ");Serial.print(A[2][0]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[2][1]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[2][2]);Serial.println(" + ");
                   Serial.println("+ - + - + - +");
                   Serial.println();
                  
                player = 2;
                } else if (player == 2) {
                    if (key == '1' && A[0][0] != 'X' && A[0][0] != '0')  {
                     A[0][0] = 'O';
                   } else if (key == '2' && A[0][1] != 'X' && A[0][1] != 'O') {
                     A[0][1] = 'O';
                   } else if (key == '3' && A[0][2] != 'X' && A[0][2] != 'O') {
                     A[0][2] = 'O';
                   } else if (key == '4' && A[1][0] != 'X' && A[1][0] != 'O') {
                     A[1][0] = 'O';
                   } else if (key == '5' && A[1][1] != 'X' && A[1][1] != 'O') {
                     A[1][1] = 'O';
                   } else if (key == '6' && A[1][2] != 'X' && A[1][2] != 'O') {
                     A[1][2] = 'O';
                   } else if (key == '7' && A[2][0] != 'X' && A[2][0] != 'O') {
                     A[2][0] = 'O';
                   } else if (key == '8' && A[2][1] != 'X' && A[2][1] != 'O') {
                     A[2][1] = 'O';
                   } else if (key == '9' && A[2][2] != 'X' && A[2][2] != 'O') {
                     A[2][2] = 'O';
                   } else {
                     Serial.print("Player ");
                     Serial.print(player);
                     Serial.println(", coba masukkan kembali : ");
                     goto zzz;
                   }
                   Serial.println("+ - + - + - +");Serial.print("+ ");Serial.print(A[0][0]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[0][1]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[0][2]);Serial.println(" + ");
                   Serial.println("+ - + - + - +");Serial.print("+ ");Serial.print(A[1][0]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[1][1]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[1][2]);Serial.println(" + ");
                   Serial.println("+ - + - + - +");Serial.print("+ ");Serial.print(A[2][0]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[2][1]);Serial.print(" ");Serial.print("+");Serial.print(" ");Serial.print(A[2][2]);Serial.println(" + ");
                   Serial.println("+ - + - + - +");
                   Serial.println();
                   player = 1;
    }
    i++;
   
    if  ((A[0][0]==A[1][1] && A[0][0]==A[2][2]) || (A[0][2]==A[1][1] && A[0][2]==A[2][0]))  {
        winner = player;
        if (winner == 1) {
            Serial.print("Winner adalah 2 ");
            for (int i =0 ; i<4;i++){
              digitalWrite(LedPIN1, 255);
              digitalWrite(LedPIN2, 255);
              digitalWrite(LedPIN3, 255);
              digitalWrite(LedPIN4, 255);
              digitalWrite(LedPIN5, 255);
              digitalWrite(LedPIN6, 255);
              digitalWrite(LedPIN7, 255);
              digitalWrite(LedPIN8, 255);
              digitalWrite(LedPIN9, 255);
              digitalWrite(player2LedPin, 255);
              delay(100);
              digitalWrite(LedPIN1, 0);
              digitalWrite(LedPIN2, 0);
              digitalWrite(LedPIN3, 0);
              digitalWrite(LedPIN4, 0);
              digitalWrite(LedPIN5, 0);
              digitalWrite(LedPIN6, 0);
              digitalWrite(LedPIN7, 0);
              digitalWrite(LedPIN8, 0);
              digitalWrite(LedPIN9, 0);
              digitalWrite(player2LedPin, 0);
              delay(100);
            }
          resetGame();
          goto zzz;
           
        } else if (winner == 2) {
            Serial.print("Winner adalah 1 ");
           for (int i =0 ; i<2;i++){
              digitalWrite(LedPIN1, 255);
              digitalWrite(LedPIN2, 255);
              digitalWrite(LedPIN3, 255);
              digitalWrite(LedPIN4, 255);
              digitalWrite(LedPIN5, 255);
              digitalWrite(LedPIN6, 255);
              digitalWrite(LedPIN7, 255);
              digitalWrite(LedPIN8, 255);
              digitalWrite(LedPIN9, 255);
              digitalWrite(player1LedPin, 255);
              delay(500);
              digitalWrite(LedPIN1, 0);
              digitalWrite(LedPIN2, 0);
              digitalWrite(LedPIN3, 0);
              digitalWrite(LedPIN4, 0);
              digitalWrite(LedPIN5, 0);
              digitalWrite(LedPIN6, 0);
              digitalWrite(LedPIN7, 0);
              digitalWrite(LedPIN8, 0);
              digitalWrite(LedPIN9, 0);
              digitalWrite(player1LedPin, 0);

              delay(500);
            }
          resetGame();
          goto zzz;           
        }
       
    } else {
        for  (line = 0; line <=2; line++) {
          if  ((A[line][0]==A[line][1] && A[line][0]==A[line][2])|| (A[0][line]==A[1][line] && A[0][line]==A[2][line])) {
            winner = player;
            if (winner == 1) {
              Serial.print("Winner adalah 2 ");
           for (int i =0 ; i<4;i++){
              digitalWrite(LedPIN1, 255);
              digitalWrite(LedPIN2, 255);
              digitalWrite(LedPIN3, 255);
              digitalWrite(LedPIN4, 255);
              digitalWrite(LedPIN5, 255);
              digitalWrite(LedPIN6, 255);
              digitalWrite(LedPIN7, 255);
              digitalWrite(LedPIN8, 255);
              digitalWrite(LedPIN9, 255);
              digitalWrite(player2LedPin, 255);
              delay(100);
              digitalWrite(LedPIN1, 0);
              digitalWrite(LedPIN2, 0);
              digitalWrite(LedPIN3, 0);
              digitalWrite(LedPIN4, 0);
              digitalWrite(LedPIN5, 0);
              digitalWrite(LedPIN6, 0);
              digitalWrite(LedPIN7, 0);
              digitalWrite(LedPIN8, 0);
              digitalWrite(LedPIN9, 0);
              digitalWrite(player2LedPin, 0);
              delay(100);
            }
           
      resetGame();
      goto zzz;

           
            } else if (winner == 2) {
                Serial.print("Winner adalah 1 ");
               for (int i =0 ; i<2;i++){
                  digitalWrite(LedPIN1, 255);
                  digitalWrite(LedPIN2, 255);
                  digitalWrite(LedPIN3, 255);
                  digitalWrite(LedPIN4, 255);
                  digitalWrite(LedPIN5, 255);
                  digitalWrite(LedPIN6, 255);
                  digitalWrite(LedPIN7, 255);
                  digitalWrite(LedPIN8, 255);
                  digitalWrite(LedPIN9, 255);
                  digitalWrite(player1LedPin, 255);
                  delay(500);
                  digitalWrite(LedPIN1, 0);
                  digitalWrite(LedPIN2, 0);
                  digitalWrite(LedPIN3, 0);
                  digitalWrite(LedPIN4, 0);
                  digitalWrite(LedPIN5, 0);
                  digitalWrite(LedPIN6, 0);
                  digitalWrite(LedPIN7, 0);
                  digitalWrite(LedPIN8, 0);
                  digitalWrite(LedPIN9, 0);
                  digitalWrite(player1LedPin, 0);
                  delay(500);
                }
           
      resetGame();
      goto zzz;


            }
          }
        }
    }
   
    if ((i < 9) && (winner == 0)) {
      Serial.print("Berikutnya player ");Serial.print(player);Serial.println(", silahkan : ");
      Serial.println();
    }
   
    if (i == 9 && winner == 0) {
      Serial.println("Draw!");
      for (int i = 0; i<2;i++){
        digitalWrite(LedPIN1, 0);
        digitalWrite(LedPIN2, 0);
        digitalWrite(LedPIN3, 0);
        digitalWrite(LedPIN4, 0);
        digitalWrite(LedPIN5, 0);
        digitalWrite(LedPIN6, 0);
        digitalWrite(LedPIN7, 0);
        digitalWrite(LedPIN8, 0);
        digitalWrite(LedPIN9, 0);
        delay(500);
        digitalWrite(LedPIN1, 255);
        digitalWrite(LedPIN1, 255);       
        digitalWrite(LedPIN3, 255);       
        digitalWrite(LedPIN5, 255);       
        digitalWrite(LedPIN7, 255);       
        digitalWrite(LedPIN9, 255);
        delay(500);
      }
        resetGame();
        goto zzz;
    }   
  }
}

char getKey()
{
  char key = 0;
  for(int column = 0; column < numCols; column++)
  {
    digitalWrite(colPins[column],LOW);
    for(int row = 0; row < numRows; row++)
    {
      if(digitalRead(rowPins[row]) == LOW)
      {
        delay(debounceTime);
        while(digitalRead(rowPins[row]) == LOW);
        key = keymap[row][column];
      }
    }
  digitalWrite(colPins[column],255);
  }
  return key;
}


void resetGame(){
  int n = 1;
  for (int i = 0; i<3;i++){
    for (int j = 0; j<3;j++){
      A[i][j]= intToChar(n);
      n++;
    }
  } 
  winner = 0;
  i = 0;  
}

char intToChar(int i){
   switch(i){
     case 1:
       return '1';
       break;
     case 2:
     return '2';
       break;
     case 3:
     return '3';
       break;
     case 4:
     return '4';
       break;
     case 5:
     return '5';
       break;
     case 6:
     return '6';
       break;
     case 7:
     return '7';
       break;
     case 8:
     return '8';
       break;
     case 9:
     return '9';
       break;
     case 0:
     return '0';
       break;
   }
}




Berikut adalah video hasil percobaan.


Ketika pertama kali dijalankan, semua LED pada papan permainan dinyalakan selama beberapa detik untuk memeriksa LED berfungsi atau tidak. Setelah itu, permainan dapat dimulai. Pemain memilih kotak yang diinginkan dengan menekan tombol yang bersangkutan pada keypad. Jika pilihan valid (kotak yang dipilih adalah kotak kosong), LED tersebut akan menyala dan LED indikator pemain akan berpindah. LED untuk player 1 tidak berkedip sementara untuk player 2 berkedip. Jika player 1 menang, semua LED akan berkedip selama beberapa detik secara lambat. Jika player 2 menang, semua LED akan berkedip selama beberapa detik secara cepat. Jika draw, LED akan membentuk pola X dan berkedip selama beberapa detik. Setelah itu permainan akan diulang. Pada rangkaian juga terdapat satu tombol yang berfungsi me-reset permainan.

Rangkaian pada percobaan ini masih memiliki ruang untuk improvisasi. Pada percobaan ini LED untuk membedakan  antara pemain adalah dengan berkedip atau tidak. Cara seperti ini mungkin masih sulit untuk sebagian orang untuk membedakan. Selain itu cahaya yang berkedip dapat memberikan ketidaknyamanan pada mata. Bisa saja cara tersebut diganti dengan warna yang berbeda antara pemain. Hal ini dapat dilakukan dengan LED RGB, yaitu LED yang dapat menghasilkan warna berbeda. Meskipun demikian, rangkaian pada percobaan ini menjadi lebih kompleks karena keterbatasan pin Arduino. Dapat dilihat juga dari video di atas, nyala LED terlalu terang untuk dilihat. Jika dimainkan di tempat gelap, cahaya LED tersebut menjadi semakin tajam. Untuk mengurangi cahaya tersebut dapat ditambahkan resistor ke dalam rangkaian tersebut.

2 komentar:

  1. Komentar ini telah dihapus oleh pengarang.

    BalasHapus
  2. Bagaimana program jika ingin membuat permainan tic ta toe menggunakan button dan hasil outputnya akan keluar di serial monitor?

    BalasHapus