TIC-TAC ou Jogo da Velha

Projeto TIC-TAC ou Jogo da Velha

Este projeto foi criado para atender o pessoal que está iniciando no Laboratório de Garagem.

Como funciona?

O circuito contém 1 botão para a entrada dos jogadores e 9 LEDs representando o tabuleiro do Jogo da Velha.

Função dos LEDs

Os LEDs, por serem todos vermelhos, para diferencia seus estados, piscam ou ficam em estados diferentes da seguinte forma:

  • LED apagado - não utilizado ainda
  • LED aceso - indica jogada feita pelo jogador 1
  • LED piscando lentamente - indica jogada feita pelo jogador 2
  • LED piscando rapidamente - indica que o LED está para ser escolhido pelo jogador da vez. Este LED poderá ser escolhido e se tornar aceso ou piscante lentamente ou o jogador poderá transferir para outro LED que estiver apagado.

A função do botão

  • Clique simples - seleciona o próximo LED que estiver disponível(desligado), tornando-o rápidamente piscante.
  • Clique longo - pressionando pelo tempo maior do que 5 segundos, indica que o jogador da vez escolheu o LED rapidamente piscante como sua jogada. O LED então, se torna aceso ou lentamente piscante indicando uma jogada feita pelo jogador e em seguida, passa-se a vez do outro jogador. Portando, um dos LEDs disponíveis (apagado) irá piscar rapidamente.
  • Quando algum jogador ganhar, o Arduíno trava, os LED piscarão mais rapidamente indicando que o jogo terminou.
  • Para iniciar novo jogo, basta provocar o RESET do Arduíno.

Abaixo, temos o sketch utilizado:

