Numéro, lettre G pas bon !

Eléphant du PHP | 129 Messages

27 nov. 2010, 12:26

Bonjour à tous,

Je me retrouve confronter à un ptchi problème avec ma lettre G

Dans ma base, j'enregistre le nombre de fois que la lettre est sortie au hasard, si celle-ci n'a pas atteint son maximum défini dans une variable max.

Mon script enregistre bien le nombre de fois pour chaque lettre si seulement il n'est pas au max, mon problème est qu'il enregistre plusieurs fois (entre 10 et 14) pour la lettre G, alors que pour les autres lettres c'est OK, quand le nombre max est atteint pas de problème.

Du coup j'arrive pas à mettre quelque chose pour lui dire de stopper quand la lettre G est au max au lieu de continuer à ajouter des +1 dans le champ.

Une fois qu'il a fini d'ajouter 10 ou 14 fois +1, j'ai bien la fin des numéro, donc parfait, mais pas pour ce foutu G qui doit être enregistrer une seul fois...

Si vous avez une idée, un grand MERCI !
<?php
$recherche = mysql_query ("SELECT id, a, b, c, d, e, f, g FROM les_numero")or die (mysql_error());
$donne = mysql_fetch_assoc($recherche);
$a=$donne['a'];
$b=$donne['b'];
$c=$donne['c'];
$d=$donne['d'];
$e=$donne['e'];
$f=$donne['f'];
$g=$donne['g'];
// variable de maximum
$Nb_A=4;
$Nb_B=4;
$Nb_C=3;
$Nb_D=3;
$Nb_E=2;
$Nb_F=1;
$Nb_G=1;

// premier chiffre au hasard
$numero=rand (1,7);


// si le numéro 7 sort et qu'il est déjà au maximum, alors on passe au numéro suivant, jusqu'a trouver un numéro qui n'est pas au max, si tout les numéro sont au max, alors il n'y pas plus de numéro.
if(($numero===7)AND ($a>=$Nb_A)){
$numero = rand (1,6);
}

if(($numero===6) AND ($b>=$Nb_B)){
$numero = rand (1,5);
}

if(($numero===5) AND ($c>=$Nb_C)){
$numero = rand (1,4);
}


if(($numero===4) AND ($d>=$Nb_D)){
$numero = rand (1,3);
}


if(($numero===3) AND ($e>=$Nb_E)){
$numero = rand (1,2);
}

if(($numero===2) AND ($f>=$Nb_F)){
$numero =1;
}


if(($numero===1) AND ($g>=$Nb_G)){

}

if(($a>=$Nb_A) AND($b>=$Nb_B)AND($c>=$Nb_C) AND($d>=$Nb_D) AND($e>=$Nb_E) AND($f>=$Nb_F) AND($g>=$Nb_G)){
echo 'plus de numéro';
}
else{
// maintenant si le numéro est ok, alors on l'enregistre dans la table
if($numero==7){
echo'A';
$db->query("update les_numero set a=a+1");
}
if($numero==6){
echo'B';
$db->query("update les_numero set b=b+1");
}
if($numero==5){
echo'C';
$db->query("update les_numero set c=c+1");
}
if($numero==4){
echo'D';
$db->query("update les_numero set d=d+1");
}
if($numero==3){
echo'E';
$db->query("update les_numero set e=e+1");
}
if($numero==2){
echo'F';
$db->query("update les_numero set f=f+1");
}
if($numero==1){
echo'G';
$db->query("update les_numero set g=g+1");
}


// fin du else
}

?>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 nov. 2010, 15:00

salut,

le problème de ton code c'est qu'il n'indique pas quoi faire dans le cas G
if(($numero===1) AND ($g>=$Nb_G)){

}
ensuite tu ne traite pas tous les cas que se passe t il si A et B sont au nombre max ?

le plus simple serais de construire un tableau ne contenant que les lettres n'ayant pas atteint leur max et de de faire un rand dessus

par exemple
<?php
try {
    $dbh = new PDO("pgsql:dbname=test_base;host=192.168.56.101", 'postgres', md5('tipounet'));
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
	$res = $dbh->query ("SELECT a, b, c, d, e, f, g FROM les_numero");
	$donne = $res->fetch(PDO::FETCH_ASSOC);
} catch (Exception $e) {
    echo 'Erreur : ' . $e->getMessage() . '<br />';
    echo 'N° : ' . $e->getCode();
}
/*
$a=$donne['a'];
$b=$donne['b'];
$c=$donne['c'];
$d=$donne['d'];
$e=$donne['e'];
$f=$donne['f'];
$g=$donne['g'];
*/

// variable de maximum
$Nb_a=4;
$Nb_b=4;
$Nb_c=3;
$Nb_d=3;
$Nb_e=2;
$Nb_f=1;
$Nb_g=1;
// onstruction du tableau

$lettreutilisable = array();
foreach ($donne as $lettre => $valeurs) {
	$var = 'Nb_'.$lettre;
	if ($$var >= $valeurs)  {
		$lettreutilisable[] = $lettre;
	}
}
if (count($lettreutilisable)>0){
	var_dump($lettreutilisable);
	// la lettre au pif
	$pif = rand(0,count($lettreutilisable) -1);
	var_dump($pif);
	$dbh->query('update les_numero set '.$lettreutilisable[$pif].'='.$lettreutilisable[$pif].'+1');
	echo $lettreutilisable[$pif];
	var_dump($donne);
	echo '<hr />';
	$res = $dbh->query ("SELECT a, b, c, d, e, f, g FROM les_numero");
	var_dump( $res->fetch(PDO::FETCH_ASSOC));
}
else {
echo 'pu possible c\'est full';
}
?> 
mais bon perso j'y vois un défaut de conception de la table (si tu devais utiliser les 26 lettres de l'alphabet tu aurais 26 champs ? enfin 27 avec l'id).
j'aurais fait ainsi
create table les_numero (
id int unsigned not null auto_increment,
nom tinytext not null,
nbmax smallint not null default 5,
nbcourant smallint not null default 0,
primary key(id))type=myisam;
a partir de la tu fait tout en sql
select id,nom from les_numero where nbcourant <= nbmax order by rand() limit 1;
ensuite une requête update si tu valide le choix sinon tu relance (le tout est surement réalisable en une seule requête mais j'ai pas cherché si l'update consécutif au select est possible ;) ).

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 129 Messages

27 nov. 2010, 15:38

Merci de ta réponse et de ton aide :wink:

Voila se que j'ai fait avec ce que tu m'a donné :
<?php
$recherche = mysql_query ("SELECT id, a, b, c, d, e, f, g FROM les_numero")or die (mysql_error());
$donne = mysql_fetch_assoc($recherche);
/*
$a=$donne['a'];
$b=$donne['b'];
$c=$donne['c'];
$d=$donne['d'];
$e=$donne['e'];
$f=$donne['f'];
$g=$donne['g'];
*/

// variable de maximum
$Nb_a=4;
$Nb_b=4;
$Nb_c=3;
$Nb_d=3;
$Nb_e=2;
$Nb_f=1;
$Nb_g=1;
// onstruction du tableau

$lettreutilisable = array();
foreach ($donne as $lettre => $valeurs) {
        $var = 'Nb_'.$lettre;
        if ($var >= $valeurs)  {
                $lettreutilisable[] = $lettre;
        }
}
if (count($lettreutilisable)>0){
        var_dump($lettreutilisable);
        // la lettre au pif
        $pif = rand(0,count($lettreutilisable) -1);
        var_dump($pif);
		$db->query("update les_numero set '".$lettreutilisable[$pif]."'='".$lettreutilisable[$pif]."'+1'");
        echo $lettreutilisable[$pif];
        var_dump($donne);
        echo '<hr />';
        $res = $db->query ("SELECT a, b, c, d, e, f, g FROM les_numero");
        var_dump( $res->fetch_assoc);
}
else {
echo 'pas possible c\'est full';
}
?>
Il m'affiche toujours full, et donc ne prend aucun numéro apparemment, du coup je comprend pas trop, et je pense qu'il faudrait que je reste sur ma structure que je comprend mieux, surtout que je n'utilise pas le PDO.

