Vous êtes sur la page 1sur 11

RAPPORT DU PROJET

D’INTELLIGENCE ARTIFICIELLE

23 MAI 2023
ELIOTT GRANDGERARD
Table des matières
I. Introduction ...................................................................................................................3
II. Déterminer la question ...................................................................................................5
III. Sélection des possibilités restantes.............................................................................7
IV. Mise en place de la solution ...........................................................................................8
V. Vérifications et pistes de développement .......................................................................9
VI. Conclusion ................................................................................................................10
I. Introduction
L’objectif de ce projet est de créer un jeu de devinette dans lequel le joueur
pense à un objet et le programme en posant des questions fermées doit être
capable de trouver quel est l’objet. Pour le projet, le joueur doit penser à un
objet qui appartient à une liste donnée d’environ 100 individus. Dans un
premier temps, je dois choisir sur quoi portera mon jeu. Pour mon projet, j’ai
décidé de travailler sur un jeu de devinette sur les Pokémon de la deuxième
génération. Cette catégorie m’a semblé intéressante puisque dans cette
génération, il y a un peu plus de 100 Pokémon et ils ne se distinguent pas des
caractéristiques plutôt évidentes ce qui me permet de facilement trouver des
questions. En effet, chaque Pokémon possède 1 ou 2 types, peut ne pas avoir
évolué, être légendaire, voler, avoir évolué deux fois… J’ai donc écrit une
vingtaine de questions que permettent de distinguer au mieux les Pokémon les
uns des autres. Pour commencer à écrire mon programme, j’ai tout d’abord
décidé de créer une version alternative de mon jeu où il y avait seulement les
starters et leurs évolutions, il y avait donc 9 Pokémon possibles. La première
étape fut de créer un tableau Excel où chaque ligne représente les
caractéristiques d'une Pokémon et chaque colonne une question. Pour mon
système de réponse aux questions, j’ai repris celui qui était conseillé dans
l’énoncé du projet : une réponse positive à une question est indiquée par un 1
et une réponse négative par un 0. J’ai rempli chaque ligne en fonction des
réponses aux questions de chaque colonne. Voici ce que j’obtiens :

Ensuite, j’ai pu commencer à écrire le programme. Tout d’abord, j’ai décidé


d’utiliser la bibliothèque pandas afin de traiter les données de mon tableur
Excel. J’ai utilisé ''import'' pour obtenir pandas, j’ai ouvert le tableur sous le
nom ‘’data_pokemon’’, et je l’ai affiché pour m’assurer qu’il s’ouvrait bien
comme je le voulais.
Selon moi, cet algorithme devait se diviser en 3 fonctions. La première, qui
permet de déterminer quelle doit être la question posée. La seconde qui pose
la question et enregistre la réponse du joueur. Et la troisième qui élimine les
possibilités qui ne correspondent pas à la réponse du joueur. Ces opérations
doivent se répéter jusqu’à ce qu’il n’y en ait plus qu’une seule.
II. Déterminer la question
Le programme dispose de questions prédéfinies en rapport avec les objets
choisis et doit être capable, en éliminant à chaque question une partie des
individus de déterminer quel est l’objet auquel le joueur pense. Une des
difficultés est donc de choisir une question clivante, qui sépare l’échantillon le
plus équitablement possible. Par exemple, s’il reste 10 objets possibles, le
programme doit essayer de poser une question qui aura une réponse positive
pour 5 individus et une négative pour les 5 autres. Pour mon projet, j’ai choisi
de travailler sur un jeu de devinette sur les Pokémon de la deuxième génération
et j’avais déjà écrit des questions. Il me fallait donc créer une fonction
‘’question_a_poser(data_pokemon)’’ qui soit capable de déterminer laquelle
des questions est la plus clivante. Pour cela, il faut dans un premier temps,
trouver quel serait les caractéristiques de la meilleure question, c’est-à-dire son
nombre de réponses positives et son nombre de réponses négatives pour
chaque Pokémon. C’est assez simple, il suffit que la moitié des réponses soit
positive et donc que l’autre moitié soit négative. On prend donc le nombre de
Pokémon possible et on le divise par 2. Dans notre situation de départ où il n’y
a que 9 possibilités la question idéale auraient 4,5 réponses ‘’oui’’ et 4,5
réponses ‘’non’’. Il suffit donc de regarder pour chaque question, quel est le
nombre de réponses positives et de prendre celle qui est la plus proche du
nombre de réponses positives de la question idéale. En pratique, on doit
additionner les réponses de chaque colonne, calculer les valeurs absolues de la
différence entre le nombre de réponses positives de la question idéale et le
nombre de réponses positives de chaque colonne, sélectionner la valeur
absolue la plus petite et garder en mémoire l’indice de la colonne associée à la
valeur absolue la plus petite. Par exemple dans notre cas avec 9 Pokémon, la
fonction ‘’question_a_poser(data_pokemon)’’ va trouver 3 pour la somme de la
première colonne de question. Ensuite, la fonction va calculer la valeur absolue
de 4,5 - 3 = 1,5 et comme elle ne va trouver de résultat inférieur pour les autres
colonnes elle va garder en mémoire l’indice de la première colonne de
question. Dans notre exemple, la fonction permet donc au programme de dire
que l’indice de la question qui doit être posée en priorité est 1. Donc, dans mon
programme, la question prioritaire à poser est déterminée par la fonction
‘’question_a_poser(data_pokemon)’’.

