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
- Committer:
- pinofal
- Date:
- 2018-12-04
- Revision:
- 2:1bdcc88f5501
- Child:
- 3:58b0cfe9cc3a
File content as of revision 2:1bdcc88f5501:
#include "mbed.h"
#include "stdlib.h"
#include "SampledSoundBadScore.h"
#include "SampledSoundGoodScore.h"
// numero di Step in cui è suddiviso il gioco
#define GAMESTEPNUMBER 4
// tempo di base tra due step di gioco in [msec]
#define TIMEBETWEEN 5000
// genera un oggetto serial collegato al PC
Serial pc(USBTX, USBRX);
DigitalOut myLed(LED2);
DigitalIn myButton(USER_BUTTON);
// moltiplicatore del tempo in millisecondi
double nMultiplier = 50.0;
Timer myTimer;
// Tempo a disposizione del giocatore per colpire il piezo dopo l'accensiond del LED
int32_t nDelay = 500; // tempo in [msec]
float fDelay = 500.0; // tempo in [msec]
// tempi misurati con il timer
int32_t nStartTimeGame, nElapsedTimeGame, nCurrentTimeGame;
// seme per la generazione di numeri casuali
unsigned int nSeed;
// numero di fade del gioco
int nStepIndex;
// 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
const int naStepDuration[GAMESTEPNUMBER]={1500, 1000, 500, 250}; // tempi in [msec]
// array contenente i punteggi di ciascuno step
int naStepScore[GAMESTEPNUMBER];
// calcola lo score su ogni singolo Step
double fScore;
// indice per la generazione del messaggio di Good Score
int nGoodScoreMsgIndex;
// amplificazione, frequenza e periodo del segnale di Good Score
double fAmpGoodScoreSound;
double fFreqGoodScoreSound;
double fDeltaTGoodScoreSound;
// indice per la generazione del messaggio di Bad Score
int nBadScoreMsgIndex;
// amplificazione, frequenza e periodo del segnale di Bad Score
double fAmpBadScoreSound;
double fFreqBadScoreSound;
double fDeltaTBadScoreSound;
// pulsante su cui bisogna colpire
DigitalIn InPiezo(PA_0);
// output analogico per i messaggi audio
AnalogOut OutWave(PA_4);
/****************************************/
/* Gnerazione AudioMesaggio Good Result */
/****************************************/
void GoodScoreMessage(void)
{
//++++++++++++ INIZIO generazione messaggio di GoodScore +++++++++++++++++
fAmpGoodScoreSound = 1.0; // fissa l'amplificazione per il messaggio di GoodScore. Valori da 0[min] a 1[max]
fFreqGoodScoreSound=nSamplePerSecGoodScore/nUnderSampleFactorGoodScore;// campioni per secondo del GoodScore message da generare = nSamplePerSec/nUnderSampleFactor
fDeltaTGoodScoreSound = (1.0/fFreqGoodScoreSound); // fFreq dipende dal periodo di campionamento e dal fattore di sottocampionamento
for(nGoodScoreMsgIndex=0; nGoodScoreMsgIndex < nSampleNumGoodScore; nGoodScoreMsgIndex++)
{
// mette in output un campione della forma d'onda del GoodScore message moltiplicato per l'amplificazione fAmp
OutWave.write_u16(naInputSoundWaveGoodScore[nGoodScoreMsgIndex]*fAmpGoodScoreSound);
// tra un campione e l'altro attendi un periodo pari al periodo di campionamento
//wait(fDeltaTGoodScoreSound);
wait_us(30);
}
//++++++++++++ FINE generazione messaggio di GoodScore +++++++++++++++++
}
/****************************************/
/* Gnerazione AudioMesaggio Good Result */
/****************************************/
void BadScoreMessage(void)
{
//++++++++++++ INIZIO generazione messaggio di BadScore +++++++++++++++++
fAmpBadScoreSound = 1.0; // fissa l'amplificazione per il messaggio di BadScore. Valori da 0[min] a 1[max]
fFreqBadScoreSound=nSamplePerSecBadScore/nUnderSampleFactorBadScore;// campioni per secondo del BadScore message da generare = nSamplePerSec/nUnderSampleFactor
fDeltaTBadScoreSound = (1.0/fFreqBadScoreSound); // fFreq dipende dal periodo di campionamento e dal fattore di sottocampionamento
for(nBadScoreMsgIndex=0; nBadScoreMsgIndex < nSampleNumBadScore; nBadScoreMsgIndex++)
{
// mette in output un campione della forma d'onda del BadScore message moltiplicato per l'amplificazione fAmp
OutWave.write_u16(naInputSoundWaveBadScore[nBadScoreMsgIndex]*fAmpBadScoreSound);
// tra un campione e l'altro attendi un periodo pari al periodo di campionamento
//wait(fDeltaTBadScoreSound);
wait_us(30);
}
//++++++++++++ FINE generazione messaggio di BadScore +++++++++++++++++
}
/********/
/* MAIN */
/********/
int main()
{
// velocità di comunicazione sulla seriale con PC
pc.baud(921600);
// messaggio di benvenuto
pc.printf("\r\nHallo Amaldi Students - Exercise 16 \r\n");
pc.printf("\r\n*** Let's Play ***\r\n");
// inizialmente spegne LED
myLed=0;
// pc.printf("RANDMAX= %d\r\n", RAND_MAX); // scopi diagnostici
while(true)
{
//++++++ INIZIO Attendi pressione USER_BUTTON per Start Game +++++++
pc.printf("\r\n*** PRESS Blue Button to START ***\r\n");
while(myButton ==1)
{
//myLed = 1;
}
if(myButton ==0)
{
while(myButton ==0){};
//myLed = 0;
//BadScoreMessage();
//GoodScoreMessage();
}
//++++++ FINE Attendi pressione USER_BUTTON per Start Game +++++++
//++++++ INIZIO degli step del gioco +++++++++++++++++++++
myTimer.start(); // avvia il timer
for(nStepIndex =0; nStepIndex < GAMESTEPNUMBER; nStepIndex++)
{
pc.printf("\r\nINIZIO FASE %d\r\n",nStepIndex); // scopi diagnostici
//rand() fissa sempre la stessa sequenza di numeri patendo da 1,
//srand(seed) fissa il numero di partenza, seed, ma la sequenza è sempre la stessa
// per generare una sequenza diversa partendo da un numero diverso il seed lo imposto leggendo l'orologio di sistema (p.e. timer)
// RAND_MAX = 2147483647
nSeed = unsigned(myTimer.read_ms()% RAND_MAX); // resto della divisione timer_read_us() / RAND_MAX
srand(nSeed);
// calcola il tempo da aggiungere come parte variabile al tempo tra uno step e l'altro
fDelay = (nMultiplier * (float(rand()) / RAND_MAX));
// pc.printf("\r\ndelay float = %f\r\n", fDelay); // scopi diagnostici
nDelay = int(fDelay);
pc.printf("delay [msec] = %d\r\n", nDelay); // scopi diagnostici
// se il ritardo è maggiore di 500, dividilo per 3 fino a quando non diventa inferiore a 5000
while(nDelay > 500)
{
nDelay /= 3;
}
// se il ritardo è minore di 100, moltiplicalo per 2 fino a quando non diventa maggiore di 100
while(nDelay < 50)
{
nDelay *= 2;
}
// tra uno step e l'altro attendi (TIMEBETWEEN + nDelay) [msec]. In questo modo il giocatore non può memorizzare i tempi di risposta
wait_ms(TIMEBETWEEN+nDelay);
pc.printf("Tempo tra due step [ms] = %d\r\n", (TIMEBETWEEN+nDelay)); // scopi diagnostici
// Accendi il LED per un tempo pari a una parte fissa in naStepDuration[nStepIndex] e una parte random pari a nDelay
myLed=1; // Accendi LED
nStartTimeGame = myTimer.read_ms();
nElapsedTimeGame=0; // inizializza tempo trascorso
// attendi fino alla pressione del pulsante/piezo oppure al timeout. Il timeout è fissato nell'array naStepDuration[]. mYButton diventa '0' alla pressione
while( (nElapsedTimeGame < naStepDuration[nStepIndex]) && (myButton == 1))
{
// misura il tempo trascorso da StartTimeGame
nCurrentTimeGame = myTimer.read_ms();
nElapsedTimeGame= nCurrentTimeGame-nStartTimeGame;
}
myLed=0; // Spegni LED
// memorizza lo score guadagnato nello Step
naStepScore[nStepIndex] = nElapsedTimeGame;
pc.printf("StepDuration= %d; Elapsed= %d\r\n", naStepDuration[nStepIndex], nElapsedTimeGame); //scopi diagnostici
// calcola lo score in percentuale della durata step. fScore = (durata dello step-tempo trascorso)/ durata dello step.
fScore = ((float)(naStepDuration[nStepIndex] - naStepScore[nStepIndex])/(float)naStepDuration[nStepIndex])*100.0;
pc.printf("Score [%%] %.2f \r\n",fScore); //scopi diagnostici
if(fScore <=0) // il tempo di risposta è stato superiore alla durata
{
// accendi LED RED relativo alla fase in cui ci si trova
pc.printf("BAD :( :( :( \r\n"); // il giocatore ha risposto dopo la scadenza del timer
BadScoreMessage();
}
if((fScore > 0) && (fScore <= 50))
{
// accendi LED YELLOW relativo alla fase in cui ci si trova
pc.printf("SO-SO !!! \r\n"); // il giocatore ha risposto in un tempo intermedio
BadScoreMessage();
}
if(fScore > 50)
{
// accendi LED VERDE relativo alla fase in cui ci si trova
pc.printf("GOOD :) :) :) \r\n"); // il giocatore ha risposto prima della scadenza del timer
GoodScoreMessage();
}
}
}
}