Programmation fonctionnelle, projet 2014

Dates et principe

Cette page peut être mise à jour, avec informations complémentaires, précisions, questions bonus, etc. Pensez à y revenir souvent.

Projet à rendre pour le vendredi 16/01 à 23h59, aucun retard ne sera toléré.
Des soutenances pourront être organisées ensuite.

Lire tout le sujet (tout ? tout).

Un rendu de projet comprend : Avez-vous lu tout le sujet ?

Protocole de dépôt

Vous devez rendre

rassemblés dans une archive tar gzippée identifiée comme votre_prénom_votre_nom.tgz.
La commande devrait ressembler à :
tar cvfz randolph_carter.tgz rapport.pdf fichiers.ml autres_truc_éventuels
Lisez le man ! et testez le contenu de votre archive (une commande comme par exemple :
tar tvf randolph_carter.tgz doit lister les fichiers et donner leur taille). Une archive qui ne contient pas les fichiers demandés ne sera pas excusable. Une archive qui n'est pas au bon format ne sera pas considérée.

Procédure de dépôt
Vous devez enregistrer votre archive tar dans le dépôt dédié au cours IPF (ipf-2014) en vous connectant à http://exam.ensiie.fr. Ce dépôt sera ouvert jusqu'au 16 janvier inclus.


Contexte

Le but de ce projet est d'uiliser des techniques de programmation génétique pour obtenir un programme qui joue à Pierre-Papier-Ciseaux, qui plus est qui joue bien contre un humain. En effet un humain a bien du mal à jouer au hasard et il est possible d'anticiper ses choix avec de bonnes chances de succès. On devra donc produire :

  1. Une plateforme qui fait s'affronter deux joueurs/programmes,
  2. Des fonctions de croisement et de sélection de programmes.
Lire le sujet en entier est une bonne idée.

Vous devez au moins réaliser la première époque.

Pierre-Papier-Ciseaux (PPC)

Deux joueurs s'affrontent à PPC.

Une partie de PPC se déroule en une ou plusieurs manches.

Une manche consiste en un choix simultané par les joueurs d'un objet parmi :

Le gain d'une manche est obtenu par le joueur qui a choisi :

toutes les autres possibilités donnent lieu à une manche nulle.

Un score peut être obtenu pour un programme en comptant un point pour une victoire, 0 pour une manche nulle et -1 pour une défaite.

Un programme pour PPC

On peut représenter un programme jouant à PPC comme associant à une séquence de manches le prochain choix. Par exemple, on peut décrire que si, au cours de la partie, les deux dernières manches sont Pierre Pierre (manche nulle) et Pierre Ciseaux (gain pour le joueur) alors le prochain sera Papier, ce qu'on écrira dans cet énoncé : Pierre,Pierre Pierre,Ciseaux → Papier
Une règle avec la séquence vide à gauche représente le coup par défaut, toujours présent.

Un ensemble non vide de telles règles constituera un programme ; notez que les longueurs des séquences à gauche de la flèche ne sont pas nécessairement égales dans un même programme.

N.B. Si plusieurs règles peuvent s'appliquer on convient de prendre au hasard une de celles dont la séquence est maximale.

Un chouia de génétique

Une population est un ensemble de programmes.

On peut générer un nouveau programme par mutation d'un programme ou par croisement de deux programmes.

On peut enfin sélectionner des programmes pouvant participer à une prochaine génération.

On obtient les générations successives de programmes en alternant mutations, croisements et sélection.

Mimer des humains

Pour obtenir un programme imitant la stratégie d'un humain, on fait jouer un humain contre un des programme et on enregistre les coups joués durant la partie.

De cette séquence on obtient un certain nombre de règles comportant à gauche les sous-séquences d'une longueur n donnée et à droite le choix suivant cette sous-séquence dans la partie. On complète par les n règles données par les sous-séquences initiales de longueur inférieure à n.

Exemple.De la séquence Pierre,Pierre Ciseaux,Pierre Ciseaux,Ciseaux Papier,Papier où le choix humain est à gauche, on peut extraire le programme constitué des deux règles de longueur 2 : complétées par Remarquez que dans cette séquence, la dernière manche Papier,Papier doit être la première accessible, la représentation concrète pourrait être (mais est-ce vraiment la meilleure façon ?) :
(Papier,Papier) :: (Ciseaux,Ciseaux) :: (Ciseaux,Pierre) :: (Pierre,Pierre) :: [ ]

Le programme est alors ajouté à la population. Plus il y a de tels programmes, plus c'est intéressant au niveau de la sélection d'individus efficaces contre des humains. On récoltera de nouvelles informations en faisant jouer des humains contre cette nouvelle population, etc.

Première époque

On pourra utiliser les fonctions Random.int, Random.float de la bibliothèque standard d'OCaml.
  1. Proposer une structure d'association pertinente pour représenter un programme.
  2. Proposer une fonction joue qui sur la donnée d'un programme, d'un bool et d'une séquence de manches (dont la dernière jouée est la première accessible) retourne le choix de ce programme pour la prochaine manche.
    La valeur true en paramètre indique que le programme fournit le coup de gauche, la valeur false indique que le programme fournit le coup de droite dans chaque manche de la séquence.
  3. On appelle joueur une fonction de type : bool → manche list → objet.
    Un joueur peut être humain ou obtenu à partir d'un programme.
    Proposer une fonction qui sur la donnée de deux joueurs J1 et J2 munis de scores et d'un nombre n de manches maximal retourne les nouveaux scores respectifs après une partie de n manches entre J1 et J2.
  4. Proposer une fonction darwin qui sur la donnée d'un ensemble de programmes, d'un nombre n de parties, d'un nombre de manches par parties et d'un pourcentage p retourne l'ensemble des p pourcents des meilleurs programmes sur un tournoi où chacun des programmes a joué n parties contre chacun des autres.
  5. Proposer une fonction qui sur la donnée d'un programme, retourne un programme comportant les mêmes règles sauf une retirée aléatoirement.
  6. Proposer une fonction croisement qui sur la donnée d'un nombre maximal de règles et de deux programmes retourne un de leurs croisements possibles.
  7. Proposer une fonction mutation qui sur la donnée d'une proportion de modifications et d'un programme retourne une mutation possible de ce programme.
  8. Proposer une fonction extrait qui sur la donnée d'un nombre de règles maximal, d'une taille de sous-séquence et d'une séquence de manches retourne un programme (comportant au moins les règles initiales) dont les règles imitent la stratégie du joueur 1 dans ces manches. On sélectionnera aléatoirement les règles à éliminer pour respecter le nombre de maximal de règles.

Deuxième époque

On ajoute bien sûr les objets Lezard et Spock tels que :

Interface

Afin de permettre les entrées des choix d'un joueur humain nous fournissons ICI un .ml et un .mli réalisant l'interface.

Exemples de valeurs

On obtient déjà des résultats intéressants avec : Trouvez-vous de meilleures valeurs ?

Vous devez avoir lu jusqu'ici avant de commencer.
Merci à J.-C. Filliâtre pour l'idée de sujet.