JeuWeb - Crée ton jeu par navigateur
Gestion des prérequis - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Gestion des prérequis (/showthread.php?tid=5419)

Pages : 1 2 3 4


RE: Gestion des prérequis - niahoo - 17-05-2011

pour le reste je sais pas mais pour les failles de sécurité je ne vois pas vraiment pourquoi, vu qu'aucune donnée externe à l'application ne joue dans la lecture des prérequis et dans la construction d'une telle requête.


RE: Gestion des prérequis - Jeckel - 17-05-2011

Tout dépend de la façon dont tu construit ta requête en effet...

Mais mettons que tu as des prérequis pouvant être sur différentes tables, il est tentant d'avoir une structure commune pour ces différentes tables et de mettre le nom de la table dans une variable... A partir de là, tout est possible.

Mais ce n'est pas ce qui m'inquiète le plus, ce qui me gène c'est l'ajout de jointure en dynamique où là, on perd complètement le contrôle sur les perfs.

Enfin comme je disais, pour la construction de requête dynamique, c'est plus une question d'avis personnel et d'habitude, je n'ai pas de justification vraiment sérieuse là-dessus.


RE: Gestion des prérequis - niahoo - 17-05-2011

C'est plutot au code de cimenter la logique des prérequis.

Comme je le proposais, ta table de prérequis contient un id pour le bâtiment à construire, un id de type de prérequis et un id d'objet correspondant.
si ton id de type de prérequis est 3, tu sais que c'est un autre bâtiment, tu vas donc dynamiqement créer ta requête pour qu'elle vérifie que le joueur a possède déjà ce bâtiment.
si c'est 12, ça veut dire que cela requiert un objet, pouf tu check l'inventaire
5, c'est avoir terminé telle quête,
6, c'est avoir telle quête en cours

Pas de faille là dedans, et les tables sont comme on veut, c'est le code qui maintient la logique. tant mieux, c'est son taf.

Ensuite effectivement on peut peut-être créer une grosse requête pour faire ça en un seul coup. Mais vouloir optimiser sur la performance sur une requête qui ne va pas être lancée souvent, est-ce que ça vaut le coup de la rendre difficile à modifier à ce point ?

Bon, je parle, je parle, et je me rends compte que ma méthode ne gère pas non plus les OU logiques.

ceci dit on peut rajouter un champ pour un groupe logique et un pour un sous groupe (le groupe logique 1 vaudrait prérequis obligatoire, et le autres nombres on répète le même schema un niveau en dessous: il faut valider tous les prérequis ayant le même nombre en sous-groupe pour valider le groupe)

ah je kiffe ma race il faut que je note tout ça. n'hésites pas à me dire si c'est complètement débile pasque sinon je vais partir là dessus.
(bon je reste sur mes requêtes dynamiques, comme je te l'ai dit la performance ce n'est pas grave je mets ça a jour chez le joueur toutes les 5 minutes et à chaque validation/construction/...)


RE: Gestion des prérequis - Ter Rowan - 17-05-2011

pour les prérequis avec OU, perso je me suis borné au modèle suivant :

une action est composée de n contraintes

Pour réaliser une action il faut que toutes les contraintes soient validées.

Une contrainte est composée de n conditions

Pour qu'une contrainte soit validée, il faut et il suffit qu'au moins une condition parmi les n soit validées

une condition peut être liée à ce qu'on veut :
- un batiment
- une quete
- une connaissance,
etc...

