Projet PASCAL Bataille navale

Transcription

Projet PASCAL Bataille navale
Projet PASCAL
Bataille navale
Christian BELIN
Guillaume ROUILLARD
8 février 2008
Table des matières
1 Architecture des modules
2 Description des modules
2.1 STD . . . . . . . . . . . . . . . .
2.1.1 Types . . . . . . . . . .
2.1.2 Procédures et fonctions
2.2 I/O . . . . . . . . . . . . . . . .
2.3 Place . . . . . . . . . . . . . .
2.4 Joueur . . . . . . . . . . . . . .
2
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3 Description du programme principal
4 Choix algorithmiques
4.1 Placement des bateaux . . . . .
4.1.1 Respect des règles . . .
4.1.2 Modification de la grille
4.2 Gestion des dégâts . . . . . . .
4.3 Tour de l’ordinateur . . . . . .
4.3.1 Mode ALEATOIRE . . . .
4.3.2 Mode DIRECTION . . . .
4.3.3 Mode VERROUILLAGE . .
4.4 Alternance des tours . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2
2
3
3
4
4
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
5
5
5
6
6
6
6
6
5 Mise au point du programme
6
6 Problèmes actuels
7
7 Améliorations - Évolution
7.1 Utilisation des constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.1 Échelle de jeu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.2 Modes de jeu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
7
7
7
1
Introduction
Le but de ce projet en PASCAL est de réaliser un jeu de bataille navale opposant un joueur humain contre l’ordinateur. Diverses conditions ont été imposées quant aux règles du jeu, à l’interface
graphique et la stratégie de l’ordinateur.
Cependant, tout le reste était laissé à l’appréciation du binôme.
Nous allons donc voir comment les modules s’articulent autour du programme principal, une
présentation succincte de chacun desdits modules, puis une explication des choix algorithmiques
réalisés, une réflexion sur la mise au point du programme, la liste des problèmes actuels non résolus,
suivie d’une ouverture présentant les améliorations qu’on pourrait apporter au programme.
On trouvera en annexe les sources du programme.
1
Architecture des modules
STD
I/O k
6M
Joueur
Place
Y
K
Bataille
– Bataille est le programme principal, il utilise donc tous les modules.
– STD est le module standard qui contient toutes les fonctions de base qui seront utilisées par tous
les autres modules.
– I/O est le module d’affichage qui s’occupe des grilles et du menu principal.
– Place est le module qui permet à l’ordinateur et au joueur humain de placer leurs bateaux sur
la grille.
– Joueur est le module qui permet de réaliser le tir de l’ordinateur ou de l’humain.
2
2.1
2.1.1
Description des modules
STD
Types
Tous les types et constantes utilisés dans le projet ont été définis dans ce module afin de permettre
un accès rapide et universel à ceux-ci.
Les types remarquables sont :
– T Coordonnees : Ceci est un outil permettant de manipuler à la fois ligne et colonne sous la
forme entrée par l’utilisateur pendant la partie (ex : ’A5’).
2
– T Direction : Ce type a été défini pour le placement des bateaux (pour les deux joueurs) et a
été réutilisé lors du bombardement par l’ordinateur.
– T Statut : Définit si un joueur est humain ou contrôlé par l’ordinateur. Nous reviendrons sur ce
point dans la partie concernant les améliorations apportées et/ou à apporter au programme.
– T Strategie : La façon (imposée) dont se comporte l’ordinateur lors de son tour nous a incité à
utiliser une ”mémoire”, c’est pourquoi la stratégie de l’ordinateur utilisera ce type lors du jeu.
– T Bateau : C’est un enregistrement permettant de repérer le bateau sur la grille, de savoir son
nom, et son état.
– T Flotte : L’ensemble des bateaux à placer sur la grille a été regroupé dans un tableau initialisé
dans ce module.
– T Case : Une case de la grille peut avoir cinq états différents, il a été décidé de les trier ainsi au
sein de ce type énuméré pour tirer parti de cette structure (comparaisons par inégalités, etc.).
– T Grille : La grille a été créée avec une bordure de cases à l’état VIDE sur le pourtour comme
vu dans le TD 2 du module ”Algorithmique et Programmation 2” (le jeu du ”Puissance 4”). De
cette manière, on résout le problème des dépassements hors zone de jeu.
– T Joueur : Une manière simple et efficace de regrouper toutes les informations concernant un
joueur était d’utiliser un enregistrement. On a ainsi accès à toutes ses données de jeu (statut,
grille de jeu, etc.) grâce à une seule variable.
2.1.2
Procédures et fonctions
– function est coord : Pour pouvoir utiliser la fonction atoi (voir ci-dessous, cf. TP 7 - Module
”Algorithmique et Programmation 1”) sans tous les contrôles programmés lors du TP, il nous
fallait réaliser nous-même ces contrôles dans le seul cadre d’une saisie utilisateur, puisque les
données manipulées par les programmes sont forcément valides.
– function atoi : C’est la fonction du TP 7 du premier module d’algorithmique, simplifiée pour
n’en garder que l’algorithme de conversion, comme expliqué ci-dessus.
– procedure ch2coord et function coord2ch : Au vu du type utilisé pour les coordonnées, il
nous fallait des fonctions de conversion pour transformer cette chaı̂ne de caractères en un couple
d’entiers (une ligne et une colonne), et vice-versa.
– function nom bateau : Le type T Bateau n’avait pas besoin de comporter le nom du bateau
car il était redondant avec la longueur de celui-ci. Cette fonction permet donc d’associer à une
longueur, un nom de bateau.
– procedure init grille : La grille est initialisée lors du début de partie, et toutes ses cases
reçoivent la valeur VIDE. On peut ensuite placer la flotte.
– function est position valable : Cette fonction permet de réaliser les saisies contrôlées de
coordonnées afin d’obtenir une position valide sur la grille.
– procedure cases bateau : On a besoin de connaı̂tre l’ensemble des cases occupées par un bateau
lorsqu’on a une case et qu’on cherche si elle appartient à un bateau ou lorsqu’on a un bateau et
qu’on cherche toutes ses cases (pour les mettre à l’état COULE par exemple).
– procedure init flotte : Le nombre et le type de bateaux sont définis dans les règles du jeu.
Cette procédure permet d’initialiser une variable de type T Flotte à la flotte de départ du joueur.
2.2
I/O - Procédures et fonctions
– procedure aff col et procedure aff lig : Ces deux procédures sont uniquement utilisées par
la procédure aff grille .
– procedure aff grille : Ceci affiche les deux grilles l’une à côté de l’autre en masquant les
bateaux non coulés ou non touchés de l’adversaire.
3
– procedure aff menu : Ce sous-programme gère l’affichage du menu et permet à l’utilisateur de
recommencer une nouvelle partie après en avoir fini une, comme préconisé dans le sujet.
2.3
Place - Procédures et fonctions
– function est placable : Le placement du bateau s’effectue en deux étapes, la première consistant à vérifier s’il ne sort pas de la zone de jeu.
– function plact valide : Avant de placer le bateau, il faut encore contrôler si le bateau respecte
les règles du jeu vis-à-vis des autres bateaux déjà placés.
– procedure placer bateau : Les deux conditions précédentes étant respectées, il faut modifier
la grille pour prendre en compte le placement.
– procedure placer humain : Grâce à cette procédure, le joueur humain peut choisir l’ordre dans
lequel il veut placer ses bateaux et saisir (de manière robuste !) leur position. Le choix du type
de saisie (origine et direction) est lié à la construction du type T Bateau et au fait que cette
manière d’opérer nous a semblé simple pour l’utilisateur, ainsi que pour le programmeur.
– procedure placer ia : Le squelette de la procédure est largement inspiré de placer humain, à
ceci près que les saisies ont été remplacées par des tirages aléatoires successifs. Comme il a été
conseillé dans le sujet, les bateaux de grande taille sont placés en premier.
2.4
Joueur - Procédures et fonctions
– function appartient bateau : Au moment où l’on a touché un bateau, on cherche à savoir
duquel il s’agit.
– procedure maj grille : Après chaque tir, on change simplement le statut de la case concernée,
en détectant également les bateaux coulés.
– function est flotte detruite : Pour détecter la fin du jeu, il fallait une fonction, à placer
dans la condition de la boucle, qui indique quand un joueur a perdu.
– procedure bombarder humain : C’est une des deux procédures principales du jeu, où l’humain
va essayer de localiser et détruire l’ensemble de la flotte adverse. La saisie est, encore une fois,
robuste.
– procedure bombarder ordi : Il s’agit sans nul doute du problème le plus épineux auquel nous
avons fait face dans ce projet. La stratégie imposée dans le sujet a rapidement conduit à l’utilisation d’une forme de mémoire entre chaque tour. Il fallait évidemment éviter de conserver trop
d’informations, mais en même temps être capable de suivre la conduite indiquée. En utilisant simplement une variable de type T Strategie et une variable de type T Coordonnees représentant
respectivement le mode de tir en cours et la première case touchée du bateau-cible actuel, nous
sommes parvenus au comportement attendu.
3
Description du programme principal - Bataille
Le programme principal s’articule en deux parties : une partie d’initialisation qui permet d’affecter
toutes les variables concernant les joueurs, et une partie concernant le jeu lui même.
La partie initialisation couvre les affectations de deux variables de type T Joueur (statut : IA ou
HUMAIN, nom, initialisation de la grille, initialisation et placement de la flotte). La stratégie de l’ordinateur est aussi initialisée ici (à ALEATOIRE).
4
La partie du jeu lui-même est constituée d’une boucle se prolongeant jusqu’à ce qu’un des deux
joueurs n’aie plus de bateaux en jeu. L’alternance des joueurs est gérées avec un booléen changeant
de valeur à chaque tour, booléen qui indexe également le tableau des joueurs. Le joueur humain peut
abandonner la partie à tout moment en entrant simplement ’00’ à la place des coordonnées d’une
attaque.
4
4.1
4.1.1
Choix algorithmiques
Placement des bateaux
Respect des règles
La principale difficulté de l’algorithme réside dans les règles de placement d’un bateau par rapport
aux autres : ”deux bateaux ne peuvent pas se toucher par les côtés mais ils peuvent se toucher par
les coins”. La zone de détection n’est pas alors un carré ou un rectangle, mais une forme englobant le
bateau :
Le rectangle à bords pleins représente le bateau, le rectangle à longs pointillés représente la zone qui
est balayée et les deux cases d’extrémités sont examinées séparément. La difficulté a été de trouver
une manière de balayer les cases de manière efficace, en factorisant le plus possible le code. La zone
rectangulaire reçoit donc des limites à gauche, à droite, en haut et en bas, en fonction de la longueur
du bateau, de ses coordonnées d’origine et de sa direction.
4.1.2
Modification de la grille
Toujours dans un souci de factorisation maximale du code pour un rendement maximal, le placement
du bateau sur la grille est une simple boucle Pour. Comme le bateau peut avoir quatre directions
différentes, un Selon affecte deux variables d’incrémentation des lignes et des colonnes.
4.2
Gestion des dégâts
Lors du tir sur un bateau, il est important de savoir quel bateau a été touché, s’il a été coulé et
où en est la flotte dans sa totalité. La grille ne comporte aucune information sur les bateaux, et le
type T Bateau ne contient pas toutes les cases sur lesquelles le bateau se trouve. Il est donc nécessaire
5
d’utiliser une fonction permettant de retrouver à quel bateau appartient telle case de la grille. À l’aide
des données stockées dans la variable affectée au bateau, on peut facilement obtenir la liste des cases,
et ensuite rechercher dans celle-ci pour chacun des bateaux de la flotte. Un compteur du nombre de
cases intactes par bateau permet de passer leur statut à COULE lors du dernier tir.
4.3
4.3.1
Tour de l’ordinateur
Mode ALEATOIRE
En mode aléatoire, l’ordinateur recherche simplement une case sur laquelle il n’a pas déjà tiré. S’il
se trouve qu’il atteint une cible, il enregistre les coordonnées du tir et passe en mode DIRECTION.
4.3.2
Mode DIRECTION
Rechercher toujours de la même manière dans quel sens est orienté le bateau pourrait conduire
à une exploitation de cette faiblesse de la part du joueur. L’ordinateur va donc tirer aléatoirement
sur les cases adjacentes et non déjà testées. Une fois qu’il a trouvé une autre case, il passe en mode
VERROUILLAGE. Si le bateau ne fait que deux cases, on repasse directement en mode ALEATOIRE, puisque
le bateau est maintenant coulé.
4.3.3
Mode VERROUILLAGE
Une fois la direction connue, l’ordinateur continue à la suivre jusqu’à arriver à un bord ou tirer
sur une case EAU. Si le bateau n’est pas encore coulé, il lui faut donc faire demi-tour, remonter les
cases touchées précédemment, et ce, jusqu’à la première case non encore découverte. Une fois le bateau
envoyé par le fond, l’ordinateur repasse en stratégie ALEATOIRE.
4.4
Alternance des tours
Comme vu précédemment, les deux profils des joueurs sont stockés dans un tableau indexé par un
booléen. Lorsque ce booléen change d’état (à la fin de chaque tour), on change aussi de joueur, donc
de grille, de flotte, de stratégie, etc. !
5
Mise au point du programme
Après une lecture complète et approfondie du sujet, nous avons chercher à cerner plus précisément
le problème, localiser les points qui allaient nous poser problème, tout en gardant une vision d’ensemble. Nous avons utilisé pour ceci la méthode des raffinages, sur quelques niveaux pour dégrossir.
De ce point nous avons pu commencer à définir de manière quasi-définitive les types que nous allions
utiliser (ceux-ci n’ont en effet connu que très peu de changement par la suite).
Une fois la structure des données déterminée, nous avons défini de manière plus précise le fonctionnement des outils qui allaient nous permettre de manipuler celles-ci. Les sous-programmes ont été séparés
en un certain nombre de modules, par catégorie de fonctionnalité (affichage, placement, etc.). Nous
ferons remarquer qu’à l’origine, il y avait deux modules Human et Machine qui ont ensuite fusionné
pour donner le module Joueur concernant la phase de jeu proprement dite.
Le travail avait été réparti par module, mais en fin de compte, nous avons tous les deux participé au
développement de chaque module, chose importante pour embrasser le projet dans sa globalité.
Les programmes de tests des modules ont été réalisés au fur et à mesure du développement de ceux-ci
afin d’assurer une continuité du suivi et d’éviter des pertes de temps trop importantes.
6
6
Problèmes actuels
L’ordinateur n’arrive pas à placer ses bateaux sur la première ligne de la grille (numérotée 0),
malgré une procédure aléatoire de placement.
De même, l’ordinateur n’arrive pas non plus à tirer sur cette même première ligne, rendant les cases
de bateaux situées sur cette ligne invulnérables.
Un problème sans doute lié avec les deux précédents est le fait que l’ordinateur ne change pas de
stratégie lorsqu’il touche une case d’un bateau située sur la deuxième ligne (numérotée 1).
Lorsque l’humain coule un bateau, le changement d’état de TOUCHE vers COULE ne se fait pas. Ceci
semble lié à la variable de type T Flotte et à son initialisation.
Nous avons passé de nombreuses heures sur ces problèmes sans pour autant arriver à les résoudre.
7
7.1
7.1.1
Améliorations - Évolution
Utilisation des constantes
Échelle de jeu
La modification des constantes MAX LIGNES et MAX COLONNES lors de la compilation permet de
changer la taille de la grille. Il est à observer que ces modifications entraı̂nent que le format du type
T Coordonnees doit voir sa longueur actualisée pour suivre les nouveaux standards de taille (si on a
plus de dix lignes, il faut pouvoir saisir plus de 2 caractères pour faire référence à une case).
Le nombre de colonnes ne pourra néanmoins dépasser vingt-six, à moins de définir de nouveaux symboles pour accéder à ces colonnes, rendant alors l’opération sensiblement plus compliquée.
La flotte utilisée par les deux joueurs peut être facilement éditée dans le module STD pour changer le
nombre de bateaux en vue de l’adaptation à la nouvelle taille de la grille, la taille desdits bateaux ainsi
que leur nom.
7.1.2
Modes de jeu
À l’aide d’un certain nombre de transformations, on pourrait modifier les règles de placement des
bateaux les uns par rapport aux autres, pour les espacer plus sur une grille plus grande, par exemple.
Les règles d’alternance des tours variant d’un individu à l’autre, il ne paraı̂t pas incohérent d’implanter
ces différentes versions et de proposer à l’utilisateur d’en choisir une au début de la partie (tirer trois
fois à l’affilée, rejouer après avoir touché, etc.).
Dans une optique de renouveau du genre, on pourrait envisager l’inclusion de nouveaux types d’armes
affectant une plus grande zone de jeu en échange d’un temps de rechargement plus important ou la
nécessité de la présence d’un vaisseau capital.
Transformer la bataille navale en deux dimensions en une bataille spatiale à trois dimensions n’est pas
non plus une tâche impossible. En effet, la plupart des algorithmes qui ont été implémentés peuvent
sans trop de peine s’adapter à trois dimensions. Le seul obstacle à cette réalisation est actuellement le
format de représentation graphique.
7
Conclusion
Ce projet PASCAL conclut donc le deuxième module ”Algorithmique et Programmation”. Il nous
a permis de peaufiner nos connaissances en programmation pour ceux qui n’étaient pas trop familiers
avec ce domaine, et d’acquérir de l’expérience supplémentaire ainsi qu’une certaine familiarité avec ce
langage pour les autres. Le sujet du projet restait accessible à tous tout en recelant suffisamment de
difficultés pour poser des problèmes intéressants.
La réutilisation d’une fonction du TP nous montre l’importance d’une implémentation soigneuse et portable, permettant une exportation rapide et simple dans des problèmes de nature totalement différente.
Nous avons aussi réutilisé plusieurs autres astuces vues en TP et en TD afin de gagner du temps et de
simplifier les algorithmes.
Ce projet a aussi été une occasion particulière d’effectuer un travail en équipe avec quelqu’un que l’on
connaı̂t et dont les connaissances différentes dans le domaine permettent d’apporter un autre éclairage.
En outre, ce sujet a mis en évidence l’importance de la programmation par contrat lors d’une conduite
de projet.
Les conditions posées pour la réalisation du projet donnent un aperçu des conditions de travail en
entreprise et apprend à gérer avec précaution les ressources, le temps, et tout ce qui en fait un projet
semblable à ceux sur lesquels nous seront amenés à travailler, tout en restant à notre échelle de temps
et de connaissances.
Nous tenons à vous remercier d’avoir lu ce rapport dans son intégralité.
Christian BELIN <[email protected]>
Guillaume ROUILLARD <[email protected]>
8

Documents pareils