Els quatre polsadors de l'esquerra de la part inferior serveixen per moure el cursor: esquerra, dreta, avall i amunt. L'altre polsador de la part inferior serveix per acceptar la posició.
El programa és el següent:
#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF #pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF #include "pic16f690.h" // Carrega el fitxer d'adreces i paràmetres del PIC 16F690 #include <xc.h> // Carrega el fitxer de funcions necessari per al compilador XC8 #define boto RA3 // Li assigna un nom a l'adreça del polsador #define _XTAL_FREQ 4000000 // La freqüència del rellotge és 4 MHz
char Sortida[6]; // Valors a enviar al MAX7221 (48 bits)
char Actiu; // Variable que diu quin color està actiu
// Actiu = 0 Apagat
// Actiu = 1 Vermell
// Actiu = 2 Verd
// Actiu = 3 Blau
int k = 1; // Variable que ens manté en el bucle de joc mentre sigui 1
int j; // Variable que utilitzarem per indicar si algu ha guanyat
int Guanyador(char Ocupao[3][3]); // Funció que ens mira la matriu 3x3 i ens comprova si
// algu ha guanyat
char V[8]= {0,0b00000000,0,0,0b00000000,0,0,0b00000000}; // Vector on guardem les posicions
// enceses del jugador 1 (verd)
char B[8]= {0,0b00000000,0,0,0b00000000,0,0,0b00000000}; // El mateix però pel jugador 2 (blau)
char Ocupao[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; // Matriu que utilitzem per saber si esta
// ocupada o no una posició i per
// comprovar si s'ha guanyat o no
char Polsad; // Variable que utilitzem per assignar el valor de la
// funció Polsador()
char torn = 2; // Variable que serveix per saber a quin jugador li toca
// cada vegada
unsigned char Valor = 0b11000000; // Variable que utilitzem per saber la columna en que
// hem d'encendre els LED
unsigned char Filera =1; // Variable que ens situa a la filera corresponent
char Polsador(void); // Funció que ens indica quin polsador BTN estem pulsant // retornant-nos un valor entre 1 i 5 char Estaocupat(char o[3][3],char v, char f); // Funció que ens retorna 1 o 0 si esta ocupada o no // una posició del taulell void Ocupat( char va, char fi); // Aquesta funció escriu el número de la casella on es // superposen dos fitxes, la ja col·locada i la que // s'esta movent void Transcriu1( unsigned char fil, unsigned char val, char v[8], char b[8], char Sortida[6]); // Aquestes dos funcions dibuixen la fitxa que // esta movent el jugador que li toca void Transcriu2( unsigned char fil, unsigned char val, char v[8], char b[8], char Sortida[6]); void Copa(void); // Funció que dibuixa una copa a la matriu // de LED quan hi ha un guanyador void Estatpartida(char t, char p, char q, char r[3][3]); //Funció que guarda la posició que ens diu // Filera i Valor a la matriu 3x3 com a ocupat i // indicant el jugador void Guarda(char x,char y, char z[8]); // Aquesta funció ens guarda al vector[8] la posició // dels LED encesos void Envia3max(char Valor[6]); // Envia un joc de valors als tres MAX7221 void Ini3max(void); // Inicialitza els tres MAX7221 void Apaga(void); // Apaga tots els LED void Tauler(char V[8], char B[8]); // Dibuixa l'estat de la partida amb les fitxes ja col·locades void EnviaL(char Caracter); // Envia un caràcter void Esborra(void); // Esborra la pantalla i posa el cursor a l'inici void Cursor(char Filera, char Columna); // Posiciona el cursor (filera 1 a 2 i columna 1 a 32, // segons pantalla)
void main (void) { // Programa principal
OPTION_REG = 0b10000101; // Configuració de Timer0
// Com a temporitzador basat en rellotge
// 101 - Factor d'escala de 64
// I resistències de pull-up desactivades (valor per defecte)
TRISC = 0; // Tot el port C és de sortida
TRISB = 0; // Tot el port B és de sortida
TRISA = 0xFF; // Tot el port A és d'entrada
ANSEL = 0b00000101; // Configura AN0 i AN2 com entrada analògica
ANSELH = 0; // Desactiva les altres entrades analògiques
PORTC = 0; // Inicialitza a 0 el port C
PORTB = 0; // Inicialitza a 0 el port B
ADCON1 = 0b00010000;
ADCON0 = 0b00001001;
Ini3max(); // Inicialitza els tres MAX7221
Apaga(); // Apaga tots els LED
Actiu = 1; // Activa el color vermell
TMR0 = 139; // Presselecció de 139, que són 117 iteracions
// Correspon a una interrupció cada 7,5 ms
INTCON = 0b10100000; // Activem GIE i T0IE
j=0;
TXSTAbits.BRGH = 1; // Configuració de velocitat
BAUDCTLbits.BRG16 = 0; // Paràmetre de velocitat de 8 bits
SPBRG = 25; // Velocitat de 9600 baud
TXSTAbits.SYNC = 0; // Comunicació asíncrona
TXSTAbits.TX9 = 0; // Comunicació de 8 bits
while(1){
_delay(500000); // Donem temps en cas de que boto, el RA3,
// estigui bloquejat perquè no ens dongui error
while (boto == 1){ // Mentre no s'apreti correctament el boto RA3 estarem
// dins el bucle
Apaga(); // Apaguem la matriu LED per si carregant el programa
// anterior se'ns ha quedat algun LED obert
PORTC = 0b00001111; // En les següents 4 linies fem que els LED vermells
// facin pampallugues
_delay(100000); // estaran més temps encessos que apagats
PORTC = 0b00000000;
_delay(50000);
Esborra(); // Esborra la pantalla i posa el cursor a l'inici
EnviaL('P'); // Escrivim a la pantalla en sèrie LCD 'PREM START'
EnviaL('R'); // a la primera linia i 'PREM' i a la segona 'START'
EnviaL('E');
EnviaL('M');
Cursor(2, 1); // Amb Cursor fem el canvi de linia
EnviaL('S');
EnviaL('T');
EnviaL('A');
EnviaL('R');
EnviaL('T');
_delay(800000);
Esborra(); // Esborrem perquè faci l'efecte de pampallugues però
// a destemps que els LED
}
Tauler(V,B); // Dibuixem el taulell i la fitxa del jugador 1 en la casella 1
Sortida[1] = Filera; // perquè pugui començar a jugar sabent on està
Sortida[3] = Filera;
Sortida[5] = Filera;
Sortida[0] = 0b00100100 | V[Filera] | B[Filera];
Sortida[2] = Valor | V[Filera];
Sortida[4] = B[Filera];
Envia3max(Sortida);
Sortida[1] = Filera + 1;
Sortida[3] = Filera + 1;
Sortida[5] = Filera + 1;
Sortida[0] = 0b00100100 | V[Filera] | B[Filera];
Sortida[2] = Valor | V[Filera];
Sortida[4] = B[Filera];
Envia3max(Sortida);
while (k == 1) {
Polsad = Polsador(); // Llegim els polsadors
if (torn%2==0){ // Indiquem a la pantalla sèrie LCD el torn del jugador
Esborra(); // quan la variable torn és parell juga 1 i 2 quan no
EnviaL('J');
EnviaL('U');
EnviaL('G');
EnviaL('A');
EnviaL('D');
EnviaL('O');
EnviaL('R');
EnviaL(' ');
EnviaL('1');
EnviaL(' ');
if (Estaocupat(Ocupao, Valor, Filera) == 1){
// Si la posició de la fitxa ja està ocupada
Cursor(2,1); // indiquem a la pantalla LCD la posició
// on està perquè
EnviaL('E'); // el jugador no es confongui en
// superposar-se les fitxes
EnviaL('S');
EnviaL('T');
EnviaL('A');
EnviaL('S');
EnviaL(' ');
EnviaL('A');
EnviaL(' ');
Ocupat(Valor, Filera);
}
if (Polsad == 5) { // Es prem el botó BTN5 'OK'
if (Estaocupat(Ocupao, Valor, Filera) == 0){
// Comprovem si la posició està buida
Estatpartida(torn, Valor, Filera, Ocupao);
// Guardem a la matriu 3x3 el valor del
// jugador 1 en aquest
// cas com a senyal de que s'omple la posició
Guarda(Valor,Filera,V); // Guardem la fitxa en el vector[8]
// amb la seva posició
PORTC= 0b00001111; // Encenem els LED vermells com a
// senyal que s'ha premut correctament
j=Guanyador(Ocupao); // Donem valor a la variable j en cas
// d'haver-hi un guanyador
_delay(100000); // Donem temps perquè tot vagi
// correctament i no es polsi més d'una
// vegada el BTN5
torn = torn +1; // Passem el torn al següent jugador
}
}
if (Polsad == 4) { // Premem BTN4
Tauler(V,B); // Pintem la partida tal i com estava fins
// al moment
_delay(200); // Donem temps perquè no s'apreti més d'un cop
if(Filera ==1){ // Si la filera ja està a 1 és que ens hem,
// passat per tant tornarem
Filera=10; // a la fila 10 que al restar-li 3 a
// continuació passarem a la fila 7 del taulell
}
Filera = Filera -3; // Restant 3 a filera movem la fitxa cap amunt
Transcriu1( Filera, Valor, V, B, Sortida);
// Pintem la fitxa que hem desplaçat
} // Aquesta funció només mou les verdes,
// les de jugador 1
if (Polsad == 3) { // Premem BTN3
Tauler(V,B); // Les següents dos línies són igual que
// en l'anterior
_delay(200);
if (Filera == 7){ // En aquest cas si arribem a 7 és que ens
// estem a punt de sortir del taulell
Filera = -2; // així que el tornem a posar a -2 que al
// sumar-li 3 ens posem a dalt de nou
}
Filera = Filera +3; // Sumem 3 per anar en direcció cap aVall
Transcriu1( Filera, Valor, V, B, Sortida);
// Pintem la fitxa que hem desplaçat
}
if (Polsad == 2) { // Premem BTN2
Tauler(V,B); // Les següents dos línies són
// igual que en l'anterior
_delay(200);
Valor = (Valor>>3) |(Valor<<6);
// En aquest cas rotem els bits de la
// variable Valor cap a la dreta
Transcriu1( Filera, Valor, V, B, Sortida);
// Així la fitxa que pintem sortirà
// desplaçada a la dreta
}
if (Polsad == 1) { // Premem BTN1
Tauler(V,B); // Les següents dos línies són igual que
// en l'anterior
_delay(200);
Valor = (Valor<<3) |(Valor>>6);
// En aquest cas rotem els bits de la variable
// Valor cap a l'esquerra
Transcriu1( Filera, Valor, V, B, Sortida);
// Pintem la fitxa que hem desplaçat
}
if (Polsad == 0) { // Si no s'ha premut cap polsador (o dos
// a la vegada)
PORTC=0b00000000;
// Fem que els LED encesos en apretar BTN5
// s'apaguin
if (j==1){ // Comprovem j si al premer BTN5 la funció
// Guanyador li ha donat algun valor
Esborra();
EnviaL('G'); // 1 en el cas de que guanyi el jugador 1
EnviaL('U'); // indiquem el guanyador a la pantalla sèrie
EnviaL('A');
EnviaL('N');
EnviaL('Y');
EnviaL('A');
EnviaL(' ');
EnviaL('1');
EnviaL(' ');
Copa(); // Dibuixem la copa
_delay(2500000); // Donem temps abans de que es reinici
// la partida
k=2; // canviem el valor de k per sortir del bucle
// i tornar a començar
} else if (j==2){
Esborra(); // En el cas de guanyar el jugador 2 j
// pren el valor 2
EnviaL('G'); // indiquem el guanyador a la pantalla sèrie
EnviaL('U');
EnviaL('A');
EnviaL('N');
EnviaL('Y');
EnviaL('A');
EnviaL(' ');
EnviaL('2');
EnviaL(' ');
Copa(); // Dibuixem la copa
_delay(2500000); // Donem temps abans de que es reinici
// la partida
k=2; // canviem el valor de k per sortir del bucle
// i tornar a començar
} else if (torn>=11) { // Quan torn arriba al valor 11 és que
// el taulell està completament pintat
Esborra(); // per tant, la partida dona empat
// i s'ha acabat
EnviaL('E'); // indiquem l'empat a la pantalla sèrie
EnviaL('M');
EnviaL('P');
EnviaL('A');
EnviaL('T');
_delay(2500000); // Donem temps
k=2; // Sortim del bucle
}
}
_delay(200000); // Retard per permetre la visualització
} else{ // Si el torn és senar juga 2
Esborra();
EnviaL('J'); // ho indiquem a la pantalla sèrie
EnviaL('U'); // a partir d'aqui tot és el mateix que
// en el jugador 1
EnviaL('G'); // en aquest cas però la funció
// Transcriu1 és Transcriu2
EnviaL('A'); // una funció que només mou les blaves
EnviaL('D');
EnviaL('O');
EnviaL('R');
EnviaL(' ');
EnviaL('2');
EnviaL(' ');
if (Estaocupat(Ocupao, Valor, Filera) == 1){
Cursor(2,1);
EnviaL('E');
EnviaL('S');
EnviaL('T');
EnviaL('A');
EnviaL('S');
EnviaL(' ');
EnviaL('A');
EnviaL(' ');
Ocupat(Valor, Filera);
}
if (Polsad == 5) {
if (Estaocupat(Ocupao, Valor, Filera) == 0){
Estatpartida(torn,Valor, Filera, Ocupao);
Guarda(Valor,Filera,B);
PORTC= 0b00001111;
j=Guanyador(Ocupao);
_delay(100000);
torn = torn +1;
}
}
if (Polsad == 4) {
Tauler(V,B);
_delay(200);
if(Filera==1){
Filera=10;
}
Filera = Filera -3;
Transcriu2( Filera, Valor, V, B, Sortida);
}
if (Polsad == 3) {
Tauler(V,B);
_delay(200);
if (Filera == 7){
Filera = -2;
}
Filera = Filera +3;
Transcriu2( Filera, Valor, V, B, Sortida);
}
if (Polsad == 2) {
Tauler(V,B);
_delay(200);
Valor = (Valor>>3) |(Valor<<6);
Transcriu2( Filera, Valor, V, B, Sortida);
}
if (Polsad == 1) {
Tauler(V,B);
_delay(200);
Valor = (Valor<<3) |(Valor>>6);
Transcriu2( Filera, Valor, V, B, Sortida);
}
if (Polsad == 0) {
PORTC=0b00000000;
if (j==1){ // Indiquem la victoria del Jugador 1
Esborra(); // amb la variable j que ens retorna
EnviaL('G'); // la funció Guanyador
EnviaL('U');
EnviaL('A');
EnviaL('N');
EnviaL('Y');
EnviaL('A');
EnviaL(' ');
EnviaL('1');
EnviaL(' ');
Copa();
_delay(2500000);
k=2;
} else if (j==2){ // Indiquem la victoria del Jugador 2
Esborra(); // amb la variable j que ens la retorna
EnviaL('G'); // la funció Guanyador
EnviaL('U');
EnviaL('A');
EnviaL('N');
EnviaL('Y');
EnviaL('A');
EnviaL(' ');
EnviaL('2');
EnviaL(' ');
Copa();
_delay(2500000);
k=2;
} else if (torn>=11){ // Si la partida arriba a les 9 tirades
Esborra(); // la partida no pot avançar més i per tant
EnviaL('E'); // s'indicara a la pantalla LED que els
EnviaL('M'); // jugadors han empatat
EnviaL('P');
EnviaL('A');
EnviaL('T');
_delay(2500000);
k=2;
}
}
_delay(200000); // Retard per permetre la visualització
}
}
V[0]=0; // Al sortir del bucle de joc reinicialitzem totes les
V[1]=0b00000000; // variables i el bucle while (1) torna a començar de nou
V[2]=0;
V[3]=0;
V[4]=0b00000000;
V[5]=0;
V[6]=0;
V[7]=0b00000000;
B[0]=0;
B[1]=0b00000000;
B[2]=0;
B[3]=0;
B[4]=0b00000000;
B[5]=0;
B[6]=0;
B[7]=0b00000000;
Ocupao[0][0] = 0;
Ocupao[0][1] = 0;
Ocupao[0][2] = 0;
Ocupao[1][0] = 0;
Ocupao[1][1] = 0;
Ocupao[1][2] = 0;
Ocupao[2][0] = 0;
Ocupao[2][1] = 0;
Ocupao[2][2] = 0;
torn = 2;
Valor = 0b11000000;
Filera = 1;
k = 1;
j = 0;
}
}
void interrupt temporit(void) {
INTCONbits.GIE = 0; // Desactiva les interrupcions momentàniament
if (INTCONbits.T0IF) { // Comprovem que hi ha interrupció per Timer 0
TMR0 = 139; // Preselecció de Timer0
INTCONbits.T0IF = 0; // Desactiva el bit que indica interrupció pel Timer0
if (Actiu != 0) { // Si la matriu no està apagada
Actiu--; // Passem a activar un altre color
if (Actiu == 0) { // Si hem arribat a zero
Actiu = 3; // Torna a posar el 3
}
}
// D'entrada els desactivem els tres
Sortida[0] = 0x00; // Vermell
Sortida[2] = 0x00; // Verd
Sortida[4] = 0x00; // Blau
if (Actiu == 1) { // Si és vermell
Sortida[0] = 0x01; // Vermell activat
}
if (Actiu == 2) { // Si és verd
Sortida[2] = 0x01; // Verd activat
}
if (Actiu == 3) { // Si és blau
Sortida[4] = 0x01; // Blau activat
}
Sortida[1] = 0x0C; // Shutdown mode
Sortida[3] = 0x0C; // Shutdown mode
Sortida[5] = 0x0C; // Shutdown mode
Envia3max(Sortida); // Ho envia al MAX7221
}
INTCONbits.GIE = 1; // Reactiva les interrupcions a l'acabar
}
void Envia3max(char Valor[6]) { // Envia un joc de valors als tres MAX7221
INTCONbits.GIE = 0; // Desactiva les interrupcions momentàniament
char Port = 0; // Variable on guardem l'estat del port B
char Temp; // Variable temporal
for (int j = 5; j >= 0; j--){ // Hem d'enviar 6 bytes
for (int k = 1; k < 9; k++){ // De 8 bits
Temp = Valor[j] & 0b10000000; // Agafa el bit de més a l'esquerra
// Temp només podrà valer 0 o 128
if (Temp == 0) { // Si val 0
Port = Port & 0b11101111; // Desactiva Data (bit 4)
} else { // Si val 128
Port = Port | 0b00010000; // Activa Data (bit 4)
}
Valor[j] = Valor[j] << 1; // Rodem els bits per situar el següent
PORTB = Port; // Ho posa al port B
Port = Port | 0b00100000; // Activa Clock (bit 5) i força lectura
PORTB = Port; // Ho posa al port B
Port = Port & 0b11011111; // Desactiva Clock (bit 5)
PORTB = Port; // Ho posa al port B
}
}
Port = Port | 0b01000000; // Activa Latch (bit 6) per copiar a les sortides
PORTB = Port; // Ho posa al port B
INTCONbits.GIE = 1; // Reactiva les interrupcions a l'acabar
}
void Ini3max(void) { // Inicialitza els tres MAX7221
char Bytes[6]; // Els sis bytes que cal enviar
Bytes[0] = 0x00; // Desactivat
Bytes[1] = 0x0C; // Shutdown mode
Bytes[2] = 0x00;
Bytes[3] = 0x0C;
Bytes[4] = 0x00;
Bytes[5] = 0x0C;
Envia3max(Bytes); // Els envia
Bytes[0] = 0x00; // No decode
Bytes[1] = 0x09; // Decode mode
Bytes[2] = 0x00;
Bytes[3] = 0x09;
Bytes[4] = 0x00;
Bytes[5] = 0x09;
Envia3max(Bytes); // Els envia
Bytes[0] = 0x07; // Vuit fileres
Bytes[1] = 0x0B; // Scan limit
Bytes[2] = 0x07;
Bytes[3] = 0x0B;
Bytes[4] = 0x07;
Bytes[5] = 0x0B;
Envia3max(Bytes); // Els envia
}
void Tauler(char V[8], char B[8]) {
_delay(10000);
Sortida[1] = 0x01; // Aquesta funció ens representa
Sortida[3] = 0x01; // cada vegada la situació de la
Sortida[5] = 0x01; // partida a cada tirada
Sortida[0] = 0b00100100 | V[1] | B[1]; // pintant el taulell i les fitxes
Sortida[2] = V[1]; // ja col·locades
Sortida[4] = B[1];
Envia3max(Sortida);
Sortida[1] = 0x02;
Sortida[3] = 0x02;
Sortida[5] = 0x02;
Sortida[0] = 0b00100100 | V[1] | B[1];
Sortida[2] = V[1];
Sortida[4] = B[1];
Envia3max(Sortida);
Sortida[1] = 0x03;
Sortida[3] = 0x03;
Sortida[5] = 0x03;
Sortida[0] = 0b11111111;
Sortida[2] = 0b00000000;
Sortida[4] = 0b00000000;
Envia3max(Sortida);
Sortida[1] = 0x04;
Sortida[3] = 0x04;
Sortida[5] = 0x04;
Sortida[0] = 0b00100100 | V[4] | B[4];
Sortida[2] = V[4];
Sortida[4] = B[4];
Envia3max(Sortida);
Sortida[1] = 0x05;
Sortida[3] = 0x05;
Sortida[5] = 0x05;
Sortida[0] = 0b00100100 | V[4] | B[4];
Sortida[2] = V[4];
Sortida[4] = B[4];
Envia3max(Sortida);
Sortida[1] = 0x06;
Sortida[3] = 0x06;
Sortida[5] = 0x06;
Sortida[0] = 0b11111111;
Sortida[2] = 0b00000000;
Sortida[4] = 0b00000000;
Envia3max(Sortida);
Sortida[1] = 0x07;
Sortida[3] = 0x07;
Sortida[5] = 0x07;
Sortida[0] = 0b00100100 | V[7] | B[7];
Sortida[2] = V[7];
Sortida[4] = B[7];
Envia3max(Sortida);
Sortida[1] = 0x08;
Sortida[3] = 0x08;
Sortida[5] = 0x08;
Sortida[0] = 0b00100100 | V[7] | B[7];
Sortida[2] = V[7];
Sortida[4] = B[7];
Envia3max(Sortida);
__delay_ms(50);
}
void Apaga(void) { // Apaga tots els LED
char Bytes[6]; // Els sis bytes que cal enviar
for (int j = 0; j <= 8; j++){ // Hem d'enviar 8 fileres
Bytes[1] = j; // Filera
Bytes[3] = j;
Bytes[5] = j;
Bytes[0] = 0x00;
Bytes[2] = 0x00;
Bytes[4] = 0x00;
Envia3max(Bytes);
}
}
char Polsador(void) {
char Pols = 0;
ADCON0bits.GO = 1; // Posa en marxa el conversor
while (ADCON0bits.GO == 1) // Mentre no acabi
; // ens esperem
if (ADRESH < 220 && ADRESH > 200) {
Pols = 1; // Comprova polsador 1
}
if (ADRESH < 194 && ADRESH > 174) {
Pols = 2; // Comprova polsador 2
}
if (ADRESH < 163 && ADRESH > 143) {
Pols = 3; // Comprova polsador 3
}
if (ADRESH < 90 && ADRESH > 70) {
Pols = 4; // Comprova polsador 4
}
if (ADRESH < 55 && ADRESH > 35) {
Pols = 5; // Comprova polsador 5
}
return Pols;
}
void Guarda(char x,char y, char z[8]){ // En aquesta funció guardem la posició de la fitxa
if (x == 0b11000000){ // indicada amb Valor per les columnes i Filera per les files
if (y == 1) z[1]= z[1] | 0b11000000; // (x i y en aquest cas) en un vector de 8 posicions
if (y == 4) z[4]= z[4] | 0b11000000; // una posició per cada fila però com per
// mourens només utilitzem
if (y == 7) z[7]= z[7] | 0b11000000; // les files 1, 4 i 7 així que només
// omplirem aquestes posicions
} // Així doncs per cada Jugador tindrem un vector[8]
// on hi haurà en [1],[4]i[7]
if (x == 0b00011000){ // 0b00000000, amb 0 on estiguin apagats els LED i
if (y == 1) z[1]=z[1] | 0b00011000; // un 1 on hi hagi una fitxa
if (y == 4) z[4]=z[4] | 0b00011000;
if (y == 7) z[7]=z[7] | 0b00011000;
}
if (x == 0b00000011){
if (y == 1) z[1]=z[1] | 0b00000011;
if (y == 4) z[4]=z[4] | 0b00000011;
if (y == 7) z[7]=z[7] | 0b00000011;
}
}
void Estatpartida(char t, char p, char q, char r[3][3]){ // Amb aquesta funció guardem
if (t%2==0){ // la fitxa del jugador a la matriu 3x3
if (p == 0b11000000){ // amb 1 o 2 diferenciant el jugador i
if (q == 1) r[0][0] = 1; // que utilitzarem després per comprovar
if (q == 4) r[1][0] = 1; // si algu ha guanyat o no
if (q == 7) r[2][0] = 1;
}
if (p == 0b00011000){
if (q == 1) r[0][1] = 1;
if (q == 4) r[1][1] = 1;
if (q == 7) r[2][1] = 1;
}
if (p == 0b00000011){
if (q == 1) r[0][2] = 1;
if (q == 4) r[1][2] = 1;
if (q == 7) r[2][2] = 1;
}
} else {
if (p == 0b11000000){
if (q == 1) r[0][0] = 2;
if (q == 4) r[1][0] = 2;
if (q == 7) r[2][0] = 2;
}
if (p == 0b00011000){
if (q == 1) r[0][1] = 2;
if (q == 4) r[1][1] = 2;
if (q == 7) r[2][1] = 2;
}
if (p == 0b00000011){
if (q == 1) r[0][2] = 2;
if (q == 4) r[1][2] = 2;
if (q == 7) r[2][2] = 2;
}
}
}
char Estaocupat(char o[3][3],char v, char f){ // En aquesta funció cridem
if (v == 0b11000000){ // la matriu 3x3 que hem creat
if (f == 1){ // i Filera i Valor per comprovar
if (o[0][0] != 0) return 1; // l'estat de la partida si la
else return 0; // casella esta ocupada o no
}
if (f == 4){
if (o[1][0] != 0) return 1;
else return 0;
}
if (f == 7){
if (o[2][0] != 0) return 1;
else return 0;
}
}
if (v == 0b00011000){
if (f == 1){
if (o[0][1] != 0) return 1;
else return 0;
}
if (f == 4){
if (o[1][1] != 0) return 1;
else return 0;
}
if (f == 7){
if (o[2][1] != 0) return 1;
else return 0;
}
}
if (v == 0b00000011){
if (f == 1){
if (o[0][2] != 0) return 1;
else return 0;
}
if (f == 4){
if (o[1][2] != 0) return 1;
else return 0;
}
if (f == 7){
if (o[2][2] != 0) return 1;
else return 0;
}
}
}
int Guanyador(char c[3][3]){
if (c[0][0]==1 | c[0][0]==2){
if (c[0][0]==c[0][1] & c[0][0]==c[0][2]){ // Cas horitzontal 1,2,3
if (c[0][0]==1){
return 1;
} else{
return 2;
}
}
if (c[0][0]==c[1][0] & c[0][0]==c[2][0]){ // Cas vertical 1,4,7
if (c[0][0]==1){
return 1;
} else{
return 2;
}
}
}
if (c[1][1]==1 | c[1][1]==2){ // Pasem al mig
if (c[1][1]==c[0][0] & c[1][1]==c[2][2]){ // Cas diagonal 1,5,9
if (c[1][1]==1){
return 1;
} else{
return 2;
}
}
if (c[1][1]==c[1][0] & c[1][1]==c[1][2]){ // Cas horitzontal 4,5,6
if (c[1][1]==1){
return 1;
} else{
return 2;
}
}
if (c[1][1]==c[0][1] & c[1][1]==c[2][1]){ // Cas vertical 2,5,7
if (c[1][1]==1){
return 1;
} else{
return 2;
}
}
if (c[1][1]==c[0][2] & c[1][1]==c[2][0]){ // Cas diagonal 3,5,7
if (c[1][1]==1){
return 1;
} else{
return 2;
}
}
if (c[2][2]==1 | c[2][2]==2){ // Passem a baix
if (c[2][2]==c[2][0] & c[2][2]==c[2][1]){ // Cas horitzontal 7,8,9
if (c[2][2]==1){
return 1;
} else{
return 2;
}
}
if (c[2][2]==c[0][2] & c[2][2]==c[1][2]){ // Cas vertical 3,6,9
if (c[2][2]==1){
return 1;
} else{
return 2;
}
}
}
return 0;
}
}
void EnviaL(char Caracter) {
INTCONbits.GIE = 0; // Desactiva les interrupcions momentàniament
RCSTAbits.SPEN = 1; // Activa comunicació sèrie
TXSTAbits.TXEN = 1; // Activa comunicació
TXREG = Caracter; // Agafa el caràcter i l'envia
__delay_ms(1); // Donem temps
while (PIR1bits.TXIF == 0) // Esperem que s'acabi d'enviar
; // No fem res
RCSTAbits.SPEN = 0; // Desactiva comunicació sèrie
TXSTAbits.TXEN = 0; // Desactiva comunicació
INTCONbits.GIE = 1; // Activa les interrupcions
}
void Esborra(void) {
EnviaL(254); // Caràcter de control
EnviaL(1); // Esborra la pantalla i posa el cursor a l'inici
}
void Cursor(char Filera, char Columna) {
char Posicio = 0; // Variable per a calcular la posició
if (Filera == 2) {
Posicio = 64; // La primera columna de la segona fila és 64;
}
if (Columna > 0 && Columna < 33) { // Comprovem que sigui un valor raonable
Posicio = Posicio + Columna; // Sumem les adreces
Posicio = Posicio - 1; // Restem 1 perquè numera des de 0
}
Posicio = Posicio + 128; // Posa el bit de posicionat a 1
EnviaL(254); // Control de la posició del cursor
EnviaL(Posicio); // Canvia el cursor de lloc
}
void Copa(void) { // La funció serveix per dibuixar una copa
Apaga(); // a la matriu LED un cop algu hagi guanyat
_delay(10000); // la partidque s'està jugant
Sortida[1] = 0x02;
Sortida[3] = 0x02;
Sortida[5] = 0x02;
Sortida[0] = 0b01111110;
Sortida[2] = 0b01111110;
Sortida[4] = 0b00000000;
Envia3max(Sortida);
Sortida[1] = 0x03;
Sortida[3] = 0x03;
Sortida[5] = 0x03;
Sortida[0] = 0b01111110;
Sortida[2] = 0b01111110;
Sortida[4] = 0b00000000;
Envia3max(Sortida);
Sortida[1] = 0x04;
Sortida[3] = 0x04;
Sortida[5] = 0x04;
Sortida[0] = 0b00111100;
Sortida[2] = 0b00111100;
Sortida[4] = 0b00000000;
Envia3max(Sortida);
Sortida[1] = 0x05;
Sortida[3] = 0x05;
Sortida[5] = 0x05;
Sortida[0] = 0b00011000;
Sortida[2] = 0b00011000;
Sortida[4] = 0b00000000;
Envia3max(Sortida);
Sortida[1] = 0x06;
Sortida[3] = 0x06;
Sortida[5] = 0x06;
Sortida[0] = 0b00011000;
Sortida[2] = 0b00011000;
Sortida[4] = 0b00000000;
Envia3max(Sortida);
Sortida[1] = 0x07;
Sortida[3] = 0x07;
Sortida[5] = 0x07;
Sortida[0] = 0b00111100;
Sortida[2] = 0b00111100;
Sortida[4] = 0b00000000;
Envia3max(Sortida);
__delay_ms(50); // Retard de 5 milisegons teorics
}
void Transcriu1( unsigned char fil, unsigned char val, char v[8], char b[8], char Sortida[6]){
Sortida[1] = fil; // En aquesta funció enviem les dos files de
Sortida[3] = fil; // de la matriu LED on està la fitxa agafant
Sortida[5] = fil; // filera i valor segons en quina fila i
Sortida[0] = 0b00100100 | v[fil] | b[fil]; // columna hem de pintar la fitxa
Sortida[2] = val | v[fil]; // que estem movent
Sortida[4] = b[fil];
Envia3max(Sortida);
Sortida[1] = fil + 1;
Sortida[3] = fil + 1;
Sortida[5] = fil + 1;
Sortida[0] = 0b00100100 | v[fil] | b[fil];
Sortida[2] = val | v[fil];
Sortida[4] = b[fil];
Envia3max(Sortida);
}
void Transcriu2( unsigned char fil, unsigned char val, char v[8], char b[8], char Sortida[6]){
Sortida[1] = fil; // En aquesta funció fa el mateix que l'anterior
Sortida[3] = fil; // que l'anterior però pel Jugador 2
Sortida[5] = fil;
Sortida[0] = 0b00100100 | v[fil] | b[fil];
Sortida[2] = v[fil];
Sortida[4] = val | b[fil];
Envia3max(Sortida);
Sortida[1] = fil + 1;
Sortida[3] = fil + 1;
Sortida[5] = fil + 1;
Sortida[0] = 0b00100100 | v[fil] | b[fil];
Sortida[2] = v[fil];
Sortida[4] = val | b[fil];
Envia3max(Sortida);
}
void Ocupat( char va, char fi){
Cursor(2, 9); // Utilitzem Cursor(2,9) per escriure sota d'on indiquem
// En aquesta funció enviem a la placa el número
if (va == 0b11000000){ // De la posició on esta la fitxa que no podem visualitzar
if (fi == 1){ // El tauler esta numerat del 1-9 com un mòbil
EnviaL('1'); // 'OCUPAT' que escrivim abans d'entrar a la funció
}
if (fi == 4) {
EnviaL('4');
}
if (fi == 7) {
EnviaL('7');
}
}
if (va == 0b00011000){
if (fi == 1) {
EnviaL('2');
}
if (fi == 4){
EnviaL('5');
}
if (fi == 7){
EnviaL('8');
}
}
if (va == 0b00000011){
if (fi == 1){
EnviaL('3');
}
if (fi == 4){
EnviaL('6');
}
if (fi == 7) {
EnviaL('9');
}
_delay(800);
}
}

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.