Après avoir déterminé la question qui doit être posée, le programme doit être
capable de la poser, pour cela, j’ai créé une fonction ‘’question’’. Elle prend en
argument l’indice de la colonne qui correspond à la question la plus clivante et
au tableur Excel dans lequel se trouve toutes les questions qui peuvent être
posées. La fonction pose la question et stocke la réponse du joueur dans une
variable ‘’ reponse_question’’. Dans notre exemple, elle va prendre dans
‘’questions_pokemon’’ la question qui correspond à l’indice 1. La fonction va
donc poser la question ‘’ Est-ce que ton Pokémon est de type plante ?’’ et
enregistrer la réponse du joueur.
III. Sélection des possibilités restantes

Après avoir reçu la réponse du joueur, le programme doit être capable de créer
un nouveau tableau ‘’data_pokemon’’ où seuls les Pokémon qui correspondent
à la réponse du joueur sont gardés. De plus, il faut s’assurer qu’une même
question ne puisse pas être posée plusieurs fois. Pour faire tout cela, j’ai créé
une dernière fonction appelée ‘’nouveau_tableau‘’ qui prend en argument le
data frame ‘’data_pokemon’’, l’indice de la colonne de la question posée et
enfin la réponse donnée par le joueur. Si la réponse du joueur est positive alors
le programme ne va garder que les lignes de ‘’data_pokemon’’ où on trouve un
1 dans la colonne de la question posée. À l’inverse, si le joueur a répondu non,
seul les lignes où un 0 figure dans la colonne seront conservés. Mais la fonction
‘’nouveau_tableau‘’ a aussi pour mission de s’assurer qu’une même question
ne puisse pas être posée deux fois. Pour cela, toutes les réponses de la question
à laquelle on vient de s’intéresser vont être remplacées par des 0, ainsi la
fonction ‘’question_a_poser’’ ne choisira jamais la même colonne deux fois.
IV. Mise en place de la solution
Après avoir créé ces trois fonctions, il suffit de les mettre dans un boucle
‘’while’’ qui va répéter les fonctions jusqu’à ce que le tableau ‘’data_pokemon’’
ne fasse plus qu’une seule ligne, celle du Pokémon choisi par le joueur. Pour
cela, on commence par indiquer au joueur que nous allons tenter de deviner le
Pokémon auquel il pense. Puis, on détermine une première fois l’indice de la
question qui doit être posée grâce à la fonction ‘’question_a_poser’’. Ensuite,
on entre dans la boucle qui continue tant que le data frame ‘’data_pokemon’’
fait plus d’une ligne. On commence par poser la question la plus pertinente ; à
la première itération, la question sera toujours la même puisque les paramètres
à chaque nouvelle partie sont identiques. Ensuite, on vérifie que la réponse
donnée par le joueur soit bien ‘’oui’’ ou ’’non’’, si ce n’est pas le cas on indique
au joueur que sa réponse est incorrecte et on sort de la boucle ‘’while’’. Si la
réponse est correcte, on utilise la fonction ‘’ nouveau_tableau’’ pour ne garder
que les Pokémon qui correspondent à la réponse du joueur. Puis, on calcule de
nouveau l’indice de la question optimale. À chaque itération une partie des
possibilités seront enlevés du tableau jusqu’à ce que le tableau ait moins de
deux lignes. Là, on s’assure que ‘’data_pokemon’’ ait une unique ligne, si c’est
le cas, on indique le nom du Pokémon qui apparaît dans la première colonne de
la ligne. Sinon on indique un message d’erreur pour signifier au joueur
qu’aucun Pokémon ne correspond à sa description.
V. Vérifications et pistes de développement
Après avoir réussi à faire marche le programme pour mes 9 premiers Pokémon,
j’ai décidé de rajouter tous les autres afin de voir s’il marcherait toujours. De
prime abord, il n’y avait aucun problème, l’algorithme était toujours capable de
trouver quel était le Pokémon auquel je pensais. Mais lorsque je lui ai demandé
de trouver le Pokémon ‘’Fouinette'', il n’a pas été capable de me donner une
réponse. Au début, je ne comprenais pas d’où venait le problème, j’ai donc
rajouté un ‘’print(data_pokemon)’’ dans ma boucle ‘’while’’ pour voir comment
évoluait mon tableau de possibilité après chaque réponse. Je me suis donc
rendu compte qu’à partir d’un moment mon programme ne pouvait plus me
poser de questions sur les Pokémon qu’ils restaient puisqu’ils avaient
exactement les mêmes caractéristiques. J’ai donc fait le choix de rajouter des
questions qui permettent de les différencier entre eux, tel que ‘’Est-ce que ton
Pokémon est une fouine ?’’. Une autre possibilité, plus efficace à long terme,
aurait été de rajouter une fonction qui si le programme n’est pas capable de
faire la différence entre les Pokémon peut demander au joueur quel était son
Pokémon parmi la liste de Pokémon possible et de trouver une question qui
puisse le différencier des autres Pokémon et la rajouter à
‘’questions_pokemon’’. Il faudrait par la suite rajouter une colonne à
‘’data_pokemon’’ en lui demandant pour chaque Pokémon quel est la réponse
à sa question.

