Probleme de PHP/MYSQL => je m'embrouille dans l'algo

Probleme de PHP/MYSQL => je m'embrouille dans l'algo - PHP - Programmation

Marsh Posté le 30-12-2003 à 03:22:42    

Salut!c'est encore moi...
Voilà le probleme.
J'ai 2 table MYSQL:
la 1er , desc_evo contient la description de différentes évolutions que peut acheter l'utilisateur du jeu(s'pour un jeu en ligne.)
les champs de cette table sont:

Code :
    • Description, amélioration,prix (sans importance)
    • [*]level, nom (clé du probleme)
    • Exmple d'enregistrement:
    • engrais - Invention de l'engrais - +10% de prod. par fermes - 40000 - 1  (nom,description,amélioration,prix,level)

et une 2nd table, qui contient qui a quoi comme évolutions.
c'est la table evolution:
donc
ses champs=>

Code :
  1. //pseudo de l'utilisateur
  2. pseudo
  3. //toute les évolutions
  4. engrais  (int)
  5. transport (int)
  6. Exemple d'enregistrement:
  7. test1 - 4 - 0 (pseudo,engrais,transport)


dans les champs engrais ou transport, on mets le niveau de l'évolution ateint par l'utilisateur 'pseudo'...
 
voilà le probleme:
je voudrais que si monsieur Test a engrais au niveau 3, on lui propose dans un tableau l'engrai au niveau 4, sans afficher qu'il a l'engrais niveau 1,2,3...
 
le code que j'ai pondu:
 
 

Code :
  1. //tit tableau HTML=>que du bonheur
  2.         <table width="90%" border="0" align="center" cellpadding="0" cellspacing="0" class="tabin">
  3.           <tr>
  4.             <td height="23" colspan="5" class="celluletitre"><div align="center">
  5. //titre général
  6.                 <p><strong>Tableau des &eacute;volutions</strong></p>
  7.               </div></td>
  8.           </tr>
  9. //titre des colonnes
  10.           <tr class="cellulesoustitre">
  11.             <td width="33%"> <p><strong>Description</strong></p></td>
  12.             <td width="37%"> <p><strong>Am&eacute;lioration</strong></p></td>
  13.             <td width="10%"> <p><strong>Prix</strong></p></td>
  14.             <td width="9%"> <p><strong>Level</strong></p></td>
  15.             <td width="9%"><p><strong>Statut</strong></p></td>
  16.           </tr>
  17. //Php.......ca se complique :(           
  18. <?
  19. //on prends les évolutions du monsieur
  20. $req="SELECT * FROM evolution WHERE pseudo='$pseudo'";
  21. $resultat=mysql_query($req,$connexion);
  22. $evo=mysql_fetch_object($resultat);
  23. //on prends les évo existentes..
  24. $nextlevel=$evo->$current+1;
  25. /* Je pense a une requete dans ce style
  26. $req="SELECT * FROM desc_evo WHERE level='$nextlevel' and nom=''";
  27. Mais je ne sais pas quoi mettre dans nom....je pense au noms d'un champ de la table evolution mais comment lui dire lequel choisir ? */
  28. /*je selectionne la description de toute les évo(faudrait juste que je prenne celle dont on a besoin...c'est a dire uniquement celle qui sont encore a effectué (si engrais=3 alors pas la peine de marquer la description de engrais 1,2,3, mais uniquement engrais 4.*/
  29. $req="SELECT * FROM desc_evo";
  30. $resultat=mysql_query($req,$connexion);
  31. while($desc_evo=mysql_fetch_object($resultat))
  32. {
  33. echo"    <tr class=cellulegris".((($l++)%2)+1).">
  34.             <td><p><a href='index.php?page=evolutions&level=$desc_evo->level&achat=$desc_evo->nom'>$desc_evo->description</a></p></td>
  35.             <td><p>$desc_evo->amelioration</p></td>
  36.             <td><p>$desc_evo->prix</p></td>
  37.             <td><p>$desc_evo->level</p></td>
  38. ";
  39. //Code pour moi, le probleme n'est pas là.
  40. $current=$desc_evo->nom;
  41. // $evo->objet en cour dans la boucle
  42. if($evo->$current==0) //revient a dire $evo->engrais par exemple
  43.   {
  44.    echo"<td><p><img src='imgjeu/coche_rouge.gif'></p></td>";
  45.   }
  46. else
  47.   {
  48.    echo"<td><p><img src='imgjeu/coche_verte.gif'></p></td>";
  49.   }
  50. echo"</tr>\n";
  51. }   
  52.    ?>
  53.         </table>


Message édité par smilm le 30-12-2003 à 03:25:37

---------------
AfterEnd: Batissez un nouveau monde
Reply

Marsh Posté le 30-12-2003 à 03:22:42   

Reply

Marsh Posté le 30-12-2003 à 10:13:37    

d'après ce que j'ai compris, si tu utilises mysql (pas de requetes imbriquées  :cry:  ) il faut faire deux requetes :
 
"select level from evolution" => tu recuperes le level
 
puis
 
"select * from desc_evo where level=$le_level_recupere_avant"


Message édité par Lex le 30-12-2003 à 10:14:00
Reply

Marsh Posté le 30-12-2003 à 16:28:30    

Lex a écrit :

d'après ce que j'ai compris, si tu utilises mysql (pas de requetes imbriquées  :cry:  ) il faut faire deux requetes :
 
"select level from evolution" => tu recuperes le level
 
puis
 
"select * from desc_evo where level=$le_level_recupere_avant"


 
Oui c'était la solution que je pensais :
$nextlevel=$evo->level+1;
SELECT * FROM desc_evo WHERE level='$nextlevel'
$nextlevel parce que je veux prendre la description du level suivant, le level courant étant déjà acquis
 
Seulement le probleme, c'est que il y'a plusieurs évolutions différentes.
avec ca :SELECT * FROM desc_evo WHERE level='$nextlevel' , il me prends la description de toute les évolutions qui ont le niveau $nextlevel.
Il y'en aura donc plein, alors que je ne cherche que celui dont l'utilisateur a besoin, l'évolution de l'objet que l'utilisateur possede au niveau $evo->level et que je veux lui proposer au niveau $nextlevel ($evo->level+1).
 
Je suis peut etre pas trés clair...?


---------------
AfterEnd: Batissez un nouveau monde
Reply

Marsh Posté le 30-12-2003 à 16:32:44    

ben : SELECT * FROM desc_evo,evolution WHERE desc_evo.level='$nextlevel' AND evolution.nom='$nomplayer'

Reply

Marsh Posté le 30-12-2003 à 16:39:21    

Lex a écrit :

ben : SELECT * FROM desc_evo,evolution WHERE desc_evo.level='$nextlevel' AND evolution.nom='$nomplayer'


 
merci je teste ca...
mais ou apparait le nom de l'évolution dans tout ca ?
en fait je fais 2 boucles while incrusté ?
je m'embrouille....


---------------
AfterEnd: Batissez un nouveau monde
Reply

Marsh Posté le 30-12-2003 à 16:47:19    

ah en fait j'avais mal compris, je pense que ça risque de pas marcher ça :D  
 
bref, creuse cette voie ;)  
 
en tous cas : évite à tout prix de mélanger ton code HTMl et ton code PHP, c illisible :D

Reply

Marsh Posté le 30-12-2003 à 16:49:29    

voilà ce que j'ai fais..

Code :
  1. $req="SELECT * FROM desc_evo,evolution WHERE desc_evo.level='$nextlevel' AND evolution.nom='$pseudo'";
  2. $resultat=mysql_query($req,$connexion);
  3. while($desc_evo=mysql_fetch_object($resultat,$connexion))
  4. {
  5. echo"    <tr class=cellulegris".((($l++)%2)+1).">
  6.             <td><p><a href='index.php?page=evolutions&level=$nextlevel&achat=$desc_evo->nom'>$desc_evo->description</a></p></td>
  7.             <td><p>$desc_evo->amelioration</p></td>
  8.             <td><p>$desc_evo->prix</p></td>
  9.             <td><p>$desc_evo->level</p></td>
  10. ";
  11. // [...]
  12. } // fin de la boucle while


 
Mais faudrait maintenant que j'initialise ma variable nextlevel.
En fait nextlevel=evo->nom_de_mon_evo +1;
donc avant j'avais fait ca:

Code :
  1. $current=$desc_evo->nom;
  2. $nextlevel=$evo->$current+1;*/


 