Le truc est que si toute les lettres sont au max, alors on à fini, sinon on recherche s'il reste des lettres non au max, mais se foutu G me couine lol
Merci en tout cas de tes lumières.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 nov. 2010, 15:47

hum vire le id dans la première il est inutile !

j'ai utilisé pdo par habitude, tu peut remarquer que je n'ai pas utiliser mysql mais le résultat est le même.

qu'a tu dans la base de donnée ? (en gros que donne un var_dump($donne); ?

si le tableau n'est pas remplis c'est que tu a déja cramé ton nombre max de possibilité!

je pense que le problème vient de la suppression du $ dans
<?php
if ($$var >= $valeurs)  {
		$lettreutilisable[] = $lettre;
	} ?>
ce n'est psa une fantaisie ou une erreur il s'agit de la syntaxe correcte pour une variable dynamique (voir construction de variable dans la doc)
le code que je t'ai fournis est testé et fonctionnel ;)

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 129 Messages

27 nov. 2010, 15:52

Ok merci, j'ai donc remis le $ j'avais vraiment pensé que c'était une erreur lol

Voila se qu'il m'affiche :

array(7) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" [3]=> string(1) "d" [4]=> string(1) "e" [5]=> string(1) "f" [6]=> string(1) "g" } int(2) carray(7) { ["a"]=> string(1) "0" ["b"]=> string(1) "0" ["c"]=> string(1) "0" ["d"]=> string(1) "0" ["e"]=> string(1) "0" ["f"]=> string(1) "0" ["g"]=> string(1) "0" } NULL

Dans la table "les_numero" tous les a, b, c, d, e, f, g sont à 0.


Edit : J'avais une petite erreur je pense ici, j'ai donc fait la modification :
var_dump($pif);
                $db->query('update les_numero set '.$lettreutilisable[$pif].'='.$lettreutilisable[$pif].'+1');
Donc la maintenant il enregistre bien dans la table, mais il enregistre quand même +1 à G malgré que celui-ci soit déjà au max, du coup je me retrouve avec 3 dans le champ G au lieu de 1
Idem pour une autre lettre !

Merci en tout cas de ton aide.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 nov. 2010, 16:26

Heu c'est un seul var_dump ce que tu a mis la ?
Parce que bon je vois un tableau avec les noms et un avec les valeurs :/

Verifie aussi ce qu'il y a dans lettreutilisable tu doit avoir seulement des lettres en valeurs et des chiffres en index !
Il en faut peu pour être heureux ......

Eléphant du PHP | 129 Messages

27 nov. 2010, 19:06

Oui c'est un seul var_dump, en faite si je change les valeurs de max :
$Nb_a=3;
$Nb_b=3;
$Nb_c=2;
$Nb_d=2;
$Nb_e=1;
$Nb_f=1;
$Nb_g=1;

Alors je retrouve un enregistrement à peu près comme je le voulais, en faite il sera +1 à chaque max.

$Nb_a=3; le max est jusqu'à 3, et bien il enregistrera +1 encore, donc 4

Du coup dans la table voici les valeurs après avoir fini tous les max :

a b c d e f g
4 4 3 3 2 2 2

Au lieu de :

a b c d e f g
3 3 2 2 1 1 1

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 nov. 2010, 19:22

hum c'est parce que j'ai été trop vite en recopiant ton code XD
<?php
foreach ($donne as $lettre => $valeurs) {
	if ($nb[ $lettre ] > $valeurs)  {
		$lettreutilisable[] = $lettre;
	}
}
?>
en considérant >= j'indiquais que quand le max est atteint je fait encore un tour !

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 129 Messages

27 nov. 2010, 20:10

Yes tes un chef Moogli =D>

Merci merci c'est niquel, j'ai pu apprendre quelque truc en plus, cool :wink: