User Tools

Site Tools


markdowntest

**This is an old revision of the document!**

Draculab: Bataille d'algorithmes

*design doc 0.0.1*

il m'énerve

Description de la tâche

Dans un labyrinthe, un vampire assoiffé de sang poursuit un professeur d’université. Chacun parcourt le labyrinthe selon les directions fournies par un programme rédigé un langage de programmation assez simple. Le vampire dispose d’un temps limité (en nombre de pas) pour attraper le professeur. Après chaque partie, les joueurs découvrent l’heuristique de parcours de l’adversaire et disposent d’un temps limité pour ajuster leurs propres algorithmes de parcours avant de rejouer. Après 11 parties, le gagnant est celui qui a remporté le plus de parties. Le public visé est des adolescents entre 11 et 14 ans typiquement.

Le jeu se jouera via un serveur intermédiaire, chaque joueur verra le labyrinthe, la progression des avatars, et si possible, l’animation de chaque algorithme couplé à la progression des avatars. L’étudiant pourra réutiliser des librairies ou déléguer l’exécution de l’algorithme à un interpréteur en option pour un “embedded DSL” (en Groovy ou Python par exemple). Logo ou Scratch devraient être des sources d’inspiration utile.

Besoins du projet ( tels que décris dans l'énoncé )

* Cartes 2D lesquelles des personnages peuvent se déplacer * Au moins une application client pour les joueurs

  • Visualisation de la carte en cours, de l'état du jeu et éditeur de code

* Un serveur intermédiaire qui contrôle le déroulement de la partie * Un language dans lequel les joueurs peuvent écrire le comportement souhaité de leur personnage

Besoins du projet ( analysés, interprétés et complétés )

* Toujours via des cartes en 2D, formées de tuiles alignées sur une grille, avec des tuiles solides faisant office de murs

  • Cartes 2D éditables/chargeables
  • Set de cartes par défaut fournies avec le jeu
  • (Optionnel) Génération de labyrinthe en utilisant une librairie/algorithme externe

* Application client pour PC ( Clients web où Android possibles, mais pas au programme cette année ) * Logiciel serveur dédié, utilisant un protocole application spécifique documenté

  • Le serveur est donc bien le vrai maître du jeu, et le client ne fait que recevoir l'état de la partie et envoyer le code source que le joueur à écrit
  • Créer un autre client est donc hautement facilité

* (Optionnel) Option pour hébérger un serveur local à partir du client PC ( dans le cas où aucun serveur distant ne serait disponible par ex ) * Le serveur est capable d'interpréter/compiler le code source fournit par le client et de l'éxécuter

  • Quel que soit le language final utilisé, les mêmes commandes sont mises à disposition, voir [Commandes du personnage]
  • Pseudolanguage spécifique basé sur un sous-set de Groovy ( pour rester dans l'écosystème Java )
  • Possibilité de supporter plusieurs languages additionnels ( Java, JS, PHP, C, Lua, … ) et donc de laisser le choix au joueur, selon ses aises

* Additionnel: Le serveur est capable d'hébérger plusieurs parties à la fois, et propose aux joueurs à leur connection un salon textuel où ils peuvent discuter, voir qui est en train de joueur et se défier à jouer une partie.

  • Additionnel: Rendre les rôles des personnages ( Dracula, Doctor ) configurable et envisager des parties avec plus de 2 joueurs, et pourquoi pas plus d'élements de jeu
  • Additionnel: Proposer un mode de jeu “tutoriel” hors-ligne où les nouveaux joueurs sont mits face à des algorithmes pré-définis de difficulté croissante et apprennent à manipuler l'interface du jeu

Lexique

* Partie := L'entiereté d'une rencontre entre deux joueurs, formés de 11 manches par défaut * Manche ( où Round ) := Période pendant laquelle après validation de leurs algorithmes respectifs, les deux personnages sont laissés à eux-mêmes jusqu'a un nombre maximal de tours où la victoire de Dracula * Tour := Instant pendant lequel un des deux personnages peut se déplacer d'une case, avant de laisser l'autre se déplacer au tour suivant.

Déroulement d'une partie type

1. Le joueur lance son client, et se connecte ( où crée ) à un serveur distant. 2. Il patiente jusqu'a rencontrer un joueur prêt à accepter de le combattre, et l'invite à joueur une partie. 3. Une salle d'attente est crée, le(s) autres joueurs la rejoignent et le joueur ayant crée la salle d'attente décide de lancer la partie 4. Les joueurs sont alors déconnectés de la salle de chat, et déplacés dans un salon privé à leur partie 5. Selon les paramètres de la partie, le serveur envoie les informations ( layout de la carte, position des personnages, … ) à chacun des clients 6. Début d'une manche: Les deux joueurs écrivent leur algorithme et appuyent sur “prêt” 7. Le serveur éxecute les deux algos en déplaçant un personnage d'une case à chaque tour, jusqu'a au choix la fin du timer où la mort du pourchassé

  • Fin du timer: Dracula perd ( et tombe en poussière avec le jour levant )
  • Mort du pourchassé: Dracula arrive sur la même case que sa victime, et la tue. Dracula gagne.

8. Le gagnant de la manche gagne un point, et on revient au point 6 jusqu'a ce que 11 manches aient eu lieu 9. Le serveur déclare le vainqueur et après un certain délai, détruit le salon privé de la partie, libère ses ressources et renvoie les joueurs dans le lobby

Commandes du personnage

À chaque tour, le personnage dont c'est le tour, reprend l’exécution de l'algorithme là où elle c'était arrêtée. Cette exécution continue jusqu’à ce que le code du joueur appelle une des commandes de personnage ci-dessous, auquel point l’exécution sera mise en pause et celle du joueur suivant reprendra, où la nombre maximal de tours sera atteint.

  • Aller une case à gauche
  • Aller une case à droite
  • Aller une case en haut
  • Aller une case en bas
  • Ne rien faire ce tour

Additionnellement, il est fournit au joueur des méthodes pour obtenir des informations sur l'état de la partie:

  • getSelfPosition : ivec2 Obtenir sa propre position * getDraculaPosition ( X et Y ) : ivec2 Obtenir la position de Dracula
  • isWall(x, y) : boolean Est-ce que cette case est un mur ? * roundsRemaining : int Combien de tours me reste-il ?

À propos d'un DSL

Une autre idée serait d'utiliser des caractères UTF-8 pour représenter plus visuellement le pseudolanguage, comme dans le language de programmation emoji: et si on représentait bougerGauche() par un simple caractère ⬅️ ? ). Cette substitution serait optionnelle et désactivable, et éviterai aux joueurs novices de perdre du temps sur de simples fautes d'orthographe où de syntaxe, tout en laissant aux joueurs plus expérimentés le choix d'une syntaxe plus formelle.

Possibilités !

Le fait que le tour se termine dès qu'une commande de mouvement est envoyée laisse aux joueurs la liberté de se concentrer sur leur algorithme sans avoir à comprendre d'obscures notions de programmation concurrentielle, qui n'entrent de toute façon pas dans le scope de ce que le jeu essaie de faire.

Les joueurs peuvent se contenter de donner une longue suite de directions ( ex: ⬅️ ⬅️ ⬅️ ⬇️ ⬆️) et donc de “hardcoder” les mouvements de leur personnage de manière très intuitive, mais peuvent également parsemer leurs instructions de structures conditionnelles. On passe ainsi d'une simple suite d'ordres à de la vraie programmation de manière totalement naturelle, et qui finalement colle assez bien à ce qu'un ordinateur est: une machine qui éxecute des ordres.

if isWall ( selfPosition.add(⬆️) ) // Si la case du dessus est un mur
	then ⬇️ 
	else ⬆️

De la même manière, on peut aussi introduire les structures conditionnelles, des variables et enfin des fonctions.

Réalisation technique

Outils (code)

* Langage de prédilection: Java * Serveur: Application Java stand-alone en CLI * Client PC: Application Java stand-alone graphique * Librairie graphique (client PC): LWJGL3 ( Wrapper pour des APIs C incontournables: OpenGL, OpenAL, … ) * Version control: Git ( what else ), sur repository privé * Build system: Gradle <3 ( Alternative à Maven, également basée sur Groovy ) * Réseau: Plain old TCP/IP sockets, où peut-être un framework plus haut niveau comme Netty ? * Logging: log4j * DSL: Groovy-based ( à discuter encore, cf support de plusieurs lang. de prog )

Outils (debug)

* JUnit ( pour ce qui s'y prête, hélas peu adapté à tester un client complet ) * Beta-testeurs en chair et en os ( pour ce que JUnit ne sait pas faire ) * Wireshark * VisualVM ( debugger Java ) * RenderDoc ( debugger OpenGL/DirectX/Vulkan )

Outils (assets, etc)

* Paint.NET ( Programmer art ) * Audacity

Roadmap

1. Analyse

  • Finaliser le plan, clarifier les points flous
  • Réaliser un mockup très basique de l'interface client

2. Création de la structure du projet

  • Repo Git
  • Fichier de configuration build.gradle créer les sous-projets, ajouter les dépendances
  • Créer les grandes interfaces utilisées par le projet (ie: les commandes du joueur)

3. Début de la programmation (code code code)

  • 3.1. Programmation: Fondamentaux
    • Implémenter le système de cartes et de personnages
    • Écrire l'interface pour contrôler le personnage ( [Commandes du personnage]
    • Écrire un début de moteur de rendu pour afficher la carte et les personnages de manière sommaire
  • 3.2. Programmation: Aspects “réseau”
    • Implémenter un client et un serveur et commencer à organiser un protocole spécifique
      • Probablement un protocole basé sur du texte seulement, par simplicité
      • UTF-8 everywhere
    • Implémenter le lobby général, les salles d'attente et les salons de jeu privés
    • Aucune vraie logique sur le serveur, une coquille vide qui est finalement juste une salle de discussion compartimentée
  • 3.3. Programmation: Aspects “serveur”
    • Écrire le matériel nécessaire pour interpréter du code reçu et mettre en pause son exécution quand la simulation le requiert.
    • Abstraire le langage de programmation utilisé et autoriser le rajout d'autres interpréteurs pour le support d'autres langages, par un méchanisme de plugin par ex

4. Intégration initiale du tout, test fonctionnel interne 5. Boucle:

  • Test externe ( bêta-testeurs: membres de la fac, amis, famille )
  • Ajout de nouvelle fonctionnalités / améliorations fonctionnalités existantes
  • Version stable et agréable à jouer ? → tag git pour la garder sous la main
  • Itérer ainsi jusqu'a la deadline selon le temps disponible pour avoir le meilleur projet possible tout en gardant des versions moins avancées mais fonctionelles sous la main

6. Écriture d'une doc plus complète que ce document et la Javadoc

  • 6.1. Manuel utilisateur: Le tutoriel peut-il en faire office ?
  • 6.2. Manuel développeur: Un dokuwiki ?
    • Quick start guide: Forker et compiler le projet
    • Description de l'architecture du projet ( sous-projets, dépendances entre eux etc )
    • Description détaillée du protocole réseau
    • Description détaillée du format des cartes
    • Description du fonctionnement du système de plugin pour ajouter le support d'un nouveau language
markdowntest.1510315955.txt.gz · Last modified: 2017/11/10 13:12 by gobrosse