60

Sasume (./57) :
Quels sont les différents « modules » possibles ?

Je dirais qu'en fait, une "page" du programme constitue un module :
- la première page, "introduction", où l'on choisit de faire un scénario, une campagne, charger une partie, voir les crédits ou que sais-je encore
- la page des highscores est un module
- la page "ouverture de partie en cours" constitue un module

mais ce sont des modules très simples, c'est pour ça que je voulais commencer par là :
- fond d'écran
- icones
- listes
- quelques sprites

Le module évidemment le plus complexe est celui du champ de bataille :
- un objet map composé de :
-> sprite du terrain
-> données (météo, date, etc...)
-> des objets cases
--> un type de terrain
--> un indice de retranchement
--> autres
--> des chaines de caractères de descriptif/coordonnées associées aux cases
- deux objets "armée"
- objets icones, sprites du hud etc...
etc...


Il me semble donc nécessaire de définir
- une classe de base comportant l'ensemble des données commune (adresse de l'écran physique et autres données, routines de base de l'affichage d'un plan sur cet écran)
- une classe dérivée pour les écrans "statiques" (highscores etc...) parce qu'ils se ressemblent globalement niveau affichage et fonctionalités
-- chaque module "statique" dérive donc de cette classe dérivée
- une classe dérivée de la classe de base pour la bataille (classe unique et très spécialisée par rapport à la classe mère)

Ca va ?

61

tu dois avoir une classe abctact générique pour les objets, puis une classe abstract par type d'objets qui est étendue de la classe d'objet, et enfin une classe par objet final qui est étendue de sa classe de type
Ancien pseudo : lolo

62

Folco (./60) :
Il me semble donc nécessaire de définir
- une classe de base comportant l'ensemble des données commune (adresse de l'écran physique et autres données, routines de base de l'affichage d'un plan sur cet écran)
- une classe dérivée pour les écrans "statiques" (highscores etc...) parce qu'ils se ressemblent globalement niveau affichage et fonctionalités
-- chaque module "statique" dérive donc de cette classe dérivée- une classe dérivée de la classe de base pour la bataille (classe unique et très spécialisée par rapport à la classe mère)
Pourquoi pas. J’ai quand même l’impression que les modules « statiques » sont assez différents du module de bataille, non ? En fait il me semble juste que les modules statiques sont des menus qui permettent de lancer le jeu, non ?

Sinon, ça me fait un peu grincer les dents quand tu dis que la classe de base contient l’adresse de l’écran physique smile Je pense qu’il vaut mieux penser les classes en termes de fonctionnalités, vraiment sans se préoccuper des données qu’elles contiennent (vu que de toute façon ces données seront privées, donc inaccessibles aux autres classes).
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

63

Sasume (./62) :
Pourquoi pas. J’ai quand même l’impression que les modules « statiques » sont assez différents du module de bataille, non ? En fait il me semble juste que les modules statiques sont des menus qui permettent de lancer le jeu, non ?

