Tatons

Un

Tantinet

Originalement la

Relative

Intelligence

Artificielle

Logicielle

Programmation avec le basic intégré à OpenOffice.Org d'un petit jeu de type 'MasterMind'™

ASPECT LEGAUX DE CETTE DOCUMENTATION

Crédits

Auteur: Cécile & Claude RELAIX

Remerciements à : Les utilisateurs de la liste users d'OpenOffice.org et en particulier B. MARCELLY pour nous avoir orienté sur la bonne doc :-)

Dernières modifications : 9. octobre 2003

Contacts:

Translation: N/A

Licence

Ce document est publié sous les termes et les conditions de la licence GNU GPL

© 2003 Cécile & Claude RELAIX

Préambule :

Ce document est plus un retour d'expérience qu'un véritable tutoriel.

En matière de programmation, il m'a souvent semblé intéressant d'étudier un nouveau domaine par la création d'un petit jeu.

Dans un élan de créativité concertée, nous avions développé avec mon épouse il y a quelques années,un petit jeu de type 'mastermind' pour le tableur excel.

Linux puis OpenOffice.org ayant depuis longtemps remplacés les alternatives concurrentes sur nos ordinateurs, une mise à niveau de ce type de projet s'imposait.

Après pas mal de déboires dans mes tentatives de portages :-(, un message de Bernard Marcelly sur la liste 'users' d'OpenOffice.Org me permis de récupérer enfin une remarquable documentation sur le Basic d'OOO. Elle se trouve ici :

http://docs.sun.com/db/doc/817-1826-10

Que Bernard en soit remercié :-)

Objet de ce document :

Montrer qu'il est aussi possible de réaliser de la programmation non triviale avec le Basic d'OOO, même si cet exemple est d'une complexité modeste.

Montrer que le portage de macros utilisant des dialogues est possible entre les produits Microsoft™ et OOO. Mais attention, l'exemple utilisé a été réalisé avec une version assez ancienne de leur tableur (Excel™ 97). Je ne suis pas en mesure de vérifier avec des versions plus récentes.

Montrer, si cela est nécessaire, que les adaptations sont peut nombreuses et concernent plus la manipulation des objets du dialogue que le langage lui même.

Les impatients peuvent lancer le jeu tout de suite en cliquant sur le bouton ci-dessous. Ceux qui veulent en savoir plus passent à la page suivante...

Objet du programme

Ce programme doit répondre à un problème assez complexe : réaliser une stratégie de réflexion pour que l'ordinateur puisse 'jouer' seul et deviner la solution.

Pour cette version, la solution est créée au lancement par le programme lui-même de manière aléatoire. Une version ultérieure devrait permettre au joueur humain de sélectionner l'énigme.

Toute la difficulté consiste à trouver un raisonnement permettant à l'ordinateur « d'approcher » la solution. Pour cela il faut analyser les réponses du joueur qui va lui signaler, pour chaque proposition, le nombre de couleurs bien placées et le nombre de couleurs mal placées.

Mode d'emploi du programme

L'utilisateur commence une partie en appuyant sur le bouton « Commencer » (j'ai ouï dire que « démarrer » était déjà pris...).

L'ordinateur génère alors une solution aléatoire qui s'affiche dans la rangée de cases du haut ainsi qu'une première proposition de solution qui s'affiche dans la rangée du bas.

L'utilisateur entre alors dans les zones de saisies « Couleurs bien placées » et « Couleurs présentes » les informations correspondantes.

Le raisonnement de l'ordinateur se base sur ces réponses. Si elles sont fausses, gare ! Le programme risque de perdre le fil de son « raisonnement ».

La partie s'arrête lorsque l'ordinateur a trouvé, mais il faut le lui signaler en mettant 6 dans la zone « Couleurs bien placées », ou lorsqu'il n'a pas trouvé en 20 coups (ce qui arrive parfois car sa profondeur de recherche est limitée à 2000 cf algorithme).

La partie peut aussi être interrompue à tout moment par un click sur le bouton « Quitter la partie » .

La programmation

