Last active
September 3, 2018 23:04
-
-
Save Nemweb/27eda928de2323e0ec19c828e803a52b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// PIC16F628A Configuration Bit Settings | |
// 'C' source line config statements | |
// CONFIG | |
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN) | |
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) | |
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) | |
#pragma config MCLRE = ON // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR) | |
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled) | |
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming) | |
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off) | |
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) | |
#include <xc.h> | |
#define _XTAL_FREQ 4000000 | |
#define SEL PORTAbits.RA3 | |
#define MOVE PORTAbits.RA4 | |
//declara as variáveis necessariamente globais | |
unsigned char verde[3][3], vermelho[3][3], cursor[3][3], linha, conta, cor; | |
bit pisca; | |
//rotina da interrupção | |
void interrupt ISR() | |
{ | |
//confere se a interrupção é devido a overflow no Timer0 | |
if(T0IF) | |
{ | |
//zera o PORTB pra evitar "sombras" nos LEDs | |
PORTB = 0; | |
//ativa o pino do PORTA correspondente a cada linha | |
if(linha == 0) | |
PORTA = 1; | |
else if(linha == 1) | |
PORTA = 2; | |
else if(linha == 2) | |
PORTA = 4; | |
//Lógica para acender cada LED | |
PORTBbits.RB0 = vermelho[linha][0] | (cursor[linha][0] & pisca & cor); | |
PORTBbits.RB1 = vermelho[linha][1] | (cursor[linha][1] & pisca & cor); | |
PORTBbits.RB2 = vermelho[linha][2] | (cursor[linha][2] & pisca & cor); | |
PORTBbits.RB3 = verde[linha][0] | (cursor[linha][0] & pisca & !cor); | |
PORTBbits.RB4 = verde[linha][1] | (cursor[linha][1] & pisca & !cor); | |
PORTBbits.RB5 = verde[linha][2] | (cursor[linha][2] & pisca & !cor); | |
//incrementa a variável linha para que na próxima interrupção a | |
//próxima linha seja ativada | |
linha++; | |
if(linha == 3) | |
linha = 0; | |
//incrementa a variável conta para contar o tempo e fazer o | |
//cursor piscar. | |
conta++; | |
if(conta == 100) | |
{ | |
conta = 0; | |
pisca = !pisca; | |
} | |
//reseta os parâmetros do Timer0 para a interrupção ocorrer novamente | |
T0IF = 0; | |
TMR0 = 131; | |
} | |
} | |
//rotina para verificar se houve uma combinação válida em alguma matriz | |
unsigned char testa_ganhou(unsigned char teste[3][3]) | |
{ | |
//verifica se existe alguma coluna completa | |
if(teste[0][0] && teste[1][0] && teste[2][0]) | |
return 1; | |
if(teste[0][1] && teste[1][1] && teste[2][1]) | |
return 1; | |
if(teste[0][2] && teste[1][2] && teste[2][2]) | |
return 1; | |
//verifica se existe alguma linha completa | |
if(teste[0][0] && teste[0][1] && teste[0][2]) | |
return 1; | |
if(teste[1][0] && teste[1][1] && teste[1][2]) | |
return 1; | |
if(teste[2][0] && teste[2][1] && teste[2][2]) | |
return 1; | |
//verifica as duas diagonais | |
if(teste[0][0] && teste[1][1] && teste[2][2]) | |
return 1; | |
if(teste[0][2] && teste[1][1] && teste[2][0]) | |
return 1; | |
//retorna zero se não há combinação válida | |
return 0; | |
} | |
//rotina para verificar se "deu velha" | |
//(todas as posições marcadas e ninguém ganhou) | |
unsigned char testa_velha(unsigned char teste1[3][3], unsigned char teste2[3][3]) | |
{ | |
unsigned char i, j, soma; | |
soma = 0; | |
//soma o valor de todas as posições das duas matrizes | |
//se todas as 9 posições estiverem completas, o valor dá nove, | |
//indicando que deu velha | |
for(i = 0; i < 3; i++) | |
{ | |
for(j = 0; j < 3; j++) | |
soma += teste1[i][j] + teste2[i][j]; | |
} | |
if(soma == 9) | |
return 1; | |
else | |
return 0; | |
} | |
//zera todas as posições na matriz | |
void limpa_matriz(unsigned char matriz[3][3]) | |
{ | |
unsigned char i, j; | |
for(i = 0; i < 3; i++) | |
{ | |
for(j = 0; j < 3; j++) | |
matriz[i][j] = 0; | |
} | |
} | |
void main(void) | |
{ | |
//cria as variáveis locais | |
unsigned char i, j, posicao, MOVE_Old, SEL_Old, pontuacao_vermelho, pontuacao_verde; | |
//inicializa as matrizes e variáveis | |
limpa_matriz(verde); | |
limpa_matriz(vermelho); | |
limpa_matriz(cursor); | |
pisca = 1; | |
linha = 0; | |
posicao = 0; | |
MOVE_Old = 1; | |
SEL_Old = 1; | |
cursor[0][0] = 1; | |
cor = 0; | |
pontuacao_vermelho = 0; | |
pontuacao_verde = 0; | |
//configura o PIC | |
CMCON = 0xFF; | |
VRCON = 0; | |
TRISA = 0x18; | |
TRISB = 0x00; | |
PORTA = 1; | |
PORTB = 0; | |
OPTION_REG = 0xC2; | |
TMR0 = 131; | |
INTCON = 0xA0; | |
T0IF = 0; | |
while(1) | |
{ | |
//testa se o botão que move o cursor está pressionado agora | |
//mas não estava antes. Isso impede que ele se mova várias vezes em uma | |
//unica pressionada. Se for verdade, muda a posição | |
//e limpa a posição anterior. | |
if(MOVE == 0 && MOVE_Old == 1) | |
{ | |
cursor[posicao/3][posicao%3] = 0; | |
posicao++; | |
if(posicao == 9) | |
posicao = 0; | |
cursor[posicao/3][posicao%3] = 1; | |
MOVE_Old = 0; | |
} | |
//verifica se o jogador soltou o botão | |
if(MOVE == 1 && MOVE_Old == 0) | |
MOVE_Old = 1; | |
//Marca na matriz correspondente a posição da jogada | |
//caso o jogador tenha pressionado o botão de jogada | |
if(SEL == 0 && SEL_Old == 1) | |
{ | |
if(cor == 0 && vermelho[posicao/3][posicao%3] == 0 && verde[posicao/3][posicao%3] == 0) | |
{ | |
verde[posicao/3][posicao%3] = 1; | |
cor = 1; | |
} | |
else if(cor == 1 && verde[posicao/3][posicao%3] == 0 && vermelho[posicao/3][posicao%3] == 0 ) | |
{ | |
vermelho[posicao/3][posicao%3] = 1; | |
cor = 0; | |
} | |
cursor[posicao/3][posicao%3] = 0; | |
posicao++; | |
if(posicao == 9) | |
posicao = 0; | |
cursor[posicao/3][posicao%3] = 1; | |
SEL_Old = 0; | |
} | |
//verifica se o jogador soltou o botão | |
if(SEL == 1 && SEL_Old == 0) | |
SEL_Old = 1; | |
//confere se o jogador da cor verde ganhou | |
//se sim, mostra a pontuação com efeito, | |
//reseta as matrizes e as variáveis de controle | |
if(testa_ganhou(verde)) | |
{ | |
limpa_matriz(vermelho); | |
limpa_matriz(verde); | |
limpa_matriz(cursor); | |
pontuacao_verde++; | |
cor = 0; | |
for(i = 0; i < pontuacao_verde; i++) | |
{ | |
verde[i/3][i%3] = 1; | |
__delay_ms(200); | |
} | |
__delay_ms(1000); | |
if(pontuacao_verde == 9) | |
{ | |
for(i = pontuacao_verde+1; i > 0; i--) | |
{ | |
verde[(i-1)/3][(i-1)%3] = 0; | |
__delay_ms(100); | |
} | |
pontuacao_vermelho = 0; | |
pontuacao_verde = 0; | |
} | |
__delay_ms(500); | |
limpa_matriz(verde); | |
linha = 0; | |
posicao = 0; | |
cursor[0][0] = 1; | |
cor = 1; | |
} | |
//confere se o jogador da cor vermelha ganhou | |
//se sim, mostra a pontuação com efeito, | |
//reseta as matrizes e as variáveis de controle | |
if(testa_ganhou(vermelho)) | |
{ | |
limpa_matriz(vermelho); | |
limpa_matriz(verde); | |
limpa_matriz(cursor); | |
pontuacao_vermelho++; | |
cor = 1; | |
for(i = 0; i < pontuacao_vermelho; i++) | |
{ | |
vermelho[i/3][i%3] = 1; | |
__delay_ms(200); | |
} | |
__delay_ms(1000); | |
if(pontuacao_vermelho == 9) | |
{ | |
for(i = pontuacao_vermelho+1; i > 0; i--) | |
{ | |
vermelho[(i-1)/3][(i-1)%3] = 0; | |
__delay_ms(100); | |
} | |
pontuacao_vermelho = 0; | |
pontuacao_verde = 0; | |
} | |
__delay_ms(500); | |
limpa_matriz(vermelho); | |
linha = 0; | |
posicao = 0; | |
cursor[0][0] = 1; | |
cor = 0; | |
} | |
//confere se deu velha | |
//se sim, apaga a matriz por um segundo, | |
//reseta as matrizes e as variáveis de controle | |
if(testa_velha(verde, vermelho)) | |
{ | |
limpa_matriz(verde); | |
limpa_matriz(vermelho); | |
limpa_matriz(cursor); | |
__delay_ms(1000); | |
linha = 0; | |
posicao = 0; | |
cursor[0][0] = 1; | |
cor = 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment