El joc vol imitar, amb les limitacions que imposa la pantalla, la pantalla Tip Toe del joc Fall Guys. En la primera fase del joc, un dels contrincants dissenya un camí entre la part inferior de la pantalla i la superior; en la segona part, l'altre jugador ha de trobar el camí i torna a l'origen si no l'encerta.

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 <xc.h> #define _XTAL_FREQ 4000000 #define cic_int 5 #define SOFT_TX PORTCbits.RC0 #define SOFT_RX PORTCbits.RC1 #define MAX_MOVES 11
char Port; char Compta; char Sortida[6]; char Sorti[6]; char Actiu; char Polsad; char figura[8][8]; char progres[8][8]; signed char y = 7; signed char x = 4; signed char start_x = 4; signed char last_x = 4; signed char last_y = 7; char mirar = 1; char compt_int = 0; char cur_on = 1; char color = 10; char mov_perm = 1; char primera_pintada = 0; char joc_acabat = 0; char pas_realitzat = 0; char rival_llest = 0; char moves_count = 0; char fase = 1; char inici_torn_f2 = 0;
void Envia3max(char Valor[]); void Envia_max(void); void Ini3max(void); void Apaga(void); char Polsador(void); void TxSoft(char b); char RxSoft_Wait(void); void Intercanvi(void); void ResetJoc(void);
void main (void) {
OPTION_REG = 0b10000101;
TRISB = 0;
TRISA = 0xFF;
TRISC = 0b00000010;
PORTC = 0;
SOFT_TX = 1;
ANSEL = 0b00000101;
ANSELH = 0;
PORTB = 0;
ADCON1 = 0b00010000;
ADCON0 = 0b00001001;
Ini3max();
Actiu = 10;
TMR0 = 100;
INTCON = 0b10100000;
ResetJoc();
while (1) {
if (PORTAbits.RA3 == 0) {
__delay_ms(20);
if (PORTAbits.RA3 == 0) {
ResetJoc();
while(PORTAbits.RA3 == 0);
}
}
if (joc_acabat == 1 && rival_llest == 0) {
TxSoft('F');
__delay_ms(10);
if (SOFT_RX == 0) {
char rebut = RxSoft_Wait();
if (rebut == 'F') {
rival_llest = 1;
}
}
}
if (joc_acabat == 1 && rival_llest == 1) {
Intercanvi();
rival_llest = 2;
joc_acabat = 2;
}
Polsad = Polsador();
if (joc_acabat == 0) {
if (fase == 1) {
if (mirar == 1){
if (Polsad == 5) {
__delay_ms(50);
if (primera_pintada == 0) {
figura[y][x] = color;
primera_pintada = 1;
start_x = x;
last_x = x;
last_y = y;
moves_count = 0;
pas_realitzat = 1;
} else {
if (x != last_x || y != last_y) {
char moves_left = MAX_MOVES - moves_count;
if (moves_left > 0) {
figura[y][x] = color;
last_x = x;
last_y = y;
moves_count++;
}
}
}
if (y == 0) {
fase = 2;
x = 4;
y = 7;
mirar = 1; mov_perm = 1;
inici_torn_f2 = 1;
for(int j=0; j<8; j++)
for(int k=0; k<8; k++)
progres[j][k] = 0;
} else {
while(Polsador() == 5);
mirar = 0; mov_perm = 1;
}
}
if (mov_perm == 1) {
signed char next_x = x;
signed char next_y = y;
char intent_moviment = 0;
if (Polsad == 1) { next_x++; intent_moviment = 1; }
if (Polsad == 2) { next_x--; intent_moviment = 1; }
if (Polsad == 3) { next_y--; intent_moviment = 1; }
if (Polsad == 4) { next_y++; intent_moviment = 1; }
if (intent_moviment == 1) {
if (next_x >= 0 && next_x <= 7 && next_y >= 0 && next_y <= 7) {
char valid = 0;
if (primera_pintada == 0) {
if (next_y == 7 && (Polsad == 1 || Polsad == 2)) valid = 1;
} else {
char moves_left = MAX_MOVES - moves_count;
char steps_to_goal = last_y;
if (moves_left <= steps_to_goal) {
if (next_x == last_x && next_y == (last_y - 1)) {
valid = 1;
}
} else {
signed char dif_x = (signed char)((next_x > last_x) ? (next_x - last_x) : (last_x - next_x));
signed char dif_y = (signed char)((next_y > last_y) ? (next_y - last_y) : (last_y - next_y));
if ((dif_x + dif_y) <= 1) {
if (figura[next_y][next_x] == 0 || (next_x == last_x && next_y == last_y)) {
valid = 1;
}
}
}
}
if (valid == 1) {
x = next_x;
y = next_y;
mov_perm = 0; mirar = 0;
}
}
}
}
} else {
if (Polsad == 0) { mirar = 1; mov_perm = 1; }
}
} else if (fase == 2) {
if (mov_perm == 1) {
if (Polsad == 1 && x < 7) { x++; mov_perm = 0; }
if (Polsad == 2 && x > 0) { x--; mov_perm = 0; }
if (inici_torn_f2 == 0) {
if (Polsad == 3 && y > 0) { y--; mov_perm = 0; }
if (Polsad == 4 && y < 7) { y++; mov_perm = 0; }
}
}
if (Polsad == 0) mov_perm = 1;
if (Polsad == 5) {
__delay_ms(50);
if (figura[y][x] != 0) {
progres[y][x] = color;
inici_torn_f2 = 0;
if (y == 0) joc_acabat = 1;
} else {
x = 4;
y = 7;
inici_torn_f2 = 1;
for(int j=0; j<8; j++)
for(int k=0; k<8; k++)
progres[j][k] = 0;
__delay_ms(200);
}
while(Polsador() == 5);
}
}
}
for (signed char j = 0; j < 8; j++){
char mascara;
char col;
Sortida[0] = 0; Sortida[2] = 0; Sortida[4] = 0;
for (signed char k = 0; k < 8; k++){
char dada_memoria;
if (fase == 1) dada_memoria = figura[j][k];
else dada_memoria = progres[j][k];
if ((y == j) && (x == k) && joc_acabat == 0){
if (cur_on == 1){
col = color;
if (col == dada_memoria) col = 1;
} else {
col = dada_memoria;
}
} else {
col = dada_memoria;
}
mascara = col & 0b0000001;
Sortida[0] = Sortida[0] | (mascara << k);
mascara = (col & 0b0000010) >> 1;
Sortida[2] = Sortida[2] | (mascara << k);
mascara = (col & 0b0000100) >> 2;
Sortida[4] = Sortida[4] | (mascara << k);
}
Sortida[1] = (char)(j+1);
Sortida[3] = (char)(j+1);
Sortida[5] = (char)(j+1);
Envia3max(Sortida);
}
__delay_ms(1);
compt_int++;
if (compt_int == cic_int){
compt_int = 0;
cur_on = (cur_on + 1) % 2;
}
}
}
void __interrupt() temporit(void){
if (INTCONbits.T0IF) {
TMR0 = 100;
INTCONbits.T0IF = 0;
if (Actiu != 0) {
Actiu--;
if (Actiu == 0) Actiu = 3;
}
Sorti[0] = 0x00; Sorti[2] = 0x00; Sorti[4] = 0x00;
if (Actiu == 1) Sorti[0] = 0x01;
if (Actiu == 2) Sorti[2] = 0x01;
if (Actiu == 3) Sorti[4] = 0x01;
Sorti[1] = 0x0C; Sorti[3] = 0x0C; Sorti[5] = 0x0C;
Envia_max();
}
}
void ResetJoc(void) {
Apaga();
for (signed char j = 0; j < 8; j++){
for (signed char k = 0; k < 8; k++){
figura[j][k] = 0;
progres[j][k] = 0;
}
}
moves_count = 0;
fase = 1;
primera_pintada = 0;
start_x = 4;
x = 4; y = 7;
last_x = 4;
last_y = 7;
joc_acabat = 0;
rival_llest = 0;
inici_torn_f2 = 0;
mov_perm = 1;
mirar = 1;
}
void TxSoft(char b) {
SOFT_TX = 0;
__delay_us(104);
for(int i=0; i<8; i++) {
if(b & 1) SOFT_TX = 1;
else SOFT_TX = 0;
b >>= 1;
__delay_us(100);
}
SOFT_TX = 1;
__delay_us(104);
}
char RxSoft_Wait(void) {
char d = 0;
__delay_us(150);
for(int i=0; i<8; i++) {
if(SOFT_RX) d |= (1<<i);
__delay_us(100);
}
return d;
}
void Intercanvi(void) {
INTCONbits.GIE = 0;
__delay_ms(100);
for(signed char j=0; j<8; j++) {
for(signed char k=0; k<8; k++) {
TxSoft(figura[j][k]);
while(SOFT_RX == 1);
figura[j][k] = RxSoft_Wait();
__delay_ms(2);
}
}
INTCONbits.GIE = 1;
}
void Envia3max(char Valor[]) {
INTCONbits.T0IE = 0;
char Port_Temp = 0;
char Temp;
for (signed char j = 5; j >= 0; j--){
for (signed char k = 1; k < 9; k++){
Temp = Valor[j] & 0b10000000;
if (Temp == 0) Port_Temp = Port_Temp & 0b11101111;
else Port_Temp = Port_Temp | 0b00010000;
Valor[j] = Valor[j] << 1;
PORTB = Port_Temp;
Port_Temp = Port_Temp | 0b00100000;
PORTB = Port_Temp;
Port_Temp = Port_Temp & 0b11011111;
PORTB = Port_Temp;
}
}
Port_Temp = Port_Temp | 0b01000000;
PORTB = Port_Temp;
INTCONbits.T0IE = 1;
}
void Envia_max(void) {
asm("banksel _Port");
asm("bcf (_Port&7fh),5");
asm("bcf (_Port&7fh),6");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
asm("banksel _Compta");
asm("movlw 48");
asm("movwf (_Compta&7fh)");
asm("Bucle:");
asm("banksel _Port");
asm("bcf (_Port&7fh),4");
asm("banksel _Sorti");
asm("rlf (_Sorti&7fh),f");
asm("rlf ((_Sorti+1)&7fh),f");
asm("rlf ((_Sorti+2)&7fh),f");
asm("rlf ((_Sorti+3)&7fh),f");
asm("rlf ((_Sorti+4)&7fh),f");
asm("rlf ((_Sorti+5)&7fh),f");
asm("banksel _Port");
asm("btfsc STATUS,0");
asm("bsf (_Port&7fh),4");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
asm("banksel _Port");
asm("bsf (_Port&7fh),5");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
asm("banksel _Port");
asm("bcf (_Port&7fh),5");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
asm("banksel _Compta");
asm("decfsz (_Compta&7fh),f");
asm("goto (Bucle&7ffh)");
asm("banksel _Port");
asm("bsf (_Port&7fh),6");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
}
void Ini3max(void) {
char Bytes[6];
Bytes[0] = 0x00; Bytes[1] = 0x0C; Bytes[2] = 0x00;
Bytes[3] = 0x0C; Bytes[4] = 0x00; Bytes[5] = 0x0C;
Envia3max(Bytes);
Bytes[0] = 0x00; Bytes[1] = 0x09; Bytes[2] = 0x00;
Bytes[3] = 0x09; Bytes[4] = 0x00; Bytes[5] = 0x09;
Envia3max(Bytes);
Bytes[0] = 0x07; Bytes[1] = 0x0B; Bytes[2] = 0x07;
Bytes[3] = 0x0B; Bytes[4] = 0x07; Bytes[5] = 0x0B;
Envia3max(Bytes);
}
void Apaga(void) {
char Bytes[6];
for (unsigned char j = 1; j <= 8; j++){
Bytes[1] = j; 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;
while (ADCON0bits.GO == 1);
if (ADRESH < 220 && ADRESH > 200) Pols = 1;
if (ADRESH < 194 && ADRESH > 174) Pols = 2;
if (ADRESH < 163 && ADRESH > 143) Pols = 3;
if (ADRESH < 90 && ADRESH > 70) Pols = 4;
if (ADRESH < 55 && ADRESH > 35) Pols = 5;
return Pols;
}

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