Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Game.cpp@2:1bdcc88f5501, 2018-12-04 (annotated)
- Committer:
- pinofal
- Date:
- Tue Dec 04 13:45:23 2018 +0000
- Revision:
- 2:1bdcc88f5501
- Child:
- 3:58b0cfe9cc3a
Game rev2
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| pinofal | 2:1bdcc88f5501 | 1 | #include "mbed.h" |
| pinofal | 2:1bdcc88f5501 | 2 | #include "stdlib.h" |
| pinofal | 2:1bdcc88f5501 | 3 | #include "SampledSoundBadScore.h" |
| pinofal | 2:1bdcc88f5501 | 4 | #include "SampledSoundGoodScore.h" |
| pinofal | 2:1bdcc88f5501 | 5 | |
| pinofal | 2:1bdcc88f5501 | 6 | // numero di Step in cui è suddiviso il gioco |
| pinofal | 2:1bdcc88f5501 | 7 | #define GAMESTEPNUMBER 4 |
| pinofal | 2:1bdcc88f5501 | 8 | |
| pinofal | 2:1bdcc88f5501 | 9 | // tempo di base tra due step di gioco in [msec] |
| pinofal | 2:1bdcc88f5501 | 10 | #define TIMEBETWEEN 5000 |
| pinofal | 2:1bdcc88f5501 | 11 | |
| pinofal | 2:1bdcc88f5501 | 12 | // genera un oggetto serial collegato al PC |
| pinofal | 2:1bdcc88f5501 | 13 | Serial pc(USBTX, USBRX); |
| pinofal | 2:1bdcc88f5501 | 14 | |
| pinofal | 2:1bdcc88f5501 | 15 | DigitalOut myLed(LED2); |
| pinofal | 2:1bdcc88f5501 | 16 | DigitalIn myButton(USER_BUTTON); |
| pinofal | 2:1bdcc88f5501 | 17 | |
| pinofal | 2:1bdcc88f5501 | 18 | // moltiplicatore del tempo in millisecondi |
| pinofal | 2:1bdcc88f5501 | 19 | double nMultiplier = 50.0; |
| pinofal | 2:1bdcc88f5501 | 20 | Timer myTimer; |
| pinofal | 2:1bdcc88f5501 | 21 | |
| pinofal | 2:1bdcc88f5501 | 22 | // Tempo a disposizione del giocatore per colpire il piezo dopo l'accensiond del LED |
| pinofal | 2:1bdcc88f5501 | 23 | int32_t nDelay = 500; // tempo in [msec] |
| pinofal | 2:1bdcc88f5501 | 24 | float fDelay = 500.0; // tempo in [msec] |
| pinofal | 2:1bdcc88f5501 | 25 | |
| pinofal | 2:1bdcc88f5501 | 26 | // tempi misurati con il timer |
| pinofal | 2:1bdcc88f5501 | 27 | int32_t nStartTimeGame, nElapsedTimeGame, nCurrentTimeGame; |
| pinofal | 2:1bdcc88f5501 | 28 | |
| pinofal | 2:1bdcc88f5501 | 29 | // seme per la generazione di numeri casuali |
| pinofal | 2:1bdcc88f5501 | 30 | unsigned int nSeed; |
| pinofal | 2:1bdcc88f5501 | 31 | |
| pinofal | 2:1bdcc88f5501 | 32 | // numero di fade del gioco |
| pinofal | 2:1bdcc88f5501 | 33 | int nStepIndex; |
| pinofal | 2:1bdcc88f5501 | 34 | |
| pinofal | 2:1bdcc88f5501 | 35 | // tempo in [msec] di ciascuna fase. Per la fase numero nStepIndex, il LED viene acceso per il tempo naStepDuration[nStepIndex] e entro tale tempo fovrà arrivare la risposta del giocatore |
| pinofal | 2:1bdcc88f5501 | 36 | const int naStepDuration[GAMESTEPNUMBER]={1500, 1000, 500, 250}; // tempi in [msec] |
| pinofal | 2:1bdcc88f5501 | 37 | |
| pinofal | 2:1bdcc88f5501 | 38 | // array contenente i punteggi di ciascuno step |
| pinofal | 2:1bdcc88f5501 | 39 | int naStepScore[GAMESTEPNUMBER]; |
| pinofal | 2:1bdcc88f5501 | 40 | |
| pinofal | 2:1bdcc88f5501 | 41 | // calcola lo score su ogni singolo Step |
| pinofal | 2:1bdcc88f5501 | 42 | double fScore; |
| pinofal | 2:1bdcc88f5501 | 43 | |
| pinofal | 2:1bdcc88f5501 | 44 | |
| pinofal | 2:1bdcc88f5501 | 45 | // indice per la generazione del messaggio di Good Score |
| pinofal | 2:1bdcc88f5501 | 46 | int nGoodScoreMsgIndex; |
| pinofal | 2:1bdcc88f5501 | 47 | |
| pinofal | 2:1bdcc88f5501 | 48 | // amplificazione, frequenza e periodo del segnale di Good Score |
| pinofal | 2:1bdcc88f5501 | 49 | double fAmpGoodScoreSound; |
| pinofal | 2:1bdcc88f5501 | 50 | double fFreqGoodScoreSound; |
| pinofal | 2:1bdcc88f5501 | 51 | double fDeltaTGoodScoreSound; |
| pinofal | 2:1bdcc88f5501 | 52 | // indice per la generazione del messaggio di Bad Score |
| pinofal | 2:1bdcc88f5501 | 53 | int nBadScoreMsgIndex; |
| pinofal | 2:1bdcc88f5501 | 54 | |
| pinofal | 2:1bdcc88f5501 | 55 | // amplificazione, frequenza e periodo del segnale di Bad Score |
| pinofal | 2:1bdcc88f5501 | 56 | double fAmpBadScoreSound; |
| pinofal | 2:1bdcc88f5501 | 57 | double fFreqBadScoreSound; |
| pinofal | 2:1bdcc88f5501 | 58 | double fDeltaTBadScoreSound; |
| pinofal | 2:1bdcc88f5501 | 59 | |
| pinofal | 2:1bdcc88f5501 | 60 | |
| pinofal | 2:1bdcc88f5501 | 61 | // pulsante su cui bisogna colpire |
| pinofal | 2:1bdcc88f5501 | 62 | DigitalIn InPiezo(PA_0); |
| pinofal | 2:1bdcc88f5501 | 63 | // output analogico per i messaggi audio |
| pinofal | 2:1bdcc88f5501 | 64 | AnalogOut OutWave(PA_4); |
| pinofal | 2:1bdcc88f5501 | 65 | |
| pinofal | 2:1bdcc88f5501 | 66 | /****************************************/ |
| pinofal | 2:1bdcc88f5501 | 67 | /* Gnerazione AudioMesaggio Good Result */ |
| pinofal | 2:1bdcc88f5501 | 68 | /****************************************/ |
| pinofal | 2:1bdcc88f5501 | 69 | void GoodScoreMessage(void) |
| pinofal | 2:1bdcc88f5501 | 70 | { |
| pinofal | 2:1bdcc88f5501 | 71 | //++++++++++++ INIZIO generazione messaggio di GoodScore +++++++++++++++++ |
| pinofal | 2:1bdcc88f5501 | 72 | fAmpGoodScoreSound = 1.0; // fissa l'amplificazione per il messaggio di GoodScore. Valori da 0[min] a 1[max] |
| pinofal | 2:1bdcc88f5501 | 73 | fFreqGoodScoreSound=nSamplePerSecGoodScore/nUnderSampleFactorGoodScore;// campioni per secondo del GoodScore message da generare = nSamplePerSec/nUnderSampleFactor |
| pinofal | 2:1bdcc88f5501 | 74 | fDeltaTGoodScoreSound = (1.0/fFreqGoodScoreSound); // fFreq dipende dal periodo di campionamento e dal fattore di sottocampionamento |
| pinofal | 2:1bdcc88f5501 | 75 | |
| pinofal | 2:1bdcc88f5501 | 76 | |
| pinofal | 2:1bdcc88f5501 | 77 | for(nGoodScoreMsgIndex=0; nGoodScoreMsgIndex < nSampleNumGoodScore; nGoodScoreMsgIndex++) |
| pinofal | 2:1bdcc88f5501 | 78 | { |
| pinofal | 2:1bdcc88f5501 | 79 | // mette in output un campione della forma d'onda del GoodScore message moltiplicato per l'amplificazione fAmp |
| pinofal | 2:1bdcc88f5501 | 80 | OutWave.write_u16(naInputSoundWaveGoodScore[nGoodScoreMsgIndex]*fAmpGoodScoreSound); |
| pinofal | 2:1bdcc88f5501 | 81 | |
| pinofal | 2:1bdcc88f5501 | 82 | // tra un campione e l'altro attendi un periodo pari al periodo di campionamento |
| pinofal | 2:1bdcc88f5501 | 83 | //wait(fDeltaTGoodScoreSound); |
| pinofal | 2:1bdcc88f5501 | 84 | wait_us(30); |
| pinofal | 2:1bdcc88f5501 | 85 | } |
| pinofal | 2:1bdcc88f5501 | 86 | //++++++++++++ FINE generazione messaggio di GoodScore +++++++++++++++++ |
| pinofal | 2:1bdcc88f5501 | 87 | } |
| pinofal | 2:1bdcc88f5501 | 88 | |
| pinofal | 2:1bdcc88f5501 | 89 | /****************************************/ |
| pinofal | 2:1bdcc88f5501 | 90 | /* Gnerazione AudioMesaggio Good Result */ |
| pinofal | 2:1bdcc88f5501 | 91 | /****************************************/ |
| pinofal | 2:1bdcc88f5501 | 92 | void BadScoreMessage(void) |
| pinofal | 2:1bdcc88f5501 | 93 | { |
| pinofal | 2:1bdcc88f5501 | 94 | //++++++++++++ INIZIO generazione messaggio di BadScore +++++++++++++++++ |
| pinofal | 2:1bdcc88f5501 | 95 | fAmpBadScoreSound = 1.0; // fissa l'amplificazione per il messaggio di BadScore. Valori da 0[min] a 1[max] |
| pinofal | 2:1bdcc88f5501 | 96 | fFreqBadScoreSound=nSamplePerSecBadScore/nUnderSampleFactorBadScore;// campioni per secondo del BadScore message da generare = nSamplePerSec/nUnderSampleFactor |
| pinofal | 2:1bdcc88f5501 | 97 | fDeltaTBadScoreSound = (1.0/fFreqBadScoreSound); // fFreq dipende dal periodo di campionamento e dal fattore di sottocampionamento |
| pinofal | 2:1bdcc88f5501 | 98 | |
| pinofal | 2:1bdcc88f5501 | 99 | |
| pinofal | 2:1bdcc88f5501 | 100 | for(nBadScoreMsgIndex=0; nBadScoreMsgIndex < nSampleNumBadScore; nBadScoreMsgIndex++) |
| pinofal | 2:1bdcc88f5501 | 101 | { |
| pinofal | 2:1bdcc88f5501 | 102 | // mette in output un campione della forma d'onda del BadScore message moltiplicato per l'amplificazione fAmp |
| pinofal | 2:1bdcc88f5501 | 103 | OutWave.write_u16(naInputSoundWaveBadScore[nBadScoreMsgIndex]*fAmpBadScoreSound); |
| pinofal | 2:1bdcc88f5501 | 104 | |
| pinofal | 2:1bdcc88f5501 | 105 | // tra un campione e l'altro attendi un periodo pari al periodo di campionamento |
| pinofal | 2:1bdcc88f5501 | 106 | //wait(fDeltaTBadScoreSound); |
| pinofal | 2:1bdcc88f5501 | 107 | wait_us(30); |
| pinofal | 2:1bdcc88f5501 | 108 | } |
| pinofal | 2:1bdcc88f5501 | 109 | //++++++++++++ FINE generazione messaggio di BadScore +++++++++++++++++ |
| pinofal | 2:1bdcc88f5501 | 110 | } |
| pinofal | 2:1bdcc88f5501 | 111 | |
| pinofal | 2:1bdcc88f5501 | 112 | /********/ |
| pinofal | 2:1bdcc88f5501 | 113 | /* MAIN */ |
| pinofal | 2:1bdcc88f5501 | 114 | /********/ |
| pinofal | 2:1bdcc88f5501 | 115 | int main() |
| pinofal | 2:1bdcc88f5501 | 116 | { |
| pinofal | 2:1bdcc88f5501 | 117 | // velocità di comunicazione sulla seriale con PC |
| pinofal | 2:1bdcc88f5501 | 118 | pc.baud(921600); |
| pinofal | 2:1bdcc88f5501 | 119 | |
| pinofal | 2:1bdcc88f5501 | 120 | // messaggio di benvenuto |
| pinofal | 2:1bdcc88f5501 | 121 | pc.printf("\r\nHallo Amaldi Students - Exercise 16 \r\n"); |
| pinofal | 2:1bdcc88f5501 | 122 | pc.printf("\r\n*** Let's Play ***\r\n"); |
| pinofal | 2:1bdcc88f5501 | 123 | |
| pinofal | 2:1bdcc88f5501 | 124 | |
| pinofal | 2:1bdcc88f5501 | 125 | // inizialmente spegne LED |
| pinofal | 2:1bdcc88f5501 | 126 | myLed=0; |
| pinofal | 2:1bdcc88f5501 | 127 | |
| pinofal | 2:1bdcc88f5501 | 128 | // pc.printf("RANDMAX= %d\r\n", RAND_MAX); // scopi diagnostici |
| pinofal | 2:1bdcc88f5501 | 129 | |
| pinofal | 2:1bdcc88f5501 | 130 | while(true) |
| pinofal | 2:1bdcc88f5501 | 131 | { |
| pinofal | 2:1bdcc88f5501 | 132 | //++++++ INIZIO Attendi pressione USER_BUTTON per Start Game +++++++ |
| pinofal | 2:1bdcc88f5501 | 133 | pc.printf("\r\n*** PRESS Blue Button to START ***\r\n"); |
| pinofal | 2:1bdcc88f5501 | 134 | while(myButton ==1) |
| pinofal | 2:1bdcc88f5501 | 135 | { |
| pinofal | 2:1bdcc88f5501 | 136 | //myLed = 1; |
| pinofal | 2:1bdcc88f5501 | 137 | } |
| pinofal | 2:1bdcc88f5501 | 138 | if(myButton ==0) |
| pinofal | 2:1bdcc88f5501 | 139 | { |
| pinofal | 2:1bdcc88f5501 | 140 | while(myButton ==0){}; |
| pinofal | 2:1bdcc88f5501 | 141 | //myLed = 0; |
| pinofal | 2:1bdcc88f5501 | 142 | //BadScoreMessage(); |
| pinofal | 2:1bdcc88f5501 | 143 | //GoodScoreMessage(); |
| pinofal | 2:1bdcc88f5501 | 144 | } |
| pinofal | 2:1bdcc88f5501 | 145 | //++++++ FINE Attendi pressione USER_BUTTON per Start Game +++++++ |
| pinofal | 2:1bdcc88f5501 | 146 | |
| pinofal | 2:1bdcc88f5501 | 147 | //++++++ INIZIO degli step del gioco +++++++++++++++++++++ |
| pinofal | 2:1bdcc88f5501 | 148 | myTimer.start(); // avvia il timer |
| pinofal | 2:1bdcc88f5501 | 149 | for(nStepIndex =0; nStepIndex < GAMESTEPNUMBER; nStepIndex++) |
| pinofal | 2:1bdcc88f5501 | 150 | { |
| pinofal | 2:1bdcc88f5501 | 151 | pc.printf("\r\nINIZIO FASE %d\r\n",nStepIndex); // scopi diagnostici |
| pinofal | 2:1bdcc88f5501 | 152 | |
| pinofal | 2:1bdcc88f5501 | 153 | //rand() fissa sempre la stessa sequenza di numeri patendo da 1, |
| pinofal | 2:1bdcc88f5501 | 154 | //srand(seed) fissa il numero di partenza, seed, ma la sequenza è sempre la stessa |
| pinofal | 2:1bdcc88f5501 | 155 | // per generare una sequenza diversa partendo da un numero diverso il seed lo imposto leggendo l'orologio di sistema (p.e. timer) |
| pinofal | 2:1bdcc88f5501 | 156 | // RAND_MAX = 2147483647 |
| pinofal | 2:1bdcc88f5501 | 157 | nSeed = unsigned(myTimer.read_ms()% RAND_MAX); // resto della divisione timer_read_us() / RAND_MAX |
| pinofal | 2:1bdcc88f5501 | 158 | srand(nSeed); |
| pinofal | 2:1bdcc88f5501 | 159 | // calcola il tempo da aggiungere come parte variabile al tempo tra uno step e l'altro |
| pinofal | 2:1bdcc88f5501 | 160 | fDelay = (nMultiplier * (float(rand()) / RAND_MAX)); |
| pinofal | 2:1bdcc88f5501 | 161 | // pc.printf("\r\ndelay float = %f\r\n", fDelay); // scopi diagnostici |
| pinofal | 2:1bdcc88f5501 | 162 | nDelay = int(fDelay); |
| pinofal | 2:1bdcc88f5501 | 163 | pc.printf("delay [msec] = %d\r\n", nDelay); // scopi diagnostici |
| pinofal | 2:1bdcc88f5501 | 164 | |
| pinofal | 2:1bdcc88f5501 | 165 | // se il ritardo è maggiore di 500, dividilo per 3 fino a quando non diventa inferiore a 5000 |
| pinofal | 2:1bdcc88f5501 | 166 | while(nDelay > 500) |
| pinofal | 2:1bdcc88f5501 | 167 | { |
| pinofal | 2:1bdcc88f5501 | 168 | nDelay /= 3; |
| pinofal | 2:1bdcc88f5501 | 169 | } |
| pinofal | 2:1bdcc88f5501 | 170 | |
| pinofal | 2:1bdcc88f5501 | 171 | // se il ritardo è minore di 100, moltiplicalo per 2 fino a quando non diventa maggiore di 100 |
| pinofal | 2:1bdcc88f5501 | 172 | while(nDelay < 50) |
| pinofal | 2:1bdcc88f5501 | 173 | { |
| pinofal | 2:1bdcc88f5501 | 174 | nDelay *= 2; |
| pinofal | 2:1bdcc88f5501 | 175 | } |
| pinofal | 2:1bdcc88f5501 | 176 | // tra uno step e l'altro attendi (TIMEBETWEEN + nDelay) [msec]. In questo modo il giocatore non può memorizzare i tempi di risposta |
| pinofal | 2:1bdcc88f5501 | 177 | wait_ms(TIMEBETWEEN+nDelay); |
| pinofal | 2:1bdcc88f5501 | 178 | pc.printf("Tempo tra due step [ms] = %d\r\n", (TIMEBETWEEN+nDelay)); // scopi diagnostici |
| pinofal | 2:1bdcc88f5501 | 179 | |
| pinofal | 2:1bdcc88f5501 | 180 | // Accendi il LED per un tempo pari a una parte fissa in naStepDuration[nStepIndex] e una parte random pari a nDelay |
| pinofal | 2:1bdcc88f5501 | 181 | myLed=1; // Accendi LED |
| pinofal | 2:1bdcc88f5501 | 182 | nStartTimeGame = myTimer.read_ms(); |
| pinofal | 2:1bdcc88f5501 | 183 | nElapsedTimeGame=0; // inizializza tempo trascorso |
| pinofal | 2:1bdcc88f5501 | 184 | // attendi fino alla pressione del pulsante/piezo oppure al timeout. Il timeout è fissato nell'array naStepDuration[]. mYButton diventa '0' alla pressione |
| pinofal | 2:1bdcc88f5501 | 185 | while( (nElapsedTimeGame < naStepDuration[nStepIndex]) && (myButton == 1)) |
| pinofal | 2:1bdcc88f5501 | 186 | { |
| pinofal | 2:1bdcc88f5501 | 187 | // misura il tempo trascorso da StartTimeGame |
| pinofal | 2:1bdcc88f5501 | 188 | nCurrentTimeGame = myTimer.read_ms(); |
| pinofal | 2:1bdcc88f5501 | 189 | nElapsedTimeGame= nCurrentTimeGame-nStartTimeGame; |
| pinofal | 2:1bdcc88f5501 | 190 | } |
| pinofal | 2:1bdcc88f5501 | 191 | myLed=0; // Spegni LED |
| pinofal | 2:1bdcc88f5501 | 192 | // memorizza lo score guadagnato nello Step |
| pinofal | 2:1bdcc88f5501 | 193 | naStepScore[nStepIndex] = nElapsedTimeGame; |
| pinofal | 2:1bdcc88f5501 | 194 | |
| pinofal | 2:1bdcc88f5501 | 195 | pc.printf("StepDuration= %d; Elapsed= %d\r\n", naStepDuration[nStepIndex], nElapsedTimeGame); //scopi diagnostici |
| pinofal | 2:1bdcc88f5501 | 196 | |
| pinofal | 2:1bdcc88f5501 | 197 | // calcola lo score in percentuale della durata step. fScore = (durata dello step-tempo trascorso)/ durata dello step. |
| pinofal | 2:1bdcc88f5501 | 198 | fScore = ((float)(naStepDuration[nStepIndex] - naStepScore[nStepIndex])/(float)naStepDuration[nStepIndex])*100.0; |
| pinofal | 2:1bdcc88f5501 | 199 | pc.printf("Score [%%] %.2f \r\n",fScore); //scopi diagnostici |
| pinofal | 2:1bdcc88f5501 | 200 | |
| pinofal | 2:1bdcc88f5501 | 201 | if(fScore <=0) // il tempo di risposta è stato superiore alla durata |
| pinofal | 2:1bdcc88f5501 | 202 | { |
| pinofal | 2:1bdcc88f5501 | 203 | // accendi LED RED relativo alla fase in cui ci si trova |
| pinofal | 2:1bdcc88f5501 | 204 | pc.printf("BAD :( :( :( \r\n"); // il giocatore ha risposto dopo la scadenza del timer |
| pinofal | 2:1bdcc88f5501 | 205 | BadScoreMessage(); |
| pinofal | 2:1bdcc88f5501 | 206 | } |
| pinofal | 2:1bdcc88f5501 | 207 | if((fScore > 0) && (fScore <= 50)) |
| pinofal | 2:1bdcc88f5501 | 208 | { |
| pinofal | 2:1bdcc88f5501 | 209 | // accendi LED YELLOW relativo alla fase in cui ci si trova |
| pinofal | 2:1bdcc88f5501 | 210 | pc.printf("SO-SO !!! \r\n"); // il giocatore ha risposto in un tempo intermedio |
| pinofal | 2:1bdcc88f5501 | 211 | BadScoreMessage(); |
| pinofal | 2:1bdcc88f5501 | 212 | } |
| pinofal | 2:1bdcc88f5501 | 213 | if(fScore > 50) |
| pinofal | 2:1bdcc88f5501 | 214 | { |
| pinofal | 2:1bdcc88f5501 | 215 | // accendi LED VERDE relativo alla fase in cui ci si trova |
| pinofal | 2:1bdcc88f5501 | 216 | pc.printf("GOOD :) :) :) \r\n"); // il giocatore ha risposto prima della scadenza del timer |
| pinofal | 2:1bdcc88f5501 | 217 | GoodScoreMessage(); |
| pinofal | 2:1bdcc88f5501 | 218 | } |
| pinofal | 2:1bdcc88f5501 | 219 | |
| pinofal | 2:1bdcc88f5501 | 220 | } |
| pinofal | 2:1bdcc88f5501 | 221 | |
| pinofal | 2:1bdcc88f5501 | 222 | } |
| pinofal | 2:1bdcc88f5501 | 223 | } |