Ce document n'a pas pour objectif une présentation de l'interface de programmation d'OOO.

De nombreux exemples, beaucoup mieux rédigés, sont disponibles sur le site d'OOO .

Deux points seront donc abordés :

Les différences constatées entre le programme version OOO et version VBA™

la description de l'algorithme utilisé (pour ceux que ça intéresse).

Les différences constatées

Je m'attendais à de grosses difficultés, en fait le nombre de différences se monte à la somme « astronomique » de trois. Oui, 3, vous avez bien lu !

Première différence : le codage des couleurs.

Pour coder du bleu en VBA™ ( de l'époque), la valeur était 16711680 soit FF0000 en héxadécimal. Pour OOO, la valeur est 0000FF. Pour le rouge, c'est l'inverse.

La codification OOO me semble plus logique puisqu'elle respecte le codage RVB.

C'est anecdotique.

Deuxième différence : La gestion des bornes dans une boucle « for-next ».

Le VBA™ de l'époque permettait de modifier la valeur d'une borne de boucle à l'intérieure de la boucle. Cela servait à sortir prématurément.

Ca ne marche pas avec OOO. Mais l'instruction « exit for » gère ça d'une manière beaucoup plus élégante. Elle existe aussi dans VBA™.

Une bonne habitude à prendre.

Troisième différence : La gestion des contrôles placés sur le dialogue.

En simplifiant outrageusement, je dirais qu'à l'appel du dialogue, VBA™ créé automatiquement une instance de chaque objet y figurant . Ils deviennent donc manipulables par des « variables » portant leur nom.

Dans OOO il faut « s'adresser » à chaque objet par une méthode, le lancement du dialogue ne créant pas automatiquement ce type de variables (ou alors je n'ai pas trouvé comment).

Mais, en y réfléchissant un peu, il suffit d'appeler UNE fois cette méthode pour CHAQUE objet en début de programme pour que les instances soient créées. Ensuite, la syntaxe est la même que dans VBA™.

Si les variables liées aux contrôles sont définies en dehors de toute fonction, elles seront donc globales et utilisables dans toutes les sous fonctions du module.

J'y vois même un avantage, la variable liée à l'objet ne porte donc pas obligatoirement le même nom que l'objet.

En trouvant un événement qui se déclenche lors de l'activation du dialogue, puis en lui assignant une fonction d'instanciation des contrôles, le portage serait encore simplifié. Pour le moment, je cherche :-)

Par contre, il me semble que le compilateur « pleure » si une référence à une des instances figure dans le source AVANT son initialisation.

En résumé :

déclarez en début de programme les variables que vous utiliserez pour accéder aux contrôles.

Créez une fonction qui va initialiser ces variables dès le début de votre source.

Finalement, on se retrouve très vite en « pays connu ».

L'algorithme utilisé.

Fruit de l'intense réflexion de mon épouse :-) il se base sur le principe suivant :

Proposer à chaque recherche une solution originale.

Avant de proposer cette solution, s'assurer qu'elle correspond aussi aux réponses précédentes de l'utilisateur. Ainsi, même si la proposition n'est pas LA solution elle est une solution possible du problème.

Dans le détail.

Le programme utilise une matrice [a(i,j)] à deux dimensions. I et j varient de 1 à 6, i désigne la position et j la couleur ( 1 bleu 2 blanc 3 vert 4 noir 5 cyan 6 rouge 7 gris) à cette position.

Un élément de la matrice vaut :

1 si on ne sait pas si la couleur est exacte ou non

0 si la couleur est fausse à cette position

2 si la couleur est certaine à cette position

Ainsi a(1,4)=0 -> la première case n'est pas noire

a(5,2)=2 -> la 5ème case est blanche

a(3,3)=1 -> on ne sait pas si la case 3 est orange ou non.

Analyse des réponses :

Si l'utilisateur n'indique aucune couleur bien placée, tous les a(couleur proposée,position i) sont mis à 0.

