TER M1 Jeu de stratégie historique

Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
TER M1 Jeu de stratégie historique

Forum du sujet de TER : Algorithme min-max dans les jeux de stratégie historique, pour les étudiants de M1 de Montpellier II 2008-2009.

Le deal à ne pas rater :
Cartes Pokémon EV6.5 : où trouver le Bundle Lot 6 Boosters Fable ...
Voir le deal

4 participants

    Proposition pour la conception du schmilblick

    Cédric
    Cédric


    Messages : 205
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Proposition pour la conception du schmilblick

    Message  Cédric Lun 26 Jan - 23:34

    Comme j'ai la flemme de faire de l'UML ce soir, je vais juste parler de l'idée de base, qui ne sera du coup pas forcément très claire pour le moment (voire pas du tout Very Happy), surtout si vous n'êtes pas habitués à la conception de jeux vidéo. J'essaierai de me motiver à compléter ça avec l'UML et les dessins correspondants demain.
    (ps : et à finir de blablater, vu que je me suis arrêté au milieu :p)

    Les principaux "modules" :

    - un ensemble de données (la carte avec les groupes dessus), accessibles par l'ensemble des autres modules via une méthode statique d'une classe servant à les gérer (un singleton).
    - moteur de jeu : il s'assure du respect des règles du jeu (cad vérifier qu'un déplacement ou une attaque proposée par l'utilisateur est valide par ex), de calculer ce qu'il y a à calculer (déroulement des batailles par ex), de l'IA, etc.
    - moteur graphique : chargé d'afficher le jeu, d'écouter les évènements clavier, souris, et de les traduire en données utilisables par le moteur de jeu :
    + ex : faire le passage de coordonnées graphiques en coordonnées sur la carte de jeu.
    + autre ex : traduire l'appui sur la touche "Echap" par un évènement "machin veut fermer le jeu".
    - moteur audio : on s'en fout (presque) complètement, mais il faut prévoir qu'il puisse y en avoir un un jour.
    - moteur réseau : on s'en fout complètement aussi, mais idem, il faut envisager l'inenvisageable Very Happy

    Communication entre les moteurs :

    - Toutes les communications entre les moteurs se font à l'aide d'objets "Event" (vu qu'il est question d'évènementiel). Ils contiennent plusieurs attributs :
    + source de l'évènement (string)
    + type de l'évènement (string) : un identificateur permettant de savoir quelles seront les clés utiles dans les données ci-dessous
    + données (map<string,string>)
    + données (map<string,int>)
    + et si le besoin s'en fait sentir : données (map<string,float>)
    Cette structure permet de faire passer n'importe quel type d'information d'un moteur à l'autre, et surtout, elle le fait sans préjuger du protocole utilisé, ce qui est important dans la mesure où il est appelé à grandir considérablement au cours du développement.

    La communication d'Event entre deux moteurs se fait selon le pattern "Observateur" (mais pas exactement, j'en parlerai après). Je vais essayer de commencer par le début :

    -A l'initialisation du programme, on fait en sorte que les moteurs soient capables de s'écouter entre eux. Par exemple :
    - moteurJeu.addEcouteur(moteurGraphique);
    - moteurJeu.addEcouteur(moteurAudio);
    - moteurJeu.addEcouteur(moteurReseau);
    - moteurGraphique.addEcouteur(moteurJeu);
    - moteurGraphique.addEcouteur(moteurAudio);
    - moteurGraphique.addEcouteur(moteurReseau);
    - et idem pour les deux autres moteurs.

    A l'issue de tout ce schmilblick, admettons qu'une bataille entre deux groupes soit calculée par le moteur de jeu. Il créera pour l'occasion un évènement disant (je traduis en Français) "il y a eu une bataille entre le groupe situé en (12,3) et celui situé en (12,4), pendant le tour de Mr. Machin. Il reste 31 soldats à l'un et 47 à l'autre", et l'enverra à qui veut bien l'entendre. Ces gens qui veulent bien l'entendre, c'est justement les trois autres moteurs, qui chacun traiteront l'évènement à leur manière, en fonction de leurs responsabilités :
    - Le moteur graphique mettra à jour l'affichage des deux groupes concernés. C'est son job.
    - Le moteur audio pourra jouer un son "Mange toi ça face d'huître", "Aïeuuuh !", ou je ne sais quoi pour agrémenter l'action (juste pour l'exemple, vu qu'on se moque pas mal de l'audio en fait)
    - Le moteur réseau sérialisera l'évènement et l'enverra par le réseau aux autres joueurs, ce qui permettra une synchronisation des données (mais c'est juste pour l'exemple aussi, faudrait être fou pour se lancer dans du réseau Very Happy)

    Donc, j'ai parlé d'envoyer un évènement, mais je n'ai pas dit comment. Une façon simple pourrait être d'utiliser deux fonctions communes aux moteurs :
    - envoyerEvenement(Event) : appelle la fonction onEvent(Event) de tous les écouteurs de ce moteur
    - onEvent(Event) : traite l'évènement passé en paramètre. Cette méthode est appelée "à distance" par les autres moteurs lorsqu'ils veulent transmettre des informations.

    On a donc à faire à du pattern Observateur... Mais en fait, c'est mal ! Very Happy

    En effet, si on fait ça, tout se passera dans le même thread. C'est pas un problème en soi, mais nous, on aura des traitements lourds (l'IA). Donc quand l'IA travaillera, l'interface freezera lamentablement. On a connu mieux... Il faut donc que la communication entre les moteurs soit asynchrone, ou dit autrement, que chacun ne travaille que dans des threads qui lui sont propres. Là aussi, ça serait bien plus clair en dessin, mais la flemmeuuuuh :'(

    Je vais quand même essayer d'expliquer vite fait les étapes :
    - les moteurs sont dotés, en plus du reste, d'une file d'objets "Event" (je ne parle pas de file comme on a vu en système, mais d'objet de la STL hein). C'est elle qui permet de rendre les communications asynchrones.
    - la méthode envoyerEvenement(Event) n'appelle plus directement les fonctions onEvent(Event) des écouteurs, mais à la place une fonction enfilerEvent(Event). Cela aura pour effet de mettre l'évènement dans la file des moteurs cibles, et c'est tout ! Fin du travail pour le thread expéditeur du message, qui peut directement passer à autre chose => pas de blocage.
    - les threads des moteurs destinataires sont alors réveillés, puisqu'un Event est arrivé dans la file. Ils l'en sortent donc, et le traitent (sans emmerder les autres donc).

    Résolution des petits problèmes liés au multithreading

    En fait, il n'y en a pas tant que ça, vu que les données des différents moteurs sont bien séparées entre elles, et qu'au sein des moteurs, il n'y a pas 36000 threads qui se les disputent. Par contre :
    - multithreading oblige, l'affichage du jeu peut se faire en même temps que des modifications des données (la position des groupes par exemple). Si rien n'est fait, on pourra potentiellement se retrouver avec le même groupe présent dans deux cases différentes (c'est juste un exemple, je suis sûr qu'il y aurait plein d'autres bugs marrants Very Happy). Il faut donc que les données utilisées par le moteur graphique soient figées le temps de l'affichage des animations. Pour cela, on ne peut pas utiliser de verrou : cela rendrait les threads totalement inutiles. Il faut donc pouvoir copier "en dur" les données du "plateau de jeu" (ce qui reste quand même très léger, vu qu'il n'est pas nécessaire de mettre en dur dans les objets "Groupe" les images associées). Cela peut se faire via le singleton gérant les données (une méthode getCopie() par ex...).
    - Plusieurs threads peuvent en même temps tenter d'ajouter un évènement à la file d'un même moteur. Que se passe t-il dans ce cas ? Bonne question ! Very Happy Je ne sais pas si cette opération est thread-safe, mais si elle ne l'est pas, il faudra verrouiller tout ça.


    Dernière édition par Cédric le Mar 27 Jan - 23:13, édité 1 fois
    avatar
    sebastien


    Messages : 137
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  sebastien Mar 27 Jan - 2:02

    pour l'instant j'ai tout comprit (en même temps l'habitude de tes conceptions Razz) et je suis entièrement d'accord ^^
    avatar
    Stretcher
    Admin


    Messages : 27
    Date d'inscription : 23/01/2009
    Age : 35

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Stretcher Mar 27 Jan - 13:45

    Jusque là, j'arrive à suivre... Je suis juste un peu effrayé à l'idée que tu aies pu penser à tout ça tout seul. O_o
    avatar
    sebastien


    Messages : 137
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  sebastien Mar 27 Jan - 22:16

    en même temps on en est pas a notre premier projet, ni notre premier jeu, et il est fanatique de conception. Chez lui il ne fait que de coder Razz
    Cédric
    Cédric


    Messages : 205
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Cédric Mar 27 Jan - 23:12

    'foiré ! Je ne fais pas que coder en plus, je lis aussi de la doc... Sad

    Bon par contre, j'ai encore la flemme de faire de l'UML... Vu que j'ai été apparemment plus compréhensible que je l'espérais, je vais en rajouter une couche, mais il faudra quand même que je me motive après pour l'UML...

    Je vais donc éditer le premier post dans les minutes à venir : ajout du contenu de la partie "Résolution des petits problèmes liés au multithreading"
    Quentin
    Quentin


    Messages : 120
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Quentin Mer 28 Jan - 17:35

    Sleep ... affraid j'v te dire ok. En gros j'ai compris et je suis d'accord. Mais ca fait peur :p
    Cédric
    Cédric


    Messages : 205
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Cédric Mer 28 Jan - 17:53

    Mais euuuh ! Very Happy
    Quentin
    Quentin


    Messages : 120
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Quentin Mer 28 Jan - 17:55

    un petit diagramme UML pour être plus clair non ? Wink
    Cédric
    Cédric


    Messages : 205
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Cédric Mer 28 Jan - 18:43

    Je n'ai pas le temps là de suite, et peut être pas ce soir non plus... Si je ne fais pas les diagrammes demain par contre, vous pouvez me lapider ^^
    avatar
    Stretcher
    Admin


    Messages : 27
    Date d'inscription : 23/01/2009
    Age : 35

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Stretcher Mer 28 Jan - 19:44

    (Encore une question de culture : y a un moyen simple de faire des diagrammes UML autrement qu'à la main ?)
    Quentin
    Quentin


    Messages : 120
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Quentin Mer 28 Jan - 20:42

    Avec un logiciel :p
    Cédric
    Cédric


    Messages : 205
    Date d'inscription : 24/01/2009

    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Cédric Sam 7 Fév - 19:03

    Vu dans les épisodes précédents (post sur le cahier des charges) :
    Cédric a écrit:Je suis en train de penser que le multithreading de l'application, c'est bien sympa, c'est un objet de fantasme et tout (non ? Very Happy), mais ça nous posera aussi pas mal de problèmes (ça n'a pas l'air si compliqué au premier abord, mais pourtant...). Par exemple, on ne peut pas lâcher complètement le moteur de jeu dans la nature pendant qu'il calcule des mouvements de l'IA non encore affichés : il y a des cas où l'interface pourrait récupérer une copie des données en retard, et donc carrément sauter l'affichage d'un coup. Ça peut bien sûr se régler, mais ça prendra un temps qu'on ferait mieux de ne pas passer sur du hors-sujet, finalement...

    Ce qui est sûr, c'est qu'il faudrait éviter de parler de multithread dans le cahier des charges (un truc qu'on peut potentiellement foirer, c'est pas le top :p). Je pense aussi qu'on ferait mieux, dans un premier temps, de tout faire dans un seul thread, mais en laissant le reste inchangé (donc l'UML aussi). Si on ne sait plus quoi faire à la fin (ce qui m'étonnerait Very Happy), on pourra tenter d'ajouter ça (je ne vois pas de problème d'incompatibilité majeur avec ce que l'on aura fait jusque là...)

    D'ailleurs, en parlant de cahier des charges, je suis en train d'écrire la partie sur l'architecture. Je la fait à part pour le moment, donc vous pouvez retoucher le cahier des charges existant sans problème (dans le cas où les petites boulettes qu'on avait repéré y seraient toujours).
    Sauf qu'étant un peu trop intoxiqué au Java, j'avais un poil oublié le fait qu'il n'y a pas de base un thread dédié à la gestion des évènements en C++. Il faudra donc au moins en ajouter un pour ça. Sinon, entre les animations s'il y en a un jour et les calculs d'IA (là, j'espère bien qu'il y en aura un jour Very Happy), on aurait parfois du mal à quitter l'application autrement qu'en tuant le processus.

    Une solution simple :
    - la fonction main initialise tout, dont le moteur graphique qui effectue la boucle évènementielle.
    - lorsqu'un évènement est intercepté, on le traite sur place (s'il ne concerne que l'affichage), ou il faut envoyer un message au moteur de jeu. Dans ce cas, on effectue l'envoi dans un autre thread.
    - la vie passionnante de ce thread : envoi d'un message au moteur de jeu -> calcul de l'IA etc -> envoi d'un message au moteur graphique pour afficher les changements -> affichage -> et c'est fini

    Il reste un problème à résoudre : en faisant comme ça, si l'utilisateur fait 1000 clics à la seconde, déjà c'est un malade, mais en plus de ça des tonnes de threads pourront être lancés en même temps. Ça peut poser beaucoup de problèmes, donc il faut faire en sorte de ne pas avoir plus d'un thread "esclave" en même temps : soit en mettant en file d'attente les éventuels threads en trop, soit en bloquant les commandes de jeu qui posent problème (faire qu'aucun message ne soit envoyé). La seconde solution me semble bien mieux, mais il va encore falloir un peu réfléchir.

    En tous cas, ça fait un poil chier :p

    Contenu sponsorisé


    Proposition pour la conception du schmilblick Empty Re: Proposition pour la conception du schmilblick

    Message  Contenu sponsorisé


      La date/heure actuelle est Ven 17 Mai - 15:14