Pour vérifier s’il n’y avait pas le même type de problème avec d’autres
Pokémon, j’ai décidé de manuellement en tester une grande quantité. Je n’ai
pas trouvé d’autre problème, mais une autre solution aurait été de créer un
autre programme qui tire au hasard un Pokémon dans la liste répond aux
questions grâce à ‘’data_pokemon’’ et puisse ainsi dire quel est la précision de
mon jeu.

Ensuite, j’ai essayé d’améliorer mon programme pour qu’il puisse actualiser
‘’data_pokemon’’ si le joueur lui donnait un Pokémon qu’il n’était pas capable
de trouver. Pour cela après la boucle ‘’while’’ il aurait fallu rajouter une fonction
qui demande le nom du Pokémon du joueur, qui vérifie s’il ne fait pas partie des
noms déjà existants et qui lui demande de répondre à toutes les questions de
‘’questions_pokemon’’ et enfin crée une nouvelle ligne dans ‘’data_pokemon’’.
Seulement, mon jeu se concentre sur les Pokémon de la deuxième génération,
si j’avais permis l’accès à de nouveaux Pokémons, il aurait aussi fallu que je crée
la fonction qui permet à l’utilisateur de créer de nouvelles questions. Or, je n’ai
pas eu le temps de faire tout cela.
VI. Conclusion
En définitive, je pense que mon algorithme répond à la problématique de
départ. Si le joueur choisit un des Pokémon de la seconde génération et qu’il
répond correctement aux questions mon algorithme sera tout à fait capable de
le trouver. Cependant mon programme reste encore imparfait puisqu’il n’y a
pas de possibilité d’actualiser la base de données afin d’être capable d’ajouter
de nouveaux Pokémon. Il n’est pas non plus possible pour le joueur d’ajouter
de nouvelles questions afin d’améliorer l’efficacité du programme et de palier le
problème de ressemblance entre les Pokémon.

Vous aimerez peut-être aussi