mais comment implementer sa dans ma requete ?


---------------
AfterEnd: Batissez un nouveau monde
Reply

Marsh Posté le 30-12-2003 à 17:05:26    

juste comme ça : la structure de ta base est vraiment chelou...
 
avec une meilleure structure des données, ça irait peut-être mieu...
 
OPTION
------
ID
Nom
Description
LVL_MAX (Niveau maximum possible)
 
USER_OPTIONS
------------
USER_ID (pseudo)
OPTION_ID (ID de la table OPTION)
LEVEL
 
Ta requête :
 
SELECT O.ID, O.NOM, NVL(UO.LEVEL, 0) + 1 AS NEXT_LEVEL
FROM OPTION O LEFT OUTER JOIN USER_OPTIONS UO ON O.ID = UO.OPTION_ID
AND NVL(UO.LEVEL, 0) + 1 <= O.LVL_MAX
 
Ca devrait marcher (vérifier que mon outer join est bien écrit, je suis pas habitué à cette syntaxe) et que le sous MySQL c'est bien NVL() qui permet de remplacer NULL par une valeur.
 
Avec cette requête, tu vas avoir la liste de toutes les options que l'utilisateur peut upgrader, ainsi que le niveau à atteindre.
 
L'avantage de ce système, c'est que le jour où tu ajoutes ou supprime une option, t'as pas à modifier la structure de tes tables. Deplus, ça t'évite d'avoir 25 doublons pour rien dans la table des options. Y'a pas de différence à faire entre engrais niveau 1 et angrais niveau 2, ça reste la donnée angrais, y'a que l'attribut level qui change. Et pour finir, tu récupères tout en une seule passe, sans aucun traîtement côté PHP.
 
En somme, faut réfléchir convenablement à sa structure de données AVANT de commencer à coder. Ca évite de perdre du temps et se casser la tête pour rien.


Message édité par MagicBuzz le 30-12-2003 à 17:10:59
Reply

Marsh Posté le 30-12-2003 à 17:09:14    

Magicbuzz :jap:

Reply

Marsh Posté le 30-12-2003 à 22:19:54    

Merci beaucoup Magicbuzz :jap:
J'avais oublié comment voir ma table mysql, c'est vrai que pour mes évolutions, j'ai creer les 2 tables sans trop réfléchir.
 
Merci.
 
pour ce qui est de ta requete que tu me proposes, je n'ai pas tout saisie je crois, mais bon, je vais regarder les reference MYSQL, ca va etre plus clair.
d'habitude je me limite avec faire des select .. where ... and ...= ... and ... like .... pas plus que ca :)
 
Par contre un tit bug dans la table desc_evo que tu me proposes=>
Il manque le prix qui est variable (engrais-level1 =10000, level2=50000 , par exemple).
et l'amélioration est aussi différente (level 1 :+10% de bouf, level 2 : +8% de bouf...ect)
Mais je vais étudier ca.
Merci encore


Message édité par smilm le 30-12-2003 à 22:25:20
Reply

Marsh Posté le 30-12-2003 à 22:19:54   

Reply

Marsh Posté le 31-12-2003 à 00:16:28    

OK, t'avais pas parlé des prix ni des améliorations ;)
 
Je pense que le mieu est que tu fasses un barème à part.
 
Soit une table de référence supplémentaire (option, level, prix, amelioration_id, amelioration_percent), soit, si c'est possible, et c'est beaucoup mieu, à partir d'un calcul (t'as juste un prix de base à indiquer, et le type d'amélioration et le pourcentage de base à rajouter dans la table des options, sans détailler pour chaque niveau).
N'oublie pas notamment les fonctions logarythmiques qui te permettront d'avoir un prix de plus en plus cher en fonction du niveau, ou alors au contraire, des évolutions de moins en moins intéressantes.
 
Sinon, en gros ma requête fait fonctionne de la fonction suivante (par contre, comme j'ai dit, y'a peut-être des problèmes de syntaxe, je suis pas habitué à bosser avec MySQL) :
 
