conditions multiples dans un switch - problème de design pattern [PHP] - PHP - Programmation
Marsh Posté le 23-01-2008 à 15:18:34
A ta place, j'utiliserais des fonctions. Comme ça, il ne te restera plus qu'a appeller la/les bonne(s) fonction(s) en fonction du cas et tu éviteras toute duplication du code.
Marsh Posté le 23-01-2008 à 15:20:59
le truc c'est que je suis déjà dans une fonction qui calcule les déplacements en fonction de la pièce, le tout dans un objet.
Ca me parait plus propre, non ? (question sincère... j'essaie d'être propre et lisible.)
et puis je suis curieux... le switch doit bien prévoir ce cas, non?
d'autres avis ?
Marsh Posté le 23-01-2008 à 15:25:00
ton switch est pourri. Pourquoi fais-tu plusieurs "case" avec les mêmes valeurs?
Code :
|
Marsh Posté le 23-01-2008 à 15:34:18
soulmanto a écrit : ton switch est pourri. Pourquoi fais-tu plusieurs "case" avec les mêmes valeurs? |
Tu n'as pas compris le problème....
Il veut assimiler la dame à fou+tour.
Je suis d'accord avec omega2, à mon avis c'est la meilleure solution.
Marsh Posté le 23-01-2008 à 15:36:07
La structure switch n'a jamais été faite pour dire "si 'machin' ou 'truc' alors blabla + ce que fait 'chouette' sauf si 'machin'.
Par contre si tu ne mets pas de break alors ça donne bien "si 'machin' ou 'truc' alors blabla + ce que fait 'chouette'" et ça, le switch le gère bien.
Pour le fait que t'es déjà dans une fonction : oui et alors? Rien n'empêche d'avoir une fonction qui sert à appeller la bonne fonction en fonction d'une valeur donnée. Si en plus ton objet représente une pièce, alors il aurait été plus propre de faire une classe par type d'objet plutôt qu'une classe générique, même s'il est vrai qu'une partie du code risquerait d'être dupliqué si tu as plusieurs classes différentes.
PS : Je ne le dis pas de la même manière, mais je suis d'accord avec soulmanto. D'ailleurs, un switch est comme une suite de "si alors blabla sinon si" et non pas de "si alors blabla fin du si, si alors ..." ce qui veut dire qu'il ne peut jamais y avoir plusieurs label identique.
Marsh Posté le 23-01-2008 à 15:39:16
en l'occurence, j'ai une classe piece
avec un attribut "type" qui me dit de quelle piece je parle
dans cette classe piece j'ai une méthode calculePositions dans laquelle je fais switch($this->type)
il faudrait donc que je crée d'autres méthodes genre :
calculePositions_Fou, calculePositions_Dame, calculePositions_Tour, etc
???
Marsh Posté le 23-01-2008 à 15:44:30
Et heu ... pourquoi ne pas faire des classes "fou", "roi" ... qui dérivent de la classe "piece" générique et qui redéfinissent la fonction "calculePositions"?
Le système d'héritage d'une classe n'a pas été inventé pour des prunes.
PS : En passant, jette un oeuil aux motif de conception (design pattern en anglais) : http://fr.wikipedia.org/wiki/Motif_de_conception
http://en.wikipedia.org/wiki/Desig [...] r_science)
Il en existe un qui sert à choisir la bonne classe à partir d'une condition donnée.
Marsh Posté le 23-01-2008 à 15:45:17
Citation : Tu n'as pas compris le problème.... |
Si, j'ai parfaitement compris ce qu'il veut faire, seulement la façon dont il le traduit en code n'est pas bonne. Chaque pièce est une entité distincte avec ses règles particulières, donc fonctionnellement leurs traitements sont différents.
Marsh Posté le 23-01-2008 à 16:54:33
omega2 a écrit : Et heu ... pourquoi ne pas faire des classes "fou", "roi" ... qui dérivent de la classe "piece" générique et qui redéfinissent la fonction "calculePositions"? |
design pattern... j'ai vu ca à l'école... mais c'est loin
ce dont tu parles, c'est le design pattern factory ?
si c'est ca, je ne vois pas trop comment l'adapter à mon cas... tu aurais un exemple ?
merci
Marsh Posté le 23-01-2008 à 17:02:19
Plus exactement, c'est la fabrique abstraite (Abstract Factory)
J'ai la flemme de créer une exemple exprès pour toi alors je te file le liens d'un exemple disponible sur wikipedia : http://fr.wikipedia.org/wiki/Fabri [...] ion%29#PHP
Dans leur cas, ils lisent un fichier de config pour savoir quel bouton créer, dans le tiens, t'auras un paramètre qui te diras quelle pièce créer.
Marsh Posté le 23-01-2008 à 17:58:04
Et petit lien qu'il est bien ( from Masklinn, signé de qualité)
http://gsraj.tripod.com/design/cre [...] ctory.html
Marsh Posté le 23-01-2008 à 19:33:55
omega2 a écrit : Et heu ... pourquoi ne pas faire des classes "fou", "roi" ... qui dérivent de la classe "piece" générique (...) Le système d'héritage d'une classe n'a pas été inventé pour des prunes. |
Dans mes bras !
Marsh Posté le 24-01-2008 à 11:53:38
j'ai essayé un pattern strategy, avec une interface Ipiece :
Code :
|
ca vous parait bien ?
est ce que dans la classe dame, je suis obligé de recopier la méthode checkMove de fou et de tour ?
d'autre part, au niveau conception, comment je peux matérialiser un joueur ?
merci
Marsh Posté le 24-01-2008 à 11:56:17
pourquoi faire une classe abstraite qui implémente une interface plutot que de déclarer les méthodes de l'interface comme abstraites dans ta classe abstraite???
(note: je suis pas persuadé que cette phrase soit compréhensible)
Marsh Posté le 24-01-2008 à 12:05:55
pas compris
tentative de réponse : pourquoi pas ?
je me suis inspiré d'un script d'implémentation de design pattern strategy ici :
http://classes.scriptsphp.org/arti [...] n-Strategy
l'interface : je vois pas encore l'intérêt d'en avoir, sinon de forcer à écrire toutes les méthodes à chaque fois. (même si, si l'on oublie une méthode, on devrait s'en rendre compte assez vite ?)
Marsh Posté le 25-01-2008 à 09:47:38
Je vais la retenter autrement
Je vois pas l'interêt de l'interface dans ton précis.
Du coup j'aurais tendance à faire:
Code :
|
L'interface n'a a mon sens d'interêt que si tu as plusieurs "jeux" qui ont des pièce ( par exemple echec, dame, go ...).
A ce moment là, ton interface te permettra de t'assurer que tu disposes des methodes d'une pièce quelque soit sa classe abstraite (piece_echec, piece_dame, piece_go).
Une dernière remarque, si 'toto' est un echiquier je suis pas fan de comment tu t'en sers. Pour moi une pièce est sur un et un seul echiquier.
Je me demande si je ferais pas plutôt un builder sur ta classe echiquier.
Marsh Posté le 25-01-2008 à 10:58:38
hello
non, mon échiquier ne servira pas à jouer aux dame
je n'ai pas non plus mon passage d'argument.
j'arrive à un truc genre
Code :
|
ce qui ne semble pas très propre...
qu'entends-tu pas builder ?
edit : tu parles probablement du design pattern builder... je me plonge dans wikipedia, et je reviens
Marsh Posté le 25-01-2008 à 19:30:33
re -
j'ai essayé quelque chose, en voulant implémenter un design pattern 'composite' (dans l'optique de dire : une case est une partie du tableau, donc il y a une hiérarchie : le design pattern composite semble être adapté dans ce cas.)
la source de mon inspiration est là : http://www-igm.univ-mlv.fr/~dr/XPO [...] terns.html (c'est du PHP4, mais je n'en prends que l'idée...)
je rajoute donc un attribut $board à mon objet piece, en le plaçant en référence au constructeur de piece.
du coup, je me retrouve avec un objet $board, constitué d'un double array de cases pouvant contenir des instances de piece, instances qui contiennent elles mêmes un pointeur vers $board...
c'est là que ça cloche à mon avis.
je poste le code, au cas où :
classe piece simplifiée :
Code :
|
classe board simplifiée :
Code :
|
et pour tester on peut coller ca à la fin du fichier qu'on appelle classes.php:
Code :
|
voilà. j'ai épuré le code, mais le principe est là.
si quelqu'un peut m'aider, ca serait sympa.
euh... je rappelle ma question :
- est ce qu'il faut bien implanter un design pattern composite,
- si oui, est ce que mon composite est bien implanté (j'en doute...)
- si non, qu'est ce qui cloche ?
-si non, quel est le design pattern pour mon cas ?
merci
Marsh Posté le 25-01-2008 à 19:44:06
j'ai fait des schémas sur papier
pour le nommage... c'est pas trop un problème (enfin le problème n'est pas là)
pour les joueurs, je pensais faire une classe partie, mais que je ferai plus tard.
pour l'instant je veux juste modéliser les pieces et leur déplacement
et donc je cherche le design pattern le plus adapté à mon cas
Marsh Posté le 25-01-2008 à 20:01:45
c'est quand même pas sorcier.
Note préliminaire : le PHP j'y pipe rien, la c'est un probleme purement objet, a toi (ou à vous les autres posteurs) de mettre le nom de la classe de base qui va bien la ou il faut.
Les entités en présence :
Joueur
Case
Equiquier
Piece
Partie
Les relations :
Une Partie contient :
2 Joueurs
1 Echiquier
2*12 Piéces
Un Echiquier contient
une collection de 8*8 cases
Un case contient :
un pointeur vers la Piéce qui est dessus (potentiellement NULL)
Une piéce contient
un pointeur vers le joueur à qui elle appartient
Première étape : comment tou ça dialogue-t-il ?
* Un joueur peut bouger une pièce en appelant la méthode move() de la piéce
a qui il passe la case de destination.
* Lorsque une piéce bouge, elle prend sa case de destination
et vérifie si le mouvement est valide. Si il est , elle se déplace
(elle s'enleve de sa case et va vers la case destination)
Deuxième étape : Comment une piéce sait elle si son deplacement est valide
Pour chaque type de déplacement élémentaire (tout droit, en diagonale, de une case seulement etc)
tu creer une classe Mouvement qui contient une methode check() qui renvoit un bool qui dit si oui ou non
le mouvement est valide en prenant en argument la case source et la case destination.
Ensuite, chaque piece contient une liste de Mouvement. La méthode check de la pièce appelle donc en séquence
les check() de ses mouvements et les combine avec un ET logique.
Chaque pièce recoit à la construction le ou les Mouvement qui lui sont associés.
En gros tu as besoin :
* d'une factory pr creer tes piéces
* la liste de mouvement implante Strategy
* Je mettrais bien un flyweight pr gérer les stratégies sans les dupliquer.
Marsh Posté le 25-01-2008 à 20:08:38
C'est ici, la fabriquation d'usines à gaz?
Marsh Posté le 25-01-2008 à 21:06:55
Absolument pas tant qu'on me demande pas d'implémenter cette horreur
Marsh Posté le 26-01-2008 à 10:21:58
oui, c'est flyweight. Ma fourche à languer, c'est bien de ça dont je veux parler.
Je retro-corrige
Marsh Posté le 26-01-2008 à 12:25:04
Joel F a écrit : c'est quand même pas sorcier. |
je vais essayer de comprendre tous le message (surtout la fin, parce que pour le début, on est bien d'accord), puis je ferai un dessin
merci pour ton aide.
masklinn a écrit : C'est ici, la fabriquation d'usines à gaz? |
euh... tu as une idée pour faire plus simple.
PS : effectivement, le PHP osef pour l'instant. on parle bien de conception, et si je m'en sors bien, le PHP (ou autre) passera sans problème.
Marsh Posté le 26-01-2008 à 14:00:21
nabbo a écrit :
PS : effectivement, le PHP osef pour l'instant. on parle bien de conception, et si je m'en sors bien, le PHP (ou autre) passera sans problème. |
Ne pas faire un objet complet de chaque pièce, ça n'a aucun intérêt dans la mesure où les pièces ne sont pas des agents intelligents mais des marqueurs explicitement manipulés par un agent externe (que tu peux voir soit comme le plateau, soit comme le joueur, soit comme le joueur par l'intermédiaire du plateau). Donc perso je modéliserais les pièces comme de simple dataholders pour deux éléments (au mieux), le type (de pièce, au sens dame/fou/roi/autre, juste pour pouvoir l'afficher correctement) et les contraites de déplacement. Point barre, et c'est le tableau qui, sur ordre de déplacement d'un joueur, vérifie que le déplacement respecte les contraintes de la pièce.
Je ne vois absolument pas quel logique pourrait être intéressante dans la pièce, à part "aucune".
edit: ah si, on peut lier un "widget" aux pièces pour qu'elles sachent comment s'afficher, mais c'est pas de la logique "métier".
Marsh Posté le 26-01-2008 à 14:08:37
masklinn a écrit : |
oui, dans ma conception de départ, c'était le plateau qui déplacait les pieces, et qui vérifait les positions possibles.
les pieces n'avaient que des attributs, dont leur nom, leur position actuelle et leurs positions possibles calculées à la demande du plateau.
Marsh Posté le 26-01-2008 à 14:21:57
nabbo a écrit : |
Tu comptes créer un bot jouant aux échecs ou pas?
Marsh Posté le 26-01-2008 à 14:27:29
oui, c'est prévu
edit : ca changerait quoi selon toi ?
Marsh Posté le 26-01-2008 à 15:05:21
nabbo a écrit : oui, c'est prévu |
Que s'il y a des bots il faut pouvoir calculer les mouvements possibles des pièces, alors que s'il n'y a pas de bot il faut juste calculer qu'un mouvement est valide (c'est pour ça que je parlais de stocker des contraintes, j'étais parti du principe qu'il n'y avait pas de bot)
Marsh Posté le 26-01-2008 à 15:12:07
en fait, je calcule les positions possibles :
- pour aider "l'utilisateur novice" à savoir où il peut bouger pour une pièce donnée
- ensuite, comme j'ai stocké les positions possibles dans un tableau qui est un attribut de mon objet piece, je n'ai qu'à vérifer, après mouvement, que celui ci est dans la liste des mouvements possibles.
- et, effectivement, cela me permettra (je pense) de simplifier les choses avec un bot
le bot n'est qu'un projet d'évolution que je garde en tête. je pense que dans mon schéma de départ, c'est la classe joueur et la classe partie qui vont changer. les mouvements et le plateau restent les mêmes.
Marsh Posté le 26-01-2008 à 15:27:49
masklinn a écrit : |
qu'est ce que tu appeles un dataholder ?
ca reste un objet au sens poo ?
c'est à dire une instance de classe avec des attributs et pas (ou peu) de méthodes ?
Marsh Posté le 26-01-2008 à 15:40:18
nabbo a écrit : |
Oui, c'est équivalent à une struct C ou un record, c'est un objet/une classe qui n'existe que pour stocker des données mais n'a pas de comportement (méthodes, messages, ...)
Marsh Posté le 23-01-2008 à 15:11:42
NOTE : pour le problème de design pattern, descendez un peu dans le topic, ici :
http://forum.hardware.fr/hfr/Progr [...] m#t1676944
je rencontre un petit problème (dont la solution est surement toute bête, mais... je trouve pas )
pour placer dans le contexte je peux résumer comme ça :
je dois étudier les mouvements des pieces d'un jeu d'échecs.
Pour résumer dans le cas qui me concerne :
- un fou peut se déplacer en diagonale
- une tour peut de déplacer à l'horizontale/verticale.
- une dame se déplace en diagonale ET à l'horizontale/verticale.
donc une dame est à la fois un fou ET une tour.
traduction en PHP :
Le code ci dessus fait se comporter la dame comme un fou.
si j'enlève les break, alors toutes les pièces sont des dames.
Mon but :
- si je mets "Fou" dans la variable $a, cela imprime Fou
- si je mets "Tour" dans la variable $a, cela imprime Tour
- si je mets "Dame" dans la variable $a, cela imprime FouTour
Les solutions que j'ai trouvées :
- mettre un case "dame" dans lequel je copie le code de Fou ET Tour. ça marche, mais ça duplique le code, c'est pas très propre.
- mettre un if($a!="Tour" ) dans le case tour, mais c'est encore plus sale.
voilà.
je sais pas si c'est très clair, mais si vous pouvez m'éclairer pour faire un truc propre, c'est cool.
Merci
Message édité par nabbo le 25-01-2008 à 19:39:10