Wednesday 4 August 2021

Wearable Tech - Simon Game - Software

 Objectiu

Programar en una placa Adafruit el joc del Simon.

Material i eines

Farem servir la versió de MakeCode per Adafruit offline, un entorn de programació tipus drag-and-drop que permet rebre informació de la placa i facilita així la resolució dels problemes que puguin sortir per errors de programació.

Aquesta és la versió offline. Es pot fer servir la versió online, però no permet rebre missatges de la placa en funcionament.

Primer pas

Comencem per la part que considero més senzilla, respondre quan l'usuari toca els botons dels pètals.


Tots els botons tenen una programació molt similar. Per qüestions d'ordre, els endreçaré fent una funció i unes llistes. Això en principi pot semblar liós però ens ajudarà a no cometre errors.

Llistes
Per fer una llista, anem a les funcions avançades.


I als valors hi posem els colors que ens agradin en una, i els números de so que ens convinguin a l'altra. Tot dins el bloc "on start", per tenir-les disponibles des del principi del joc.



Funcions
Ara farem una funció que rebrà un número, el del botó que l'usuari ha tocat, i aquest número ens servirà per seleccionar el color i el so de les llistes.
Dins d'Advanced, anem a funcions, escollim un paràmetre (número) i li posem un nom, p.e., "color". (El nom "color" està mal triat, perquè coincideix amb una paraula reservada en Javascript i pot generar conflictes. Jo ho he deixat així, però seria bo anomenar-la amb qualsevol altre nom, com ara "pinta"...)



Posem totes les ordres dins la funció i després la cridem des dels botons, enviant el número de botó com a identificació. Com els elements de les llistes es numeren començant des del 0, el nostre primer botó envia un 0, el segon un 1, i així tots.

La funció fa servir el número per recuperar el color de la llista "colors" i el so de la llista "sons".

És important organitzar el codi en funcions per evitar errors. Si, per exemple, vull canviar la duració del so de 1/2 temps a 1 temps, com he fet, només caldrà que ho canviï a la funció i no a tots els botons, evitant despistar-me i deixar un sense canviar o amb un valor diferent.



Torns i flags
Aquest joc funciona amb dos torns, un per la màquina i un altre pel jugador, així que necessitarem un semàfor per donar pas a un i a l'altre. 

Això ho fem amb el que es coneix com a flag (bandera), que s'implementa amb una variable a la que anomeno "playing". Al principi del joc, playing = 0, quan juga la màquina, playing = 1 i quan li toca a l'usuari, playing = 2.

Modifiquem el bloc "on start" per establir el flag, establir el volum del so desitjat i de pas, iniciar la tira de LEDs, els nostres neopíxels cosits en sèrie, en una variable de nom "strip". Més endavant la farem servir per senyalitzar el nombre de vides i els torns.


Modifiquem els botons de manera que només responguin quan és el torn de l'usuari.


A continuació, programem el botó A, que ens servirà per iniciar el joc, o interrompre'l quan ens cansem. 

Si playing = 0, inicia el joc. Llavors, encenem els 3 primers neopíxels, que ens serviran per visualitzar el nombre de vides, i cridem la funció que inicia el joc. 

Altrament, apaguem tots els LEDs i playing = 0.



La funció "iniciJoc" encén el quart neopíxel de color vermell, senyalitzant així que és el torn de la màquina. A més, dona el valor adequat per a l'inici del joc a les variables "vides" i "playing". 

També inicialitza una llista buida amb anomenada "says". En aquesta llista és on guardem la sèrie aleatòria que genera la màquina i l'usuari ha de recordar. En aquesta llista només guardem números (del 0 al 5), cada un dels quals correspon a un element de les nostres llistes "colors" i "sons". El 0 és el violeta, l'1 el blau...

La variable "nivell" indica el nombre d'elements que hi ha a la llista.

Finalment, crida una altra funció, "ompleSays".



La funció "ompleSays" afegeix un nou element aleatori a la llista, de forma que cada vegada que la cridem s'incrementa en 1 els seus elements. Aquest element és un número entre 0 i 5, i correspon a un dels elements de les nostres llistes "colors" i "sons".

Per saber quin element hem d'afegir, fem servir la variable "nivell", que ens indica quans hi ha i quin ens toca afegir. (Cal recordar que el primer element d'una llista és l'element 0).

En acabat, crida la funció "playSays".



Aquí és quan juga la màquina, reproduint un a un els elements de la llista aleatòria. Per fer-ho la recorre des del seu element número 0 fins a l'últim element que hi hagi (for index from 0 to nivell). La primera vegada, de 0 a 0 només en troba un, però després es va incrementant.

Per reproduir els elements, crida la funció "color", que ja hem codificat abans, i li passa com a paràmetre cada un dels elements que troba a la llista "says". 

A continuació, es prepara per al torn del jugador. Primer, posa la variable "ordreSo" = 0. Aquesta variable ens serveix per saber quina és la resposta que hauria de fer l'usuari. Com ha de reproduir una seqüència, quan comenci volem que premi el botó que correspon al primer element de la llista i després l'anem incrementant per saber quin color/so és el següent.

Posem playing = 2, ja que li toca a l'usuari, i el neopíxel 3 (el quart) de color verd, per senyalitzar que ja pot començar.



Ja no cridem cap més funció, ni que sigui de moment. Esperem a veure què fa l'usuari.

Segons hem programat abans, ara que playing = 2, si prem un botó, s'encendran els píxels del color corresponent i sonarà el so que l'acompanya. 

Només com a recordatori, aquí està de nou la captura.



La funció "color", però, l'haurem de completar. Ara que la cridem quan juga la màquina i quan juga l'usuari, cal distingir entre les dues situacions.


Si playing = 0, no fa res. Altrament, encén els píxels del color que toca i fa el so corresponent. A més, si es el torn de l'usuari, comprova si és l'element correcte de la seqüència. Com ho fa? Amb la funció "comprova" a la que passem com a paràmetre el número de botó que ha premut.

Ara ve quan la liem.

Primer comprovem si ho ha fet be

Si ho ha fet bé i ja ha acabat de repetir la seqüència i llavors li toca a la màquina. 

Si ho ha fet bé però no ha acabat, actualitzem el número de l'element que li toca, i ja està.

I si ho fa malament, perd una vida.



I per acabar, "perdreVida" i si cal, acabar el joc.




Podeu descarregar el codi en aquest link. Si el feu servir, penseu a citar les fonts.