-> Elle récupère toutes les options (y compris celles où on n'a pour le moment pas de level - donc à 0), et indique le niveau prochain.
 
L'avantage réside notamment dans le fait que tu peux ajouter une option ou en supprimer une sans avoir ni à modifier la structure de la table, ni la requête, ni même le code.
 
Pour ce qui est de la complexité de la requête, en effet, bien que j'utilise des concepts assez basiques ici, si tu n'as pas reçu une formation SQL et que tu n'as pas d'expérience dans le domaine, c'est normal que tu n'y ait pas pensé. En effet, car même quand on connait ces possibilités, c'est assez difficile d'acquérir le réflèxe de les utiliser.
 
Mais la clé d'un code propre et maintenable, c'est avant tout :
-> Généricité la plus importante possible du modèle des données : on doit pouvoir ajouter et supprimer des informations sans changer la structure des données, et on doit pouvoir aisément intégrer de nouveaux paramètres. Ainsi, tu ne te retrouves jamais devant une base de données que tu dois reprendre à 0 parceque tu es bloqué par une évolution que tu n'arrives pas à implémenter.
-> Faire un maximum de traîtements, notamment ensemblistes et de regroupement dans les requêtes SQL. Le moteur de la base de données est conçu pour traîter ces instructions à la fois de façon simple et extrêment performantes. Même en optimisant à mort avec un langage compilé, tu n'arriveras "jamais" à reproduire les perfs du moteur de la base de données, et ce sera au prix d'un code bien plus complexe, donc difficile à maintenir.
 
Je te conseille fortement de te documenter sur deux sujets :
-> Analyse (au choix la méthode Merise ou UML. Je préfère la première, mais c'est aussi la seule que je sâche utiliser donc c'est normal ;)). Ca te permet de découper une problématique afin d'y trouver une solution, qui est parfois loin d'être celle qui sautait aux yeux à première vue. Au final, si tu appliques correctement ces méthodes, tu auras un modèle de données à la fois propre, simplifié, et maintenable. Tu n'auras plus qu'à le dénormaliser un peu pour l'optimiser, mais ça n'est pas indispensable.
 
-> Le langage SQL. Notamment les concepts ensemblistes (Les différents types de jointure, mais aussi UNION, INTERSECT, etc., même si tous ne sont pas supportés par tous les SGBD), et ceux de regroupement (GROUP BY). Ca permet généralement de simplifier au maximum l'algorythme qui va utiliser les données par la suite.

Reply

Marsh Posté le 31-12-2003 à 16:23:23    

Merci merci merci beaucoup !!
:love:  
Donc ca sert a ca le UML, c'était encore un mystere pour moi ya deux minutes, enfin bon, ca doit servir a beaucoup de chose vu que j'en entends parler trés régulierement.
 
Merci pour ce petit cours en tout cas, c'est trés instructif.
Je crois que je vais utiliser le truc des logarythmes qui diminue..meme si je n'ai aucune idée de qu'est ce que c'est (c'est pas au programme de 3éme), je demanderais un coup de main a mon pere ou mon frere.
Enfin bon, je pense que tu parlais d'un truc du style:
hmm non ,je fais des tests avec ma calculette là, je trouve pas..je pensais a :
pourcent_add=level*(0.80+level), mais le résultat ne diminue pas si on augmente le level. :sweat: s'pas grave
 
Pour ce qui est de SQL, j'ai un bookin ou ya un peu de doc dessus (Pratique de MySQL et PHP de chez O'reilly) mais je ne m'y étais jamais interrésé au profondeur car je ne voyais pas l'utilité de faire des jointures ou chose dans le genre, parce que j'en faisais une utilisation assez basique mais je crois que je vais m'y mettre :)
 
Voilà.
 
Merci encore, et bonne fete !


Message édité par smilm le 31-12-2003 à 16:24:15
Reply

Marsh Posté le 31-12-2003 à 17:47:45    

hmm log(level*level) ?
Mon frere m'a embrouiller :(
 
Apparement ca a l'air bien compliqué tout ca.
Je crois que je vais faire sans logarythmes finalement, je vais creer une nouvelle table de référence.., ca me fera 3 tables pour une seul page web, record battu lol.
 
Je vous tiens au courant.

Reply

Marsh Posté le 01-01-2004 à 22:50:12    

Bah, c'est vrai que ce genre de fonction c'est pas super intuitif à utiliser.
 
Sinon, y'a tout bêtement les fonctions carré et racine qui offrent un comportement similaire mais une courbe moins belle. En étalonnant bien, ça devrait suffir cependant

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed