Non ci sono prodotti a carrello.
Riedizione di un classico gioco elettronico realizzato in chiave moderna con la piccola scheda che rende facile imparare a programmare.
Per quanto oggi siamo letteralmente โbombardatiโ da ogni tipo di videogame, su console, PC e smartphone, esistono giochi comunque suggestivi anche se semplici; ecco perchรฉ abbiamo deciso di proporre in chiave moderna uno dei passatempi piรน famosi al mondo: il Tris.
Un popolarissimo gioco carta e matita, o gessetto e lavagna o ancora meglio giocabile con un bastoncino sulla sabbia, fatto di poche e semplici regole, ma caratterizzato da tanti aspetti curiosi che vogliamo esporvi prima di passare al progetto.
Il gioco del Tris รจ anche noto in Italia come crocetta e pallino, filetto, cerchi e croci, oppure con simboli del tipo OXO o XOXO che riprendono direttamente i simboli utilizzati nel gioco; considerando che รจ universale, in altre parti del mondo รจ noto con altri nomi, per esempio negli Stati Uniti si chiama tic-tac-toe (oppure tick-tat-toe e tit-tat-toe); in Inghilterra รจ โnoughts and crossesโ (zero e croci); in Francia si chiama Morpion (piattola); in Spagna ta-te-ti, tres en raya, gato, equis cero.
Alcune ricerche sostengono che giochi simili fossero giร diffusi nellโantico Egitto e al tempo dei Romani in cui esisteva un gioco chiamato โterni lapilliโ – utilizzato tra i soldati – in cui perรฒ, non venivano usati gli stessi simboli di oggi (X e O).
Il Tris deve sicuramente la sua notorietร e longevitร negli anni alla semplicitร delle sue regole, infatti nella sua accezione piรน generale si gioca su una griglia quadrata di 3×3 caselle e allโinizio del gioco un giocatore sceglie come simbolo una โXโ, mentre lโavversario un โOโ (cerchio); dopodichรฉ a turno, i giocatori scelgono una casella vuota e vi disegnano il proprio simbolo.
Vince il giocatore che riesce a disporre tre dei propri simboli in linea retta orizzontale, verticale od obliqua; per quanto, molto spesso le partite terminano con un pareggio (soprattutto se i giocatori non sono giovanissimi), infatti se la griglia viene riempita senza che nessuno dei giocatori sia riuscito a completare una linea retta di tre simboli, il gioco finisce in paritร e come accade in altri giochi, tanto per citarne uno quello degli scacchi, nel caso in cui il gioco finisse in paritร , la partita รจ detta โpattaโ.
Avendo un numero ridotto di situazioni in cui ci si puรฒ trovare a giocare e una griglia 3×3, รจ possibile implementarlo in un programma per microprocessore o microntrollore, come abbiamo fatto.
Vedremo a breve lโimplementazione su Microbit che tuttavia non sarร fatta con un giocatore โumanoโ contro Microbit ma per semplificare ulteriormente lโimplementazione ed evitare di confrontarsi con un dispositivo che non perderร mai una partita, abbiamo pensato di realizzare il gioco del Tris con una doppia partecipazione umana, ovvero come in origine con carta e matita.
l’hardware per il tris con micro:bit
Prima di passare allโimplementazione software, vediamo il necessario hardware per la corretta gestione di questo progetto, dove utilizziamo micro:bit e un display LCD da 1.8 pollici della Waveshare Electronics mostrato in Fig. 1.
Questo display รจ facilmente assemblabile perchรฉ ha solo ed esclusivamente il connettore dโinterfaccia da collegare al micro:bit e nullโaltro, in piรน offre unโampio display se confrontato con altre soluzioni simili e il driver per la sua gestione รจ direttamente su scheda.
Sulla scheda del display LCD รจ incorporato il controller a interfaccia SPI (Serial Peripheral Interface): si tratta di un chip Sitronix ST7735S che permette di pilotare 162 e 132 canali RGB al fine di abilitare o disabilitare qualsiasi pixel del display LCD.
Tramite il protocollo di comunicazione SPI o con unโinterfaccia parallela da 8bit a 18bit รจ possibile comunicare con un microprocessore esterno e salvare i dati nella memoria RAM disponibile di 132x168x18 bit.
Il controller consente anche di minimizzare i consumi energetici realizzando operazioni di scrittura/lettura senza alcun clock (segnale di temporizzazione) esterno, ma per maggiori dettagli si faccia riferimento al sul datasheet scaricabile on-line.
Per quanto lโarchitettura del sistema sembri semplice, le tecnologie di micro:bit e del display LCD mascherano la complessitร astraendo mediante varie librerie software la complessitร dellโhardware
Le librerie per micro:bit
A questo punto passiamo direttamente allโimplementazione software del sistema.
Tra i software utilizzabili, abbiamo deciso di utilizzare la piattaforma Make Code Block e di importare le librerie messe a disposizione dal produttore del display, per avere tutte le sue funzionalitร immediatamente utilizzabili.
Procedendo per ordine, vediamo come aggiungere tali librerie al programma, con riferimento alla Fig. 2: innanzitutto dallโinterfaccia utente bisogna cliccare sul pulsante a forma dโingranaggio e poi, dal menu cui dร accesso, cliccare su โEstensioniโ (a); nella finestra cui accederete digitate il path https://github.com/waveshare/PXT-WSLCD1in8 (b) ed infine aggiungete la libreria LCD1in8 dedicata a micro:bit v2.
Fatto ciรฒ, la nuova libreria LCD1IN8 comparirร nel pannello principale (c).
Prima di procedere oltre รจ opportuno conoscere le funzioni della libreria che utilizzeremo, per interagire correttamente con il display e che รจ possibile visionare dalla piattaforma di sviluppo tramite un click sul nome della libreria LCD1IN8.
Vediamo quali sono le varie funzioni e i parametri da definire:
- LCD1IN8 Init: consente di inizializzare il display;
- Clear Drawing cache: cancella tutti i dati in RAM;
- Filling Color: consente di definire il colore di background del display;
- LCD Clear: cancella i dati in RAM mostrati su display;
- Show Full Screen: aggiorna il display con i dati disponibili in memoria RAM;
- Set back light level: definisce il livello di intensitร luminosa della retroilluminazione;
- Draw Point: consente di scrivere in memoria RAM le informazioni relative ad un โpuntoโ del quale devono essere definiti i seguenti parametri: coordinata x, y, colore, dimensioni del punto tramite un menรน a tendina;
- Draw Line: consente di scrivere in memoria RAM le informazioni relative ad una linea attraverso la definizione di due punti: coordinata โxโ iniziale, โyโ iniziale, โxโ finale, โyโ finale, (si aggiungono anche: colore, dimensioni e spessore della linea tramite un menรน a tendina);
- Draw Rectangle: consente di scrivere in memoria RAM le informazioni relative ad un rettangolo del quale devono essere forniti i vertici estremi in termini di coordinate x e y: coordinata โxโ iniziale, โyโ iniziale, โxโ finale, โyโ finale, (altre informazioni che รจ necessario definire sono: colore, il tipo di riempimento del rettangolo, spessore della linea tramite un menรน a tendina);
- Draw Circle: consente di scrivere in memoria RAM le informazioni relative ad un cerchio del quale devono essere forniti il centro in termine di coordinate x, y ed il raggio: coordinata โxโ, โyโ, raggio, (in piรน: colore, il tipo di riempimento del cerchio, spessore della linea tramite un menรน a tendina);
- Show Number: consente di scrivere in memoria RAM le informazioni relative ad un numero del quale deve essere fornita la posizione in termine di coordinate x, y ed il colore: coordinata โxโ, โyโ, colore;
- Show String: consente di scrivere in memoria RAM le informazioni relative ad un carattere del quale deve essere fornita la posizione in termine di coordinate x, y ed il colore: coordinata โxโ, โyโ, colore.
La logica
Il progetto, per quanto semplificato a livello hardware richiede unโimportante implementazione dal punto di vista software, per cui risulta fondamentale descrivere le logiche di implementazione; per facilitarne la comprensione รจ buona norma realizzare un flow-chart (diagramma di flusso) che nel caso specifico รจ mostrato in Fig. 3.
La prima fase del programma consiste nellโinizializzazione del display e delle variabili che verranno descritte nel successivo capitolo cosรฌ da migliorare la lettura del programma.
Il successivo blocco di โTrisGame Initโ riguarda le prime istruzioni che guideranno lโutente nella gestione della partita e a tale scopo utilizziamo come riferimento la Fig. 4, che esemplifica ciรฒ che verrร mostrato dal display.
Il display รจ composto da 160×128 pixel pertanto qualsiasi dato puรฒ essere interpretato come la successione di โnโ pixel con il fine di mostrare una parola oppure una figura.
Quindi la prima fase del gioco consiste nel mostrare la stringa โTris GAMEโ e nel guidare lโutente nella successiva azione, ovvero la pressione del โtasto Aโ presente su Microbit. Alla pressione di tale tasto seguono i vari blocchi di inizializzazione partita che consistono nella definizione e scrittura su display della griglia del Tris, del selettore e della prima pedina.
La griglia sarร composta da nove riquadri (come vedevamo prima una griglia 3×3) allโinterno dei quali il selettore (indentificato da un pallino nero) potrร navigare per definire la successiva posizione della pedina.
Con la pressione del tasto โAโ si avrร quanto riportato in Fig. 5.
A questo punto il programma attende la successiva azione utente che consiste nello spostare il selettore e definire la successiva posizione.
La micro:bit rende disponibili due tasti che utilizzeremo per la movimentazione del selettore e il logo touch per confermare lโinserimento della pedina. Il tasto A verrร utilizzato per il movimento verticale mentre il tasto B per il movimento orizzontale che saranno di tipologia endless (senza fine) cosรฌ da garantire la completa movimentazione allโinterno della griglia.
Come visto nellโintroduzione, il gioco del Tris si basa sullo scambio di azioni utente che posizionano le loro pedine al fine di realizzare il Tris ovvero tre pedine consecutive in orizzontale, verticale o diagonale.
Pertanto il turno รจ inizializzato dal player 1 che sposta il selettore tramite i tasti A e B nella posizione desiderata e conferma lโinserimento della pedina tramite il logo touch.
Terminata questa operazione, il programma deve controllare se esistono le condizioni di vittoria altrimenti passa il turno al secondo player che potrร inserire la sua pedina e cosรฌ via.
Le condizioni di vittoria sono indentificate nella Fig. 6 e vengono verificate ogni qual volta una nuova pedina รจ inserita.
I numeri associati ad ogni casella vengono utilizzati per rendere piรน intuiva e semplice la lettura delle combinazioni e torneranno molto utili in fase di implementazione software.
Le linee tratteggiate indicano la sequenzialitร delle caselle e quindi di una condizione di vittoria che puรฒ essere interpretata come combinazione di numeri, ad esempio la linea arancio orizzontale rappresenta la sequenza numerica 0-3-6. Quando le condizioni di vittoria sono verificate, con una delle 8 possibili soluzioni vittoria, la partita puรฒ ritenersi conclusa e sul display verrร mostrato il testo con il vincitore (Fig. 7) altrimenti la partita terminerร con un pareggio.
Implementazione del software per micro:bit
Passiamo alla scrittura del codice tramite la piattaforma di sviluppo Make Code Block analizzando passo-passo le funzioni realizzate in linea con il diagramma di flusso mostrato precedentemente in Fig. 3.
Le prime funzioni realizzate sono eseguite allโinterno della funzione avvio e riguardano i blocchi di inizializzazione display (Display Init), variabili (Variables Init) e gioco del Tris (TrisGame Init).
Per comprendere al meglio le funzioni implementate, utilizziamo come riferimento la Fig. 8 che mostra alcuni parametri molto importanti per la comprensione delle logiche che andremo a descrivere.
La creazione della griglia e della pedina si basa sulla definizione delle coordinate x, y che verranno utilizzate come parametri delle funzioni โdisplayโ:
xI, yI โ indicano le coordinate del pixel dal quale verrร creata la griglia;
xPx, yPy โ indicano le coordinate del pixel dal quale verrร creata la pedina;
xSx, ySy โ indicano le coordinate del selettore;
dim โ rappresenta la dimensione in termini di pixel di ogni quadrante della griglia;
offset โ indica il numero di pixel che distanziano la pedina dalla griglia;
Per facilitare la comprensione del testo utilizzeremo il carattere corsivo per le variabili e il grassetto-corsivo per le funzioni.
Inizializzazione del progetto
Riportiamo in Fig. 9 la lista di variabili che andremo ad utilizzare successivamente e le funzioni adottate:
- Variabili black, blue, white, red e green verranno utilizzate per definire il colore delle pedine e del selettore;
- Variabili _dim e offset_pedina le abbiamo giร descritte;
- Variabili S_base_x e S_base_y sono le coordinate del primo pixel dal quale verrร creata la griglia del Tris;
- Le funzioni set_pawn_position, set_selector_position, set_win_position verranno analizzate nel dettaglio;
- LCD1IN8 Init e Clear Drawing Cache sono funzioni della libreria del display descritte precedentemente, che consentono di configurare i registri interni del dispositivo e di cancellare ogni possibile dato nella memoria volative del display;
Infine utilizziamo la funzione Show String per visualizzare i dati come mostrato nella Fig. 4.
Le funzioni hanno lo scopo di salvare in memoria i dati relativi alle possibili 9 posizioni di pedina e selettore, ma anche le possibili combinazioni di vittoria.
Cominciamo dalla funzione set_pawn_position, in riferimento alla Fig10a, che richiede i parametri start_x, start_y, dim e offset; questi in fase di chiamata verranno identificati rispettivamente con le coordinate della griglia (S_base_x e S_base_y), con la dimensione del quadrante griglia (_dim) ed infine con lโoffset_pedina.
Perciรฒ definiamo la funzione e quindi la creazione delle variabili:
S_pos_x2, S_pos_y2 tengono conto della posizione della griglia e dellโoffset della pedina;
la lista list_pos_pawn sarร riempita con le coordinate della pedina, le quali nella Fig. 8 sono scritte in blu relativamente al pixel per la creazione della pedina per ogni quadrante.
La funzione set_selector_position di Fig. 10 (รจ evidenziata dalla lettera b) utilizza lo stesso metodo della funzione set_pawn_position (a) con la differenza che le coordinate in questione saranno identificate al centro di ogni quadrante come indicato dalle frecce rosse di Fig. 8.
Lโultima funzione set_win_position (la c in Fig. 10) ha lo scopo di raccogliere in un unico array combo_win le possibili combinazioni vittoria con sequenze di tre elementi consecutivi ed in linea con la descrizione definita precedentemente.
Inizio del gioco
In linea con il diagramma di flusso descritto, attendiamo lโazione utente e quindi la pressione del tasto A che dal punto di vista implementativo si traduce nel trascinare la funzione quando premi pulsante A presente nella sezione Fondamentali e definire una macchina a stati; questโultima risulta necessaria in quanto, come dicevamo, il tasto A verrร utilizzato anche per spostare il selettore.
Con riferimento alla Fig. 11 eseguiamo quanto segue.
Aggiungiamo allโinterno della sezione relativa alla pressione tasto un if-else con argomento la variabile btn_A_sts, che in corrispondenza della pressione del tasto A avrร valore 0 e pertanto porterร allโincremento della medesima variabile e della variabile system_sts che rappresenta lo stato del sistema come suggerisce il nome.
Da questo momento in poi, le successive pressioni del tasto andranno ad identificare lo spostamento verticale del selettore che andremo ad analizzare in seguito.
In parallelo la funzione per sempre risulta sempre attiva pertanto risulta necessario, tramite un blocco di if-else con variabile system_sts, assegnare una prioritร alle operazioni da effettuare.
Alla pressione del tasto A, la variabile system_sts assume valore 1 con conseguente creazione della griglia (create_game_base), dopo aver ripulito il display dai dati visualizzati.
Al successivo incremento della variabile system_sts viene creato il selettore e mostrato sulla matrice led del Microbit il numero 1 per indicare il turno del giocatore.
Per la creazione della griglia la funzione create_game_base richiede tre argomenti identificati dalle coordinate e dalla dimensione del quadrante. Come in Fig. 5, decidiamo di utilizzare la libreria del display Draw Line e quindi nella definizione di due punti (quattro coordinate) per ogni linea con lo scopo di rappresentare la griglia attraverso quattro linee.
Tra i parametri occorre:
- impostare Color a 0 (indicativo del colore nero);
- impostare Width al valore DOT_PIXEL_2 cosรฌ da definire una linea piรน spessa;
- impostare Style a LINE_SOLID al fine di definire una linea continua.
Procediamo nella realizzazione del selettore con la funzione create_selector e quindi nellโutilizzo della funzione Draw Point (Fig. 12) che non richiede particolari processi implementativi ma lโassegnazione delle corrispondenti variabili e la dimensione del punto Point Size al valore DOT_PIXEL_4.
In fase di chiamata funzione รจ importante esplicitare le coordinate del punto che dovrร posizionarsi al centro del riquadro (_dim/2) ed il colore che dovrร essere assegnato alla variabile blu inizialmente dichiarata.
Spostamento del selettore
Con lโimplementazione e la creazione del piano di gioco, il sistema rimane in attesa della successiva azione utente che spetterร al giocatore 1 il quale potrร spostare il selettore tramite i tasti A e B della micro:bit.
La nuova posizione del selettore viene definita attraverso quattro variabili che hanno la funzione di identificare le nuove coordinate x e y (pos_x_selector, pos_y_selector) ed avere memoria anche di quelle precedenti tramite pos_x_prev_selector e pos_y_prev_selector.
In corrispondenza della pressione tasto A andremo a salvare le attuali coordinate e incrementare (+1) la coordinata y per la movimentazione verticale; la pressione del tasto B implementa le stesse funzionalitร con la differenza che la variabile da aggiornare (+1) sarร la coordinata x (Fig. 13).
Se lโincremento eccede del valore 2 per entrambe le coordinate allora verrร assegnato il valore 0 cosรฌ da simulare la movimentazione endless.
Lโaggiornamento delle variabili appena descritte determina lโaggiornamento della posizione del selettore, come mostrato in Fig. 14 attraverso la funzione refresh_selector_pos.
Se ricordate, in Fig. 10 (punto b) abbiamo descritto la funzione che consente di creare e riempire la variabile globale list_pos_sel con le possibili coordinate del selettore definendo una lista di 9 elementi contenenti le coordinate x ,y che a questo punto andiamo ad utilizzare allโinterno della nostra funzione, tuttavia per comprendere al meglio la logica da implementare consideriamo la Fig. 15.
List_pos_sel puรฒ essere schematizzato come mostrato, mentre le variabili precedentemente definite pos_x_prev_selector, pos_y_prev_selector, pos_x _selector e pos_y _selector possono assumere i valori da 0 a 2 come evidenziato per la griglia base del Tris, pertanto รจ possibile risalire agli elementi della lista sfruttando la relazione coordinata_x * 3 + coordinata_y che lega un oggetto monodimensionale con un altro bidimensionale quale la matrice.
Supponendo che pos_x _selector e pos_y _selector abbiano entrambi valore 1 (coordinata xS4, yS4), il risultato della relazione sarร 4 che trova corrispondenza nella lista list_pos_sel. Quindi ritornando allโ implementazione di Fig. 14 e facciamo quanto segue.
Creiamo lโarray get_previous_value che dovrร contenere gli elementi x,y della lista list_pos_sel in corrispondenza del risultato della relazione definita tramite le variabili pos_x_prev_selector e pos_y_prev_selector. La funzione leggi valore allโindice รจ disponibile allโinterno della sezione Array.
Utilizziamo la funzione create_selector (precedentemente descritta) che riceve le coordinate contenute in posizione 0 e 1 del vettore get_previous_value ed il colore associato alla variabile white con lo scopo di andare a rimuovere quella che era la posizione precedente del selettore.
Creiamo lโarray get _value che dovrร contenere gli elementi (x,y) della lista list_pos_sel in corrispondenza del risultato della relazione definita tramite le variabili pos_x_selector e pos_y_selector.
Utilizziamo la funzione create_selector che riceve le coordinate contenute in posizione 0 e 1 del vettore get _value ed il colore associato alla variabile blu con lโintento di aggiornare e quindi scrivere su display la nuova posizione del selettore.
Conferma della posizione della pedina
Quando il giocatore di turno decide, tramite il selettore, la successiva posizione che la pedina dovrร assumere, dovrร confermare tale posizione tramite la pressione del logo touch che illustreremo a display attraverso lโimplementazione proposta nella Fig. 16.
Sempre nella sezione Fondamentali รจ possibile trascinare il blocco relativo alla funzione del logo e cosรฌ procedere con lโoperazione di scrittura su display della corrispondente pedina e nella valutazione delle possibili condizioni vittoria.
Per valutare le condizioni di fine partita dopo lโinserimento di una pedina, รจ necessario avere memoria delle posizioni occupate dalle pedine di entrambi i giocatori.
Dal punto di vista implementativo, procediamo con la creazione della variabile index_sel che รจ indicativa della successiva posizione x,y della pedina tramite la relazione coordinata_x * 3 + coordinata_y e della variabile status_pawn_refresh che assume il valore di ritorno della funzione refresh_pawn_pos che consente di verificare se รจ possibile aggiungere la pedina in corrispondenza della posizione del selettore come evidenziato in Fig. 17.
La funzione consiste nella creazione di due vettori che indicheremo con pos_pawn1_busy e pos_pawn2_busy e che hanno lo scopo di tenere traccia delle posizioni (in termini di index_sel) per la pedina del giocatore 1 e del giocatore 2 e quindi:
- aggiungiamo il blocco di if-else per valutare il turno del giocatore;
- verifichiamo se il vettore pos_pawn1_busy contiene elementi tramite la funzione lunghezza array disponibile nella sezione Array e successivamente tramite un ulteriore โifโ verifichiamo che neanche il secondo vettore pos_pawn2_busy contenga la posizione index_sel.; la funzione restituisce il valore 0 se index_sel รจ presente nel vettore pos_pawn2_busy altrimenti aggiunge index_sel in coda al vettore pos_pawn1_busy e restituisce (return) il valore 1;
- nel caso in cui il vettore pos_pawn1_busy contenga giร elementi al suo interno, andiamo a valutare se index_sel รจ giร presente nei due vettori tramite la funzione trova indice di disponibile nella sezione Array e restituisce il valore 1 se lโelemento non รจ presente aggiungendolo index_sel in coda al vettore pos_pawn1_busy altrimenti restituisce il valore 0;
- medesime considerazioni possono essere implementate anche per il secondo giocatore utilizzando il vettore pos_pawn2_busy come mostrato in Fig. 17.
In base al valore restituito e al turno del giocatore riconsideriamo lโimplementazione di Fig. 9, dove attendiamo che una nuova pedina venga inserita (status_pawn_refresh == 1) cosรฌ da estrarre le coordinate dalla lista list_pos_pawn sulla base dellโultimo index_sel aggiunto nella lista pos_pawn1_busy per il giocatore 1 oppure pos_pawn2_busy per il giocatore 2.
Le coordinate vengono assegnate alla variabile get_value e sulla base dei valori x e y presenti allโindirizzo 0 ed 1 viene creata la pedina tramite la funzione create_pawn ed associato il colore rosso nel caso del giocatore 1 ed il colore verde per il giocatore 2.
Dopo la creazione della pedina, cambia il turno del giocatore tramite la variabile player_turn ed il numero mostrato sulla matrice di LED.
Verifica del fine gioco
Dopo aver ultimato la valutazione della posizione index_sel allโinterno dei vettori pos_pawn1_busy e pos_pawn2_busy ed aggiunto la nuova pedina in base al turno del particolare giocatore, รจ necessario procedere con la valutazione delle condizioni di gioco definite allโinterno della funzione verify_end_conditions definita in Fig. 18; tramite essa andremo a valutare se sussistono le condizioni di pareggio o vittoria giocatore 1 o giocatore 2 sulla base delle possibili combinazioni di vittoria.
Il primo passo รจ la creazione della variabile game_sts alla quale verrร assegnato il valore di ritorno della funzione check_win_conditions, che avrร il compito di verificare le condizioni di vittoria in base allโimplementazione definita in Fig. 19.
La prima verifica della funzione check_win_conditions รจ analizzare i vettori pos_pawn1_busy e pos_pawn2_busy ed in particolare verificare che il numero di elementi sia pari a 9 come il numero di quadranti della griglia; in tal caso verrร restituito il valore 0.
Se la prima condizione non รจ rispettata allora รจ necessario verificare che gli elementi dei vettori pos_pawn1_busy e pos_pawn2_busy non contengano una delle combinazioni vittoria definiti (in Fig.10c) tramite il vettore combo_win (con elementi index_sel), che raggruppati in sottoinsiemi di 3 elementi definiscono le combinazioni di vittoria.
Creiamo la variabile win_condition_sts che dovrร essere inizializzata al valore 255 ed aggiungiamo la funzione ripeti disponibile nella sezione Cicli per esaminare ogni elemento del vettore combo_win. In linea con la struttura del vettore, aggiungiamo un blocco if-else con due seguenti condizioni:
- la prima valuta che lโindice i del vettore combo_win sia multiplo di 3, indicando lโinizio di un nuovo insieme di elementi; aggiungiamo la funzione resto di disponibile nella sezione Matematica;
- la seconda si basa sulla valutazione della variabile win_set_index_pawn1, che consente di proseguire con la valutazione del sotto-insieme se una precedente corrispondenza รจ stata riscontrata.
Lo scopo principale della funzione รจ confrontare ogni elemento di una possibile combinazione vittoria con gli elementi del vettore che tengono memoria delle posizioni occupate in termini di index_sel, per ogni giocatore.
Aggiungiamo un blocco ripeti con indice j da 0 alla lunghezza del vettore pos_pawn1_busy, per il giocatore 1 e tramite un blocco if-else, verifichiamo che lโi-esimo elemento del vettore combo_win sia uguale al j-esimo elemento del vettore pos_pawn1_busy.
Se non esiste alcuna occorrenza allora si attende il successivo indice del vettore combo_win multiplo di 3, altrimenti la variabile win_set_index_pawn1 viene aggiornata (+1), interrotto il ciclo โforโ tramite un break e si prosegue con la valutazione del successivo elemento allโinterno del sottogruppo di 3 elementi. Analoga implementazione deve essere fatta per il giocatore 2 e le variabili interessate come win_set_index_pawn2.
Sempre allโinterno del ciclo โforโ del vettore combo_win, creiamo la variabile index_check_win che verrร incrementata di 1 per ogni i-esimo elemento di combo_win ed aggiungiamo un blocco if-else che controllerร il valore di index_check_win uguale a 3, indicando la fine di un sottoinsieme di combinazione vittoria.
Allโinterno del blocco, azzeriamo la variabile index_check_win e verifichiamo il contenuto delle variabili win_set_index_pawn1 e win_set_index_pawn2.
Se il valore รจ inferiore a 3, allora si procederร con il reset al valore zero, altrimenti verrร aggiornata la variabile win_condition_sts al valore 1 per il giocatore 1 oppure al valore 2 per il giocatore 2, con conseguente interruzione del ciclo โforโ (break) e ritorno (return) della variabile win_condition_sts.
Ritornando allโimplementazione di Fig. 18, in base al valore della variabile game_sts e quindi al valore restituito dalla funzione check_win_conditions, andiamo a visualizzare su display lโesito della partita. Il primo blocco if-else verifica che il valore della variabile sia diverso da 255 mentre il successivo if-else analizza il risultato della partita ed in particolare:
- se il valore di game_sts รจ 0 allora saranno presenti le condizioni di pareggio e la variabile str_sts_game verrร impostata al valore โTIEโ e mostrato sulla matrice led del Microbit la lettera T;
- se il valore di game_sts รจ 1 allora il giocatore 1 avrร vinto la partita e la variabile str_sts_game verrร impostata al valore โGIOCATORE 1 WINโ e mostrato sulla matrice led del Microbit la lettera W;
- se il valore di game_sts รจ 2 allora il giocatore 2 avrร vinto la partita e la variabile str_sts_game verrร impostata al valore โGIOCATORE 2 WINโ e mostrato sulla matrice led del Microbit la lettera W.
Al termine deve essere utilizzata la funzione display Show String con argomento la variabile str_sts_game seguita da Show Full Screen per mostrare su display lโesito della partita.
โฆ E ORA SI GIOCA!
Completata la definizione dei blocchi e quindi lโimplementazione software, รจ il momento di giocare. Alcune fasi di gioco sono riportate nella Fig. 20.
Qui vedete le fasi piรน importanti dellโimplementazione descritte nei precedenti paragrafi:
- in (a) sono mostrate le prime informazioni mostrate su display allโavvio con le indicazioni che lโutente dovrร seguire (pressione del tasto A) per iniziare la partita;
- in (b) รจ proposto il risultato dopo la pressione del tasto con la creazione della griglia del gioco Tris ed il posizionamento del selettore;
- in (c) e in (d) vedete le pedine per il giocatore 1 e 2 dopo la pressione del logo touch.
Infine la Fig. 21 mostra una situazione di fine partita con la vittoria del giocatore 1.
Conclusioni
Vi abbiamo guidato nella realizzazione della riedizione โdigitaleโ dello storico gioco del Tris, partendo dalla presentazione del display LCD lato hardware e tutta lโimplementazione lato software, spiegando nei minimi dettagli tutte le fasi, le funzioni e le variabili utilizzate, per dare lโidea della facilitร di realizzazione e di utilizzo della scheda micro:bit; infatti permette, attraverso le sue librerie, di astrarre lโutente dalla complessitร hardware, agevolando soprattutto lโinformatizzazione dei giovani/giovanissimi, avvicinandoli cosรฌ al mondo dellโelettronica.
Buon divertimento con questo gioco e con micro:bit.