Oui, c'est pour ça que je veux dériver une classe "module-statique" à partir de la classe "module", puis après des classes "modules-machin", "module-truc" dérivant de la classe "module-statique".
La classe "module-bataille" dérivera de la classe "module" directement (sans intermédiaire, c'est une classe unique en son genre).
Sasume (./62) :
Sinon, ça me fait un peu grincer les dents quand tu dis que la classe de base contient l’adresse de l’écran physique smile.gif Je pense qu’il vaut mieux penser les classes en termes de fonctionnalités, vraiment sans se préoccuper des données qu’elles contiennent (vu que de toute façon ces données seront privées, donc inaccessibles aux autres classes).

Oui, en fait j'ai déjà implémenté une classe "screen" dont la classe "module" recevra un pointeur, et qui contient l'adresse de l'écran en tant que membre privé (récupérable par eccesseur).

64

Tiens, j'ai pensé à un truc.
Si je fais une classe qui se charge de toute l'interface avec SDL, ça permet, en en réécrivant qu'une classe, de changer de lib ? Comme ça Godzil pourrait porter mon boulot pour Allegro, Lionel pour ExtGraph, Patrick pour Genlib, GoldenCrystal pour OpenGL, et enfin Kevin pour ... DirectX ? trivil



Sinon, le fait d'avoir la classe Screen donne une abstraction entre les classes et l'affichage, c'est suffisant, non ? Ca permet de garder de la souplesse ?

Dans ce cas, je me pose une question (récurente, là ce n'est qu'un exemple). La fonction de copie d'un plan sur l'écran doit-il incomber à la classe Module ou à la classe Screen ?

Si c'est aux modules, il font un this.Affiche(screen.GetPtr())
Si c'est au Screen, il faut faire un screen.Affiche(CePlan)

Que convient-il de faire ? La structure des classes en dépend (CePlan devra envoyer des références à des données dont screen.Affiche aura besoin, alors qu'elles resteraient en interne avec this.Affiche()).

Et sinon, ça va, je peux me lancer ?

65

Oui oui, vas-y…
Sinon, pour le problème de dépendances dont tu parles, c’est effectivement un problème récurrent, je ne saurais te donner une solution meilleure qu’une autre. À toi dans chaque cas d’estimer quelle devrait être la responsabilité de la classe.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

66

Sasume (./65) :
Oui oui, vas-y...

Tu dis ça sur quel ton ? tu penses que ça pourra aller, ou t'en as marre ? grin

67

Spipu (./54) :
pour ma part, j'aurais fait :
- un objet pour gérer les entrées (souris, clavier, autre)
- un objet pour gérer les sorties (l'écran)
- un objet pour gérer tout ce qui est base de donnée si tu en as - des objet pour gérer tes module, qui communiquent avec les 3 précédents objets
Spipu (./61) :
tu dois avoir une classe abctact générique pour les objets, puis une classe abstract par type d'objets qui est étendue de la classe d'objet, et enfin une classe par objet final qui est étendue de sa classe de type

Tu peux m'expliquer le pourquoi du comment stp ?

Je ne comprends pas l'intérêt d'utiliser un objet pour gérer les modules, parce qu'ils me semblent justement être la base de ce que j'utilise. Mais tu vois sûrement une autre manière de faire.

Et pourquoi décomposer autant les objets ? Une première classe objet dont dérive les objets finaux (icones, listes, tableaux) ne suffisent pas ?

68

./66 Aucun ton particulier smile Faut bien se frotter au code au bout d’un moment, c’est tout wink
./67 Il me semble qu’en ./61 il dit la même chose que toi en ./60, non ?
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

69

Oki hehe (et encore une fois merci mille fois pour tout ! smile)
Sasume (./68) :
./67 Il me semble qu'en ./61 il dit la même chose que toi en ./60, non ?

Je ne voyais qu'une seule décomposition :
classe objet générique -> classe objet spécialisé (genre icone)

Visiblement, il voit une décomposition supplémentaire :
classe abctact (?) -> classe abstract -> classe par objet final

70

tromb Fichier joint : cK5l (classes.png)

Il me semble que vous avez tous les deux proposé ce modèle, non ? (les classes Module et ModuleStatique sont abstraites)
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

71

Yay ! Moi en tout cas c'est ça grin

Bon maintenant, je sais faire ça avec Umbrello (de l'UML). En quoi cet outil peut m'aider à concevoir mes classes ? #lourd# fear grin

edit ->
Ma version : tromb Fichier joint : oCrO (screen15.png)

Ceci dit, maintenant je sais pas quoi en foutre #triclasse#

72

Ça te permet juste de voir en un coup d’œil les classes impliquées dans ton projet, leurs relations, leurs fonctions.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

73

C'est donc purement graphique ? Ca n'aide pas à la conception ? Je sens qu'il faut que je reprenne mon tuto d'UML ( http://uml.free.fr/ ) que j'avais largué parce que je n'en voyais pas l'intérêt. ^^

74

Je trouve que ça aide à la conception de bénéficier de cette représentation des classes.
Sinon tu fais quoi ? Tu as tout le modèle en tête ? Tu regardes directement ton code ? Dès que ça devient un tout petit peu complexe tu es largué.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

75

Ok ! Go UML !

Merci pour tooouuuutttt !!! calin bisoo

76

Spipu (./54) :
pour ma part, j'aurais fait :
- un objet pour gérer les entrées (souris, clavier, autre)
- un objet pour gérer les sorties (l'écran)
- un objet pour gérer tout ce qui est base de donnée si tu en as - des objet pour gérer tes module, qui communiquent avec les 3 précédents objets

Tiens, tu disais pas ça pour éviter dans le corps principal du programme :

int module = module_intro;


switch (module)
{
    case (module_intro):
        ....
        break;
    case (module_bidule):
        ....
}

?

Parce que pour le coup, je trouverais ça chouette en effet. hehe


edit ->
ayé ! cette classe sert de gestionnaire de tâche ! Donc avec l'initialisation de la SDL au début et sa fermeture dans le destructeur, le pied ! Plus de code avec des if(!truc){erreur();} de partout trilove Le panard. Adopté, merci Spipu t'auras pas prêché dans le vent boing

77

folco, j'aime bien ta méthode : cette autodidaxie t'honore. (Et j'en profite aussi. Bref, je m'abonne à cette discussion)

78

Bah, personnellement, je n'ai pas trop l'habitude de faire beaucoup de conception (design) à l'avance, je me plonge directement sur mon code C/C++, et le programme et sa structure (qui a en général tendance à être plutôt monolithique et procédurale, je n'ai pas vraiment internalisé la pensée "objet") se crystallisent au fur et à mesure que je code.

Un invariant auquel je tiens beaucoup est que le code doit rester compilable au fur et à mesure que je développe. Quand je fais des modifications qui rendent le code non compilable, j'essaie toujours de corriger ça d'abord avant de continuer. Ceci me permet de corriger les fautes facilement (parce que le compilateur me les indique), faire des tests dans une certaine mesure et effectuer des commits réguliers tout le long du développement. Par conséquent, ma stratégie est quelque part entre le top down strict (la manière naturelle de coder sans plan: on code, on voit les fonctions qui manquent, on code ces fonctions etc.) et le bottom up strict (la meilleure manière de garantir la compilabilité: on ne code pas une fonction avant d'avoir les fonctions dont on a besoin codées). Parfois, je travaille top down, parfois bottom up (sur le même logiciel), et souvent je code le long du fil d'exécution (je code, je vois que je veux appeler une fonction qui n'existe pas encore, donc je code la fonction, ensuite je reviens à la fonction appelante; oui, c'est très procédural comme manière de fonctionner).

L'UML, je n'en vois pas vraiment l'utilité, ça ne rentre pas du tout dans ma manière de fonctionner.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

79

Programmer à l'instinct, on aime tous, mais c'est le mal en terme d'heure/homme en entreprise.
Si tu vas dans ce sens, on peux pousser à l'extrême :
"Je code comme je comprend : je teste : ça bug, je corrige jusqu'à ce qu'il n'y ait plus de bug : ça marche."
vs.
"Avec quelques heures de recherche, je m'évite des semaines de travail (toujours en heure/homme) de perdues en déboggage."
Sans compter qu'on a un code con mais debuggé (pour les cas simples) d'un côté, contre un code malin avec quelque bug de l'autre (et des bugs touchant seulement les cas "exceptionnels").

La version 1 fait rêver, mais la deux est efficace. C'est comme ça.
Surtout dès que tu touches à des bases de données.

Je poste ça, mais je lutte moi même contre la version 2, enfin, surtout mon chef ^^.

80

Oué, ben j'ai pas le cerveau pour mener un petit projet en avançant comme ça, alors on parle pas d'un gros grin

Sinon, mon jeu est fini ! \o/
#include    <SDL.h>
#include    "task.hpp"


int main (void)
{
    Task MainTask;
    if (!MainTask.getSDLState())
        return EXIT_FAILURE;
    return MainTask.ManageTask(TASK_INTRO);
}

enfin, presque, mais j'ai déjà écrit tout main.cpp ! #triclasse#

81

Bah, à mon avis, c'est plutôt le code conçu à l'avance qui a tendance à être "con", ou plutôt inadapté aux contraintes réelles qui n'ont pas pu être prévues.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

82

Il faudrait que tu sois plus persuasif que ça, pour que j'arrive à y croire afin de convaincre mon chef.

83

Je ne suis pas du tout, mais alors pas du tout convaincu par la méthode de Kevin grin
Ca ne peut pas marcher en équipe, ça ne peut pas marcher quand tu travailles sur un projet commandé (pour lequel tu as un cahier des charges), ça marche difficilement pour un projet sur plusieurs années...
avatar

84

Un article très intéressant qui compare ces deux types de méthodes : ftp://ftp.software.ibm.com/software/rational/web/whitepapers/2003/TP167.pdf
avatar
I wanna... bioman, bioman, défenseur de la teeeerrrreee

85

Nil (./83) :
Ca ne peut pas marcher en équipe

Si, il y a bien moyen de coder de manière purement incrémentelle en équipe, du moins dans beaucoup de cas. Évidemment, si l'équipe n'a pas l'habitude de travailler ensemble, si tous les développeurs codent en même temps, si le projet n'a pas une décomposition en modules évidente dès le départ (ou si l'interaction entre les modules est trop forte) et si les outils utilisés pour coder ne permettent pas de merges efficaces, ça va être le désastre. Mais il y a plusieurs moyens de s'en sortir. Par exemple développer en paire avec une personne qui code le jour et une la nuit (déjà essayé, par exemple sur ld-tigcc (même si ce n'était pas forcément un projet "conçu en codant" et même si Sebastian l'avait commencé seul, donc ce n'est pas forcément un bon exemple): d'habitude, Sebastian codait le jour et moi la nuit et on s'échangeait les patches par mail, il n'y avait presque pas de conflits entre les patches parce que chacun travaillait à son tour).
ça ne peut pas marcher quand tu travailles sur un projet commandé (pour lequel tu as un cahier des charges)

Si. On implémente une charge à la fois de manière incrémentelle et à la fin du processus, on a couvert tout le cahier des charges. Le cahier des charges est censé spécifier les exigences à couvrir, pas la manière dont on le fait, donc on peut très bien coder avec un cahier des charges, mais sans un concept de l'architecture du programme.

Bien sûr il y a aussi le cas où la liste des charges est dynamique (d'ailleurs, c'est souvent le cas en pratique même quand sur papier, il y a un cahier de charges; il est tout aussi difficile pour le client que pour le programmeur de prévoir le futur), dans lequel cette liste évoluera aussi au fur et à mesure qu'on code, mais même quand la liste est fixe, ça ne change pas de beaucoup cette manière de coder. (Cela dit, connaître les exigences à l'avance, quand la liste est vraiment fiable, peut faciliter des méthodes de programmation où on planifie à l'avance. Quand les charges exactes ne sont pas connues dès le départ, c'est tout de suite beaucoup plus difficile.)
ça marche difficilement pour un projet sur plusieurs années...

Pourtant il y a plusieurs de mes projets codés comme ça qui ont plusieurs années, et j'arrive toujours à les maintenir. (Il y a un seul projet que je n'arrive plus à maintenir, c'est Tokens89: un bordel infame de bidouillages fragiles parce que je n'y connaissais rien au parsing à l'époque, du code qui dépend d'à peu près toutes les propriétés tordues du VB5 (langage propriétaire et obsolète), bref faudrait tout réécrire. sad Ce n'est pas du tout un problème d'organisation du code.)
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

86

Kevin Kofler (./85) :
Par exemple développer en paire avec une personne qui code le jour et une la nuit

Mince alors, pourquoi on n'y avait pas pensé ? cheeky
avatar
I wanna... bioman, bioman, défenseur de la teeeerrrreee

87

D'ailleurs, les fuseaux horaires peuvent aider dans cette manière de fonctionner. smile
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

88

Souane (./84) :
Un article très intéressant qui compare ces deux types de méthodes : ftp://ftp.software.ibm.com/software/rational/web/whitepapers/2003/TP167.pdf

Attention, ce document a été écrit par les personnes derrière le Rational Unified Process, donc forcément il va dire que le RUP est la meilleure chose au monde…
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

89

Non non, pas du tout smile Le mec fait plutôt les louanges d'XP smile (même s'il explique ce qu'il aime dans RUP)
avatar
I wanna... bioman, bioman, défenseur de la teeeerrrreee

90

Souane (./84) :
Un article très intéressant qui compare ces deux types de méthodes : ftp://ftp.software.ibm.com/software/rational/web/whitepapers/2003/TP167.pdf
Hm, j’ai un peu la flemme de tout lire, tu veux pas faire un petit résumé ? gni
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »