MasterMind, Codice Segreto e Strike & Ball sono nomi diversi per lo stesso gioco di intelligenza che proveremo ad implementare oggi su Arduino.
In quest’epoca di schede grafiche iperottimizzate e di CPU multicore, parlare di videogiochi per Arduino può sembrare sciocco e pretenzioso. Tuttavia esiste un’intera categoria di giochi che consentono una implementazione ottimale con una manciata di righe di codice: si tratta di quei giochi in cui il computer (o il microcontrollore, nel nostro caso) deve occuparsi esclusivamente di gestire le condizioni di gioco e controllare le mosse del giocatore. Quando la logica della strategia è semplice, è persino possibile insegnare al nostro Arduino a giocare contro di noi.
Giocare con Arduino
L’argomento dei videogiochi è un argomento che ci sta particolarmente a cuore. Progettare un videogame obbliga il programmatore a “spremere” ogni ciclo di clock dal sistema sul quale sta lavorando, ottimizzando funzioni e procedure. L’effetto, però è anch’esso esplosivo. Esiste inoltre la possibilità di studiare tattica e strategia, e tentare di applicarla alle nostre macchine.
Purtroppo Arduino non è potentissimo, ed è quindi necessario scegliere con cura codice ed algoritmi. Ad esempio, il nostro Simone ha presentato qualche tempo fa un emulatore di Simon, mentre il sottoscritto ha sviluppato un programma che vi batte senza rimedio a “pari e dispari”.
Oggi presenteremo un altro gioco di tattica, in cui Arduino rappresenterà il giudice delle nostre mosse.
MasterMind e statistica
Mastermind richiede al giocatore di indovinare una sequenza di elementi (cifre o colori) scelta dall’avversario, deducendola dalle risposte ai propri tentativi di indovinarla. Se l’elemento scelto è presente nella sequenza da indovinare, il giudice riporterà un flag bianco, se oltre all’elemento viene indovinata anche la sua posizione, il giudice riporterà un flag nero. Dal momento che gli elementi e le posizioni da indovinare sono limitati, il gioco (se giocato correttamente) ha un termine, ma le combinazioni possibili crescono in modo esponenziale, specie se gli elementi possono ripetersi nella sequenza da indovinare.
Elementi diversi | Sequenza da 3 elementi | Sequenza da 4 elementi | Sequenza da 5 elementi | Sequenza da 6 elementi |
---|---|---|---|---|
6 | 216 | 1296 | 7776 | 46656 |
7 | 343 | 2401 | 16807 | 117649 |
8 | 512 | 4096 | 32768 | 262144 |
10 | 1000 | 10000 | 100000 | 1000000 |
MasterMind utilizza in genere 6 colori ed una sequenza di quattro posizioni. Dal momento che i colori nella sequenza possono ripetersi, avremo quindi 64 = 1296 sequenze possibili. Nei casi più difficili viene consentito anche un settimo “elemento nullo”, portando le sequenze possibili a 74 = 2401. Nel caso del gioco con i numeri (chiamato strike & ball, o bulls & cows, o salamino) abbiamo 10 elementi differenti, ma con una sequenza da indovinare di soli 3 elementi, per complessive 103 = 1000 sequenze diverse. Per quanto appaia controintuitivo, la complessità del gioco è esponenziale, dipende cioè più dal numero degli elementi nella sequenza che dal numero di elementi differenti da scegliere.
La difficoltà consiste nello sfruttare la conoscenza logica delle proprie risposte errate per capire quale sia la sequenza corretta in un massimo di dieci tentativi.
Il programma per Arduino
Come abbiamo anticipato, Arduino terrà la parte del “giudice”, definendo la sequenza da indovinare e fornendo le risposte che verranno fornite dall’utente attraverso l’interfaccia seriale.
Il numero di elementi e la lunghezza della sequenza da indovinare verranno definiti nel codice con costanti: il giocatore potrà modificarne i valori a proprio piacimento prima dell’inizio della partita.
Esaminiamo il codice: nel setup del programma inizializzeremo il sistema Serial attraverso il quale Arduino comunicherà con il giocatore, quindi chiameremo la funzione randomSeed(analogRead(0)) per inizializzare il nostro generatore random, e sceglieremo la sequenza da indovinare attraverso NUM_SEQUENZA chiamate alla funzione random(0, MAX_ELEMENTI).
Nella sezione loop() avremo una sorta di macchina a stati composta come segue:
- input tentativo
- controllo correttezza tentativo
- controllo colore indovinato
- controllo posizione indovinata
- stampa risultato
- controllo numero tentativi
- stampa messaggio finale
Estensioni
Come sempre, il codice sorgente è liberamente scaricabile su github.
Il programma controlla la correttezza sintattica dell’input del giocatore, ne valuta la semantica, e risponde di conseguenza.
E’ possibile estendere il progetto utilizzando un sistema di input/output differente: un LCD, un display TFT, un sistema di servomeccanismi che alzino un flag bianco o nero, un trasmettitore ad infrarossi o ultrasuoni, una serie di pulsanti colorati, una batteria d LED RGB… e magari racchiudere il progetto in un contenutore creato con la propria stampante 3D.
Lasciamo la definizione dei dettagli ai lettori, con la promessa di pubblicare i progetti più meritevoli.
Arrivederci al prossimo articolo!