Un goto sans goto?

Bonjour à tous,
J'ai lu un peu partout que la fonction goto n'était pas du tout préconisé dans la programmation.
Seulement je ne vois pas du tout comment la remplacer?

Je m'explique, c'est pour un jeu pour enfant.
Au bout d'un certain temps dans le jeu (à partir de //programme DT), il faut que l'enfant bouche un petit trou parmis 3 (dans lequel il y a une photoresistance) pendant 1 à 10 sec.
Si il le fait bien pendant le temps imparti, un message "good" s'affiche et retour au début du programme.
Par contre si il ne la bouche pas bien, il ne laisse pas sa main ou la mal positionnée, une led rouge s'allume et retour au début du programme.

Comment puis-je programmer ce comportement sans goto?

Voici la partie intéressante de mon code:

// DÉBUT DU PROGRAMME DT

tpsprogdt = random (1000, 10000); ////////// DIF

PR = random (1, 3); ////////// DIF
valphoto = analogRead (photoR [PR]);

previousmillispm = currentmillis;
while (currentmillis - previousmillisdt < tpsprogdt){

Serial.println (PR);

if (valphoto < 500){
void notgood ();
goto debut;
}

delay (10);
}

Serial.println ("GOOD");
void reward ();

debut:

}
}

Merci beaucoup pour votre aide!

Yep!

previousmillis = millis();  
  while (millis() - previousmillis < tpsprogdt){ 
    Serial.println(PR);
    if (valphoto < 500){ flag = 1; break; }
    //delay (10);
  }
  if (flag) { void notgood (); }
  else { 
  Serial.println ("GOOD");
  void reward ();
  }
  
  flag = 0;
}

Grosso modo, la variable flag (int ou boolean) aura la valeur 1 si la condition est remplie pendant le laps de temps. Le break sert à casser la boucle et on teste hors de la boucle la valeur du flag.
On doit pouvoir faire la même chose à l'intérieur de la boucle.

Deux petites choses, je suppose que si le detecteur a une valeur inférieure à 500, c'est qu'il est dans le noir. Donc par rapport à tes pré-requis, l'enfant bouche le bon trou et devrait être récompensé. Le code a un fonctionnement inverse, non ???
Ensuite, afin de tester si l'enfant maintient assez longtemps la case dans le noir, faire quelque-chose comme ceci :

previousmillis = millis();
unsigned long timer = 0; // compteur a 0
int start = 0; // init starter
Serial.println(PR); // mieux en dehors de la boucle car appeler 1 seule fois.
  while (millis() - previousmillis < tpsprogdt){ 
    if ((valphoto < 500) && (start == 0)){ // recouvrement ok et comtpteur non actif, init
		timer = millis();
		start = 1; // activation du compteur
	}
	else if (valphoto >= 500) { start = 0; } // recouvrement non ok reinit du compteur
	
	if ((start) && (millis() - timer >= tpsprogdt/2)) {  //  recouvrement ok, duree ok (tpsprogdt/2 completement arbitraire)
		flag = 1; break; // flag a 1 et sortit de la boucle
	}
    //delay (10);
  }
  if (flag) { // si flag ok, reward
	Serial.println ("GOOD");
  	reward();
	 }
  else { // si flag non ok, boooouuuhhh
  	notgood();
  }
  
  flag = 0; // reinit du flag
}

J'ai pas fait le tour de toutes les conditions, mais çà peut t'aider à repartir :wink:

@+

Zoroastre.

Bonjour,

Les deux derniéres accolades délimite une fin de fonction ou une fin de boucle/condition ?
Si c'est une fin de fonction un "bête" return ferait la même chose que le goto mais en plus propre.