///*Uso do sketch Ao ligar e depois do teste dos LEDs o primeiro LED fica piscando. O jogador 1 inicia jogando. O jogo inicia posicionado na "casa" 0,0. Ao apertar o botão por um tempo maior que 100 mseg e menor que 1000 mseg, (1 segundo) e libera-lo, a "casa" de jogada avança. Ao segurar o botão pressionado por mais que 1000 mseg, o valor jogado é salvo, e ao soltar o botão os LEDs acendem, e a casa avança, e abre para o jogador 2. A opção de jogo não para em uma casa que já esteja ocupada. Ao completar 3 casas do mesmo jogador, em qq combinação de linha, coluna ou diagonal, o jogo termina. Só inicia novamente com reset do Arduíno. Os LEDS do jogador 1 não piscam Os LEDS do jogador 2 piscam com velocidade = metade da velocidade do "cursor". Ao terminar o jogo, os LEDs do jogador 1 não piscam e o do jogador 2 piscam mais rápidos. Botão ligado ao port A0 e Gnd Cada Leds ligados a cada port através de um resistor de 470 ohms e Gnd.*/#define LA0 2 // Ports para os LEDs#define LA1 3#define LA2 4#define LB0 5#define LB1 6#define LB2 7#define LC0 8#define LC1 9#define LC2 10#define botU A0 // Botao de jogadasbyte mMat1[5][5] = // Matriz para as entradas do jogador 1 e calculos{ {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}};byte mMat2[5][5] = // Matriz para as entradas do jogador 2 e calculos{ {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}};byte mMat3[3][3] = // Matriz temporaria para display{ {0, 0, 0}, {0, 0, 0}, {0, 0, 0},};bool ticTac = 0; // variavel para controle dos LEDsbool salvaMat = LOW; // Controle do qual jogador está ativobyte linha = 0; // Enderecamento das linhas da matrizbyte coluna = 0; // Enderecamento das colunas da matrizbyte botOn = 0; // Botao foi pressionadoint valor = 0; // Calculo de celula ocupadaint total = 0; // Contador de passadas para evitar loop continuounsigned long tempo = 0; // Controle do tempo de botao acionadounsigned long grava = 800; // Controle do tempo de botão acionadounsigned long phase1 = 0; // Controle piscaunsigned long phase2 = 0; // Controle piscaunsigned long phase3 = 0; // Controle piscaunsigned long phase4 = 0; // Controle piscaunsigned long phase5 = 0; // Controle piscaunsigned long phase6 = 0; // Controle piscaunsigned long phase7 = 0; // Controle piscaunsigned long phase8 = 0; // Controle piscaunsigned long tPisca1 = 70; // Tempo do pisca ONunsigned long tPisca2 = 50; // Tempo do pisca OFFunsigned long lampteste = 50; // Tempo de teste dos LEDsunsigned long endGame = 40; // Tempo de pisca no fim do jogo//-----------------------------void setup(){ Serial.begin(9600); // Inicializacao da serial pinMode(botU, INPUT_PULLUP); // Botao como entrada e em pullup pinMode(LA0, OUTPUT); // Ports como saida pinMode(LA1, OUTPUT); pinMode(LA2, OUTPUT); pinMode(LB0, OUTPUT); pinMode(LB1, OUTPUT); pinMode(LB2, OUTPUT); pinMode(LC0, OUTPUT); pinMode(LC1, OUTPUT); pinMode(LC2, OUTPUT); ticTac = 1; // ticTac em HIGH para acender LEDS testaLeds(); // Lamp teste dos LEDs ticTac = 0; // ticTac em LOW para apagar LEDS testaLeds(); // Lamp teste dos LEDs phase1 = millis();}//-----------------------------void loop(){ piscaLED(); // Mostra resultado nos LEDs ckResult(); // Verifica se alguem ganhou while (valor != 0) // Verifica se casa esta ocupada { ckPos(); // Avanca para uma vaga } if (digitalRead(botU) == LOW) // Se botao foi pressionado { delay(40); // Debouncing tempo = millis(); // Atualiza variavel para medir tempo de botão prescionado while (digitalRead(botU) == LOW) // Enquanto o botao estiver pressionado { botOn = 1; // Informa que foi pressionado if (millis() - tempo >= grava) // Verifica se ficou muito tempo pressionado { if (salvaMat == LOW) // Seleciona jogador mMat1[linha][coluna] = 1; // Salva a casa Matriz 1 else // Seleciona jogador mMat2[linha][coluna] = 1; // Salva a casa Matriz 2 salvaMat = !salvaMat; // Troca jogador ckPos(); // Avanca para uma vaga ckVago(); // Verifica se esta vazia while (digitalRead(botU) == LOW) // Enquanto botão estiver pressionado ticTacDisp(); // Mostra leds phase1 = millis(); botOn = 0; // Libera indicador de botao pressionado } } if (botOn == 1) // Se indicador informa botao pressionado { ckPos(); // Avanca para uma vaga ckVago(); // Verifica se esta vazia botOn = 0; // Libera indicador de botao pressionado phase1 = millis(); } if (total >= 9) // Se contador for maior que 9 piscaGeral(); }}//-----------------------------------------------------void ckVago(){ total = 0; // Zera contador de passadas while (valor != 0) // Verifica se tem alguma vaga { total++; // Incrementa contador ckPos(); // Avanca para uma vaga if (total >= 9) // Se contador for maior que 9 valor = 0; // Sai do while }}//----------------------------------------------------void ckPos() // verifica se tem alguma vaga{ coluna++; // Incrementa contador de coluna if (coluna > 2) // Se a coluna for maior que a matriz de dados { coluna = 0; // inicia nova linha linha++; // Incrementa a linha if (linha > 2) // Se a linha for maior que a matriz de dados linha = 0; // inicia nova coluna } valor = mMat1[linha][coluna] + mMat2[linha][coluna]; // Soma valores das casas atuais}//-----------------------------------------------------void cntlPisca1(){ for (int i = 0; i < 3; i++) // Seleciona 3 linhas { for (int j = 0; j < 3; j++) // Seleciona 3 colunas { mMat3[i][j] = mMat1[i][j] || mMat2[i][j]; // Salva copia de OR das jogadas das matrizes } }}//-----------------------------------------------------void cntlPisca2(){ for (int i = 0; i < 3; i++) // Seleciona 3 linhas { for (int j = 0; j < 3; j++) // Seleciona 3 colunas { mMat3[i][j] = mMat1[i][j] ; // Salva copia das jogadas da matriz1 } }}//-----------------------------void ticTacDisp(){ digitalWrite(LA0, mMat3[0][0]); // Le matriz 3 Liga ou desliga o LED conforme digitalWrite(LA1, mMat3[1][0]); digitalWrite(LA2, mMat3[2][0]); digitalWrite(LB0, mMat3[0][1]); digitalWrite(LB1, mMat3[1][1]); digitalWrite(LB2, mMat3[2][1]); digitalWrite(LC0, mMat3[0][2]); digitalWrite(LC1, mMat3[1][2]); digitalWrite(LC2, mMat3[2][2]);}//------------------------------------void testaLeds() // Testa todos LEDs{ digitalWrite(LA0, ticTac); delay(lampteste); digitalWrite(LA1, ticTac); delay(lampteste); digitalWrite(LA2, ticTac); delay(lampteste); digitalWrite(LB0, ticTac); delay(lampteste); digitalWrite(LB1, ticTac); delay(lampteste); digitalWrite(LB2, ticTac); delay(lampteste); digitalWrite(LC0, ticTac); delay(lampteste); digitalWrite(LC1, ticTac); delay(lampteste); digitalWrite(LC2, ticTac); delay(lampteste);}//-----------------------------void ckResult(){ checkMatriz(); // Verifica dados lidos das matrizes for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (mMat1[i][j] == 3 || mMat2[i][j] == 3) // Se tiver algum valor igual a 3 { piscaGeral(); } } }}//----------------------------------------------------void piscaGeral(){ while (1) // Fica em loop mostrando resultado final { cntlPisca1(); ticTacDisp(); delay(endGame); cntlPisca2(); ticTacDisp(); delay(endGame); }}//-----------------------------------------------------void checkMatriz(){ for (int i = 0; i < 3; i++) // Scan de linhas matriz1 { mMat1[i][3] = mMat1[i][0] + mMat1[i][1] + mMat1[i][2]; // Salva soma dos valores lidos } for (int i = 0; i < 3; i++) // Scan de coliunas matriz1 { mMat1[3][i] = mMat1[0][i] + mMat1[1][i] + mMat1[2][i]; // Salva soma dos valores lidos } mMat1[4][0] = mMat1[0][0] + mMat1[1][1] + mMat1[2][2]; // Salva soma dos valores lidos diagonal mMat1[4][1] = mMat1[0][2] + mMat1[1][1] + mMat1[2][0]; // Salva soma dos valores lidos diagonal
for (int i = 0; i < 3; i++) // Scan de linhas matriz2 { mMat2[i][3] = mMat2[i][0] + mMat2[i][1] + mMat2[i][2]; // Salva soma dos valores lidos } for (int i = 0; i < 3; i++) // Scan de coliunas matriz1 { mMat2[3][i] = mMat2[0][i] + mMat2[1][i] + mMat2[2][i]; // Salva soma dos valores lidos } mMat2[4][0] = mMat2[0][0] + mMat2[1][1] + mMat2[2][2]; // Salva soma dos valores lidos diagonal mMat2[4][1] = mMat2[0][2] + mMat2[1][1] + mMat2[2][0]; // Salva soma dos valores lidos diagonal}//-----------------------------------------------------void piscaLED(){ if (millis() - phase1 < tPisca1) { cntlPisca1(); // Salva Or de 2 matrizes na 3a matriz mMat3[linha][coluna] = 1; // Acende Led da jogada ticTacDisp(); // Mostra nos LEDs phase2 = millis(); } else { if (millis() - phase2 < tPisca2) { cntlPisca1(); // Salva Or de 2 matrizes na 3a matriz mMat3[linha][coluna] = 0; // Apaga Led da jogada ticTacDisp(); // Mostra nos LEDs phase3 = millis(); } else { if (millis() - phase3 < tPisca1) { cntlPisca1(); // Salva Or de 2 matrizes na 3a matriz mMat3[linha][coluna] = 1; // Acende Led da jogada ticTacDisp(); // Mostra nos LEDs phase4 = millis(); } else { if (millis() - phase4 < tPisca2) { cntlPisca1(); // Salva matriz jogador 1 na 3a matriz mMat3[linha][coluna] = 0; // Apaga Led da jogada ticTacDisp(); // Mostra nos LEDs phase5 = millis(); } else { if (millis() - phase5 < tPisca1) { cntlPisca2(); // Salva matriz jogador 1a matriz mMat3[linha][coluna] = 1; // Acende Led da jogada ticTacDisp(); // Mostra nos LEDs phase6 = millis(); } else { if (millis() - phase6 < tPisca2) { cntlPisca2(); // Salva matriz jogador 1a matriz mMat3[linha][coluna] = 0; // Apaga Led da jogada ticTacDisp(); // Mostra nos LEDs phase7 = millis(); } else { if (millis() - phase7 < tPisca1) { cntlPisca2(); // Salva matriz jogador 1a matriz mMat3[linha][coluna] = 1; // Acende Led da jogada ticTacDisp(); // Mostra nos LEDs phase8 = millis(); } else { if (millis() - phase8 < tPisca2) { cntlPisca2(); // Salva matriz jogador 1a matriz mMat3[linha][coluna] = 0; // Apaga Led da jogada ticTacDisp(); // Mostra nos LEDs } else { phase1 = millis(); } } } } } } } }}

J_Velha_TicTac.mp4