Boucle de test avec fonction et Bool [C#]

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
HellSon
Messages : 26
Inscription : 26 Avr 2015 15:11

Boucle de test avec fonction et Bool [C#]

Message par HellSon » 01 Mai 2016 11:12

Bonjour à toutes et à tous, j'ai un soucis avec un script et je n'arrive pas bien à comprendre d'où il vient...

Voici mon script

Code : Tout sélectionner

public bool questionTest (int Num)
	{
		
	switch(Num)
		{
		case 1:
			if(PlayerPrefs.GetInt("Argent") <= 100)
			test = true;
			else
				test = false;
			break;
		case 2:
			if(PlayerPrefs.GetInt("Argent") <= 100)
				test = true;
			else
				test = false;
			break;
		case 3:
			if(PlayerPrefs.GetInt("Argent") <= 40)
				test = true;
			else
				test = false;
			break;
		case 4:
			if(PlayerPrefs.GetInt("Argent") >= 15)
				test = true;
			else
				test = false;
			break;
		case 5:
			if(PlayerPrefs.GetInt("Argent") >= 10)
				test = true;
			else
				test = false;
			break;
		case 6:
			test = true;
			break;
		case 7:
			test = true;
			break;
		case 8:
			if(PlayerPrefs.GetInt("Argent") >= 10)
				test = true;
			else
				test = false;
			break;
		case 9:
			test = true;
			break;
		case 10:
			test = true;
			break;
		case 11:
			test = true;
			break;
	}
		
		if(test == true)
			return true;
		else
		return false;
	}

	
	void Start () {


		do
		{
			testorUn = false;
			RandUn = Random.Range(0,GameController.StockQuestion.Length);
			testorUn = questionTest(RandUn);
		}while(testorUn == false);

		do
		{
			testorDeux = false;
			RandDeux = Random.Range(0,GameController.StockQuestion.Length);
			testorDeux = questionTest(RandDeux);
		}while(testorDeux == false);

Alors en fait ce que je souhaite c'est que mon code pioche des questions dans un tableau mais qu'il pioche certaines question en fonction de variables qui caractérisent le joueur, j'ai donc procédé ainsi :
Premièrement mon code pioche deux questions au hasard, puis il teste et si une est fausse il la change jusqu'à ce qu'elle soit juste.

Seulement ce code ne fonctionne pas comme je voudrais (il me pose quand même toutes les questions).

Merci beaucoup de votre aide ! :super:

Avatar de l’utilisateur
simonj
Messages : 293
Inscription : 29 Nov 2015 20:47
Localisation : Lyon

Re: Boucle de test avec fonction et Bool [C#]

Message par simonj » 01 Mai 2016 15:27

Salut,

Après un tour d'inspection, je ne vois pas de grosses fautes sur ton code qui pourrait faire que ça ne marche pas. Essaye de mettre des Debug.Log sur tes différents tirages pour savoir quel nombre est tiré ?

Après au niveau algo et code y'a quand même pas mal de petites choses à revoir je dirais. Au niveau de l'algo, je ne suis pas fan du bruteforce comme ça. J'aurais plutôt fait une copie en local de toutes tes questions, je mélange le tableau des copies (Beaucoup de morceaux de codes existent pour mélanger efficacement un tableau), je parcours mon tableau de 0 à n (n étant la longueur de mon tableau - 1), je test si la question où j'en suis est bonne. Si oui et que c'est ma première question, alors je stock la question et je continue. Si oui et que c'est ma deuxième question, alors je stock la question et je sors de ma boucle avec un break. Si non, alors je continue tant que je ne suis pas arrivé à la fin de ma boucle ou que je n'ai pas trouvé les deux questions.

Ensuite, pour savoir si une question est bonne, moi j'aurais plutôt fait une classe "Question" et tu fais hériter des classes de celle-ci (Une classe qui va check si tu as bien le bon nombre d'argent par exemple, ...). Et c'est cette classe "Question" et ses dérivées qui vont vérifier si elle est bonne (En gros tu laisses l'intelligence du comportement à l'objet). Mais je ne connais pas ton niveau en programmation, donc c'est peut-être un peu compliqué en fonction du niveau que tu as.

Au niveau du code, tu peux travailler un peu efficacement par exemple avec des améliorations du type :

Code : Tout sélectionner

if(PlayerPrefs.GetInt("Argent") <= 100)
         test = true;
else
	test = false;
	
// Peut être transformé en :
test = (PlayerPrefs.GetInt("Argent") <= 100);
Ou encore :

Code : Tout sélectionner

if(test == true)
	return true;
else
	return false;
	
// Peut être transformé en :
return test;
Une petite astuce aussi, si dans un switch tu veux faire plusieurs fois la même action, tu peux simplifier les choses :

Code : Tout sélectionner

case 9:
	test = true;
	break;
case 10:
	test = true;
	break;
case 11:
	test = true;
	break;

// Peut être simplifié en :
case 9:
case 10:
case 11:
	test = true;
	break;
Et c'est un détail mais tu n'as pas besoin d'initialiser ta variable testorUn et testorDeux puisque tu les remplis juste après.

Code : Tout sélectionner

testorUn = false; // Inutile, tu le fais 1 ligne en dessous
RandUn = Random.Range(0,GameController.StockQuestion.Length);
testorUn = questionTest(RandUn);
Désolé de ma réponse un peu longue et qui ne corrige pas forcément ton problème.

HellSon
Messages : 26
Inscription : 26 Avr 2015 15:11

Re: Boucle de test avec fonction et Bool [C#]

Message par HellSon » 07 Mai 2016 13:13

Salut,
Tout d'abord merci beaucoup de m'avoir répondu, et je suis désolé de n'avoir pu répondre avant, j'étais un peut trop occupé, mais j'avais lu ta réponse !

J'avais mis des Debug.Log et j'avais vu que parfois, il en tirait plusieurs avant de me sortir une question, mais il ne respectait quand même pas les conditions... Étrange...

Pour mon niveau en programmation, je sais programmer, je veux dire, j'arrive à ce que je souhaite, mais après je ne connais pas les moyens bruteforce ou non de programmer. :hehe:

Bon, ce que tu me conseilles, c'est de recommencer avec ta technique, mais je ne pense pas vraiment avoir tout compris, si tu pouvais me détailler un peu, ce serait génial !

Merci bien pour les petites améliorations, à vrai dire pour le "return else", et l'initialisation de la variable testor, j'avais fait ça pour tester d'où pouvais venir le problème, mais il est vrai que j'avais oublié de le remettre correctement.
Mais merci pour ces petites astuces !

Encore merci, et si tu peux m'aider à transformer ce code pour qu'il soit parfait, ce serait vraiment génial ! :amen:

Avatar de l’utilisateur
simonj
Messages : 293
Inscription : 29 Nov 2015 20:47
Localisation : Lyon

Re: Boucle de test avec fonction et Bool [C#]

Message par simonj » 10 Mai 2016 10:41

Salut,

Alors pour transformer ce code. Voilà comment je ferais (Attention je code directement ici donc y'auras surement des bugs) :

Code : Tout sélectionner

internal class TaClasse 
{
	private int rand1= -1;
	private int Rand2 = -1;
	
	private Question q1 = null;
	private Question q2 = null;

	Start()
	{
		Question[] questions = new Question[GameController.StockQuestion.Lenght];
		Array.Copy(GameController.StockQuestion, 0, questions, 0, GameController.StockQuestion.Lenght); // Create a local copy of the list of the questions
		Shuffle<Question>(questions); // Randomize the array
		
		for(int i = 0; i < questions.Length; i++) 
		{
			if(questionTest(i)) // If the question is good (If questionTest send true)
			{
				if(rand1 != -1)
					rand1 = i; // We have a good question and not find one yet
				else if(rand2 != -1)
				{
					rand2 = i // We have a good question and find one yet
					break; // We have find the 2 questions, we can stop the loop
				}
			}
		}
		
		// Find the real question 1 in the original array not shuffled
		if(rand1 != -1)
		{
			for(int i = 0; i < GameController.StockQuestion.Lenght; i++) 
			{
				if(GameController.StockQuestion[i] == questions[rand1])
				{
					q1 = GameController.StockQuestion[i];
					break;
				}
			}
		}
		// Find the real question 2 in the original array not shuffled
		if(rand2 != -1)
		{
			for(int i = 0; i < GameController.StockQuestion.Lenght; i++) 
			{
				if(GameController.StockQuestion[i] == questions[rand2])
				{
					q2 = GameController.StockQuestion[i];
					break;
				}
			}
		}
		
		if(q1 == null) Debug.Log("Question 1 cannot be found (Id find : " + rand1 + ")");
		if(q2 == null) Debug.Log("Question 2 cannot be found (Id find : " + rand2 + ")");
	}
	
	private void Shuffle<T>(this T[] array)
	{
	 	rng = new Random();
	 	int n = array.Length;
	 	while (n > 1)
	  	{
	  		int k = rng.Next(n);
	  		n--;
	  		T temp = array[n];
	  		array[n] = array[k];
	  		array[k] = tem;
	 	 }
	}
	
	public bool questionTest (int Num)
	{
		switch(Num)
		{
		case 1:
		case 2:
			test = (PlayerPrefs.GetInt("Argent") <= 100)
			break;
		case 3:
			test = (PlayerPrefs.GetInt("Argent") <= 40)
			break;
		case 4:
			test = (PlayerPrefs.GetInt("Argent") >= 15)
			break;
		case 5:
			test = (PlayerPrefs.GetInt("Argent") >= 10)
			break;
		case 6:
		case 7:
			test = true;
			break;
		case 8:
			test = (PlayerPrefs.GetInt("Argent") >= 10)
			break;
		case 9:
		case 10:
		case 11:
			test = true;
			break;
		}
		
		Debug.Log("Question tested n°" + Num + ". Result : " + test);
		return test;
	}
}
Je n'ai pas fait grand chose. Juste réorganisé un peu le truc. Mais globalement ça reste la même chose. J'ai essayé de mettre des commentaires pour que tu comprennes mais n'hésites pas, je suis toujours là.

Et au niveau du code, j'ai essayé de faire quelque chose de propre. Bien sur il y a plein de façon de faire les choses et il y a encore moyen d'optimiser les choses, mais j'ai surtout fait en sorte que tu puisses t'y retrouver...

Et voilà les liens dont je me suis servis :
- Mélanger un tableau
- Copier un tableau

HellSon
Messages : 26
Inscription : 26 Avr 2015 15:11

Re: Boucle de test avec fonction et Bool [C#]

Message par HellSon » 15 Mai 2016 13:57

Un grand merci à toi, et je te demande pardon de ne pas avoir répondu un peut plus tôt, coupure d'internet !

J'ai regardé ton code, je n'ai pas tout tout compris, j'ai modifié tant que j'ai pu, j'arrive maintenant à cela :

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class Buttons : MonoBehaviour {

	public string[] Question;
	public GameController gameController;
	public bool test;
	public int rng;
	private int rand1 = -1;
	private int rand2 = -1;
	
	private bool q1 = null;
	private bool q2 = null;


	void Start()
	{
		string[] questions = new string[GameController.StockQuestion.Length];
		System.Array.Copy(GameController.StockQuestion, 0, questions, 0, GameController.StockQuestion.Length); // Create a local copy of the list of the questions
		Shuffle<string>(questions); // Randomize the array
		
		
		for(int i = 0; i < questions.Length; i++)
		{
			if(questionTest(i)) // If the question is good (If questionTest send true)
			{
				if(rand1 != -1)
					rand1 = i; // We have a good question and not find one yet
				else if(rand2 != -1)
				{
					rand2 = i // We have a good question and find one yet
						break; // We have find the 2 questions, we can stop the loop
				}
			}
		}
		
		// Find the real question 1 in the original array not shuffled
		if(rand1 != -1)
		{
			for(int i = 0; i < GameController.StockQuestion.Length; i++)
			{
				if(GameController.StockQuestion[i] == questions[rand1])
				{
					q1 = GameController.StockQuestion[i];
					break;
				}
			}
		}
		// Find the real question 2 in the original array not shuffled
		if(rand2 != -1)
		{
			for(int i = 0; i < GameController.StockQuestion.Length; i++)
			{
				if(GameController.StockQuestion[i] == questions[rand2])
				{
					q2 = GameController.StockQuestion[i];
					break;
				}
			}
		}
		
		if(q1 == null) Debug.Log("Question 1 cannot be found (Id find : " + rand1 + ")");
		if(q2 == null) Debug.Log("Question 2 cannot be found (Id find : " + rand2 + ")");
	}


	
	private static void Shuffle<T>(this T[] array)
	{
		rng = new Random();
		int n = array.Length;
		while (n > 1)
		{
			int k = rng.Next(n);
			n--;
			T temp = array[n];
			array[n] = array[k];
			array[k] = tem;
		}
	}


	public bool questionTest (int Num)
	{
		switch(Num)
		{
		case 1:
		case 2:
			test = (PlayerPrefs.GetInt("Argent") <= 100)
				break;
		case 3:
			test = (PlayerPrefs.GetInt("Argent") <= 40)
				break;
		case 4:
			test = (PlayerPrefs.GetInt("Argent") >= 15)
				break;
		case 5:
			test = (PlayerPrefs.GetInt("Argent") >= 10)
				break;
		case 6:
		case 7:
			test = true;
			break;
		case 8:
			test = (PlayerPrefs.GetInt("Argent") >= 10)
				break;
		case 9:
		case 10:
		case 11:
			test = true;
			break;
		}
		
		Debug.Log("Question tested n°" + Num + ". Result : " + test);
		return test;
	}

}

Mais il me reste quelques problèmes :
- Dans le private static void Shuffle<T>(this T[] array) :
Je n'arrive pas à comprendre ce que représentent Next et tem
- Et j'ai une erreur : Error CS1106: Les méthodes d'extension doivent être définies dans une classe statique non générique (CS1106) (Assembly-CSharp) à la 4ème ligne.
Je comprend qu'il y a un problème de classes mais je n'arrive pas à le résoudre.

Je suis désolé si je pose des questions un peut stupides mais c'est vrai que décortiquer un code nouveau n'est pas toujours très simple.
Encore merci à toi ! :hello:

Répondre

Revenir vers « (C#) CSharp »