Si l'utilisateur indique qu'aucune couleur est présente (bien ou mal placée), c'est que les couleurs proposées ne font pas partie de la solution. Tous les a(couleur, toutes positions) sont mis à 0.

Si la somme du nombre de couleurs bien et mal placées est 6, alors la bonne solution est une permutation, dans ce cas les couleurs absentes de la proposition sont fausses et pour chaque couleur absente a(n'importe quelle position, couleur)=0.

Si pour une colonne j0 (position) donnée, la somme des a(i,j0) vaut 1, c'est que toutes les couleurs sont impossibles à cette position sauf une qui est « indécise ». Donc elle devient certaine et en multipliant tous les a(i,j0) par 2 le seul non nul passe à 2 (certain).

Si dans une colonne j (position), un a(i,j) vaut 2, l'ordinateur proposera systématiquement la couleur correspondante.

Dans une colonne où il n'y a pas de certitude, l'ordinateur ne proposera plus les couleurs i dont les a(i,j) sont nuls.

Les propositions sont élaborées à l'aide d'une autre matrice l(a,b) avec a variant de 1 à 21 (maximum de proposition) et b variant de 1 à 8. De 1 à 6 ce sont les positions, 7 le nombre de bonnes couleurs et 8 le nombre de couleurs mal placées.

Pour b de 1 à 6, un l(a,b) quelconque vaut :

0 si on ne sait rien de spécial pour cette position b « à venir ».

le code de la couleur proposée si cette proposition à déjà été jouée.

Le code d'une couleur dont on est sur pour les coups à venir.

Exemples dans le cas d'une recherche sur la 4ème ligne :

l(3,5)=2 : la ligne précédente, l'ordinateur avait proposé blanc en 5ème position

l(2,7)=1 : il y a eu une couleur bien placée au deuxième coup

l(4,1)=l(5,1)=.......l(20,1)=3 en première position le vert est certain.

Méthode pour valider une proposition :

Si à la ligne suivante (d'où l'utilité de la 21ème ligne) on a l(ligne,position) différent de 0, c'est que l'on connait la couleur exacte pour cette position. Elle est donc proposée.

Dans le cas contraire on tire aléatoirement une couleur possible (dont le a(i,j) n'est pas nul).

Quand une couleur est choisie pour chaque position on obtient une solution virtuelle.

Ensuite, on va comparer cette solution virtuelle avec chaque ligne précédente pour vérifier que les nombres de couleurs bien placées et mal placées sont en cohérence avec les réponses de l'utilisateur.

Si cette proposition est originale (non encore proposée) et cohérente le programme l'affiche.

Sinon, il recommence à chercher. Les limites du programme sont donc là.

dans la profondeur de la recherche, 2000 actuellement (je dois avouer que c'était 5000 sous VBA™ qui est plus rapide).

Dans la confiance envers les réponses de l'utilisateur.

Si l'ordinateur va jusqu'au bout il propose la dernière proposition étudiée. Le programme doit pouvoir être amélioré à ce niveau.

CONCLUSION

En général, le programme trouve en moins de 10 coups, sinon il ne trouve pas. Les échecs sont en général dus à un « mauvais » démarrage ou (cas fréquent) à une erreur de l'utilisateur. Vous êtes le maillon faible, etc... donc faites très attention à vos réponses. Une confusion fréquente est de compter deux fois une couleur, une fois en bien placée et une fois en mal placée mais présente quand elle figure une fois dans la solution et deux fois (dont une bien) dans la proposition.

Etudiez par exemple les exemples ci-dessous pour plus de précisions :-)

Pour des informations plus « techniques » je vous encourage à étudier le code.

Il est accessible par le menu Outils/Macros/Macro...

Je vous encourage aussi à prendre des programmes issus de VBA et à essayer de les porter. Comme c'est actuellement un des plus gros point de blocage pour le passage à OOO plus il y aura d'exemples de réussites plus OOO se diffusera (cqfd et Lapallissade en même temps).

Bon courage...

Il ne suffit hélas pas toujours, de cliquer sur deux trois boutons pour faire un programme :-))

Claude RELAIX

2002-09-19T08:39:42