(là j'ai transposé, je suis sur des actions au niveau du personnage, inventaire, compétence, lieu, énergie, ...)


j'attends avec intérêt ta solution



RE: Gestion des prérequis - niahoo - 17-05-2011

heu ma solution ? Ou celle de Jeckel ? non parce que moi maintenant que je me suis trouvé le principe de base, ça va rester dans la doc a attendre patiemment une implémentation.


RE: Gestion des prérequis - Jeckel - 17-05-2011

J'aime bien la solution de Ter Rowan, ça a le mérite d'être assez simple (sur le papier comme ça)

Bon, histoire d’approfondir le sujet, et là je pars sur du pur théorique hein...

Pour un système "complet" (ou presque), il faut voir la construction de nos bâtiments (ou autre) comme un workflow avec :
- la construction du bâtiment est une étape
- le pré-requis est une condition sous la forme d'une expression booléenne, si la condition est vrai, on peut passer l'étape (et donc construire le bâtiment).

Donc une solution optimale devrait pouvoir "évaluer" n'importe quelle condition booléenne (avec des OU, des ET, des parenthèses, des >=, etc...)

Voilà pour la théorie.
Pour ça, je pense que le SQL ne sera pas à la hauteur.

Sinon, pour niahoo, coder des règles en SQL n'est pas forcément idiot, c'est parfois en effet plus compliqué et plus difficile à maintenir, mais sur des règles complexes qui doivent être évaluer régulièrement, c'est parfois beaucoup plus rapide que du PHP par exemple. Surtout quand il y a du volume.


RE: Gestion des prérequis - niahoo - 17-05-2011

(mais en fait ce que je disais ça correspond également à ce que proposait ter rowan, c'est à dire que mes groupes sont les contraintes et que les sous-groupes sont les conditions, seulement au lieu d'avoir une seule condition requise, on requiert toutes celles qui ont le même nombre)

Oui ok pour PHP mais même en PHP je pense que ça doit pas prendre plus de 1 seconde, alors toutes les 5 minutes c'est cool.
Surout que tu peux garder pas mal d'infos en javascript pour afficher ce qui est constructible ou pas.


RE: Gestion des prérequis - Myrina - 17-05-2011

(17-05-2011, 04:52 PM)Ter Rowan a écrit : pour les prérequis avec OU, perso je me suis borné au modèle suivant :

une action est composée de n contraintes

Pour réaliser une action il faut que toutes les contraintes soient validées.

Une contrainte est composée de n conditions

Pour qu'une contrainte soit validée, il faut et il suffit qu'au moins une condition parmi les n soit validées

une condition peut être liée à ce qu'on veut :
- un batiment
- une quete
- une connaissance,
etc...

(là j'ai transposé, je suis sur des actions au niveau du personnage, inventaire, compétence, lieu, énergie, ...)


j'attends avec intérêt ta solution
Pour ma part, j'ai fait la même approche (hormis le OU) sauf qu'au lieu de contraintes, j'utilise des éléments qui doivent attendre un certain niveau/nombre.

Par rapport à la proposition que j'ai fait initialement, il n'y a aucun changement dans le SQL (sauf changer les 'bati' en 'element') et pour les notions style quête, la réalisation de celle-ci ferait un stockage en interne de la quête au niveau 1 donc utilisable au même titre qu'un bâtiment comme prérequis.




RE: Gestion des prérequis - Jeckel - 18-05-2011

Je viens de faire un petit test pour les requête imbriqués.

J'ai une table user avec 4 utilisateur dedans, avec un id de 1 à 4.

Puis j'ai lancé plusieurs fois la requête suivante :
SELECT * FROM `user` WHERE `user_id` IN (SELECT CONVERT(RAND() * 100, UNSIGNED INT) % 4 + 1);

Le sous-requête me renvoie un (et un seul) nombre aléatoire compris entre 1 et 4.
En toute logique, on s'attendrait donc à ce que la requête complète nous renvois toujours un seul utilisateur, aléatoirement... ?

Dans les fais, plusieurs fois cette requête m'a renvoyé deux utilisateurs, voir trois.

Qu'est ce qu'il se passe ?

La première partie de la requête (SELECT * FROM user) extrait les 4 utilisateurs de ma table, puis ce résultat est filtré par la clause WHERE... donc pour chaque utilisateur il va tester si l'Id n'est pas dans la résultat de la seconde requête.... qui va donc être exécuté pour chaque utilisateur. Le résultat étant aléatoire, il se peut que 2 voir 3 (et même en théorie les 4) utilisateurs ressortent.

D'où, l'utilisation d'une sous-requête dans un WHERE est extrêmement lent, car si dans votre table utilisateur vous n'en avez pas 4 mais 200, ce sont donc 201 requêtes qui sont exécuté sur la base de donnée pour cet exemple.

(ceci est vrai pour MySQL, pour les autres SGBD je n'en sais rien du tout)
Et comme je suis d'humeur généreuse, voici la parade :
SELECT * FROM `user`
INNER JOIN (SELECT CONVERT(RAND() * 100, UNSIGNED INT) % 4 + 1 AS `user_id`) AS `rand_user`
USING (`user_id`)

Ici la sous-requête n'est plus dans le WHERE mais directement dans la jointure, elle fait donc partie de la première phase du SELECT et n'est donc exécuté qu'une seule fois... (oui bon, par contre c'est moins lisible)


RE: Gestion des prérequis - Myrina - 18-05-2011

Je suis d'accord avec toi sur les questions sur la performance; encore faut-il pouvoir y arriver!
Pour l'instant, j'ai trouvé comment faire pour savoir les bâtiments répondant aux prérequis (ceci n'inclue pas les bâtiments sans prérequis :'( => manque les bati 1 & 6)

SELECT p.id_bati
FROM bati_user u
RIGHT JOIN prerequis p ON ( u.id_bati = p.id_prerequis
AND u.id_user =1 )
GROUP BY p.id_bati
HAVING avg( if( ifnull( u.niveau, 0 ) >= p.niveau_prerequis, 1, 0 ) ) =1

Maintenant, coté performance, entre un sous-select est un group by... having; de deux maux, il faudra choisir le moindre