TIC-TAC ou Jogo da Velha
Projeto 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?
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 jogadas
byte 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 LEDs
bool salvaMat = LOW; // Controle do qual jogador está ativo
byte linha = 0; // Enderecamento das linhas da matriz
byte coluna = 0; // Enderecamento das colunas da matriz
byte botOn = 0; // Botao foi pressionado
int valor = 0; // Calculo de celula ocupada
int total = 0; // Contador de passadas para evitar loop continuo
unsigned long tempo = 0; // Controle do tempo de botao acionado
unsigned long grava = 800; // Controle do tempo de botão acionado
unsigned long phase1 = 0; // Controle pisca
unsigned long phase2 = 0; // Controle pisca
unsigned long phase3 = 0; // Controle pisca
unsigned long phase4 = 0; // Controle pisca
unsigned long phase5 = 0; // Controle pisca
unsigned long phase6 = 0; // Controle pisca
unsigned long phase7 = 0; // Controle pisca
unsigned long phase8 = 0; // Controle pisca
unsigned long tPisca1 = 70; // Tempo do pisca ON
unsigned long tPisca2 = 50; // Tempo do pisca OFF
unsigned long lampteste = 50; // Tempo de teste dos LEDs
unsigned 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