程序代写代做 graph Compléments de Programmation – L1 Université de Poitiers

Compléments de Programmation – L1 Université de Poitiers
1 Ob jectifs
Jeu de serpent : 1ère partie
Consignes générales :
— ce travail est à réaliser en binôme ;
— chaque binôme maintient un document indiquant ce qui a été réalisé, par qui et
quand, durant toute la durée de la réalisation ;
— toutes les activités doivent être mentionnées : précisions apportées aux objectifs,
conception, développement, tests, etc.
— les membres de chaque binôme se mettent d’accord entre eux sur l’organisation
de leur travail, et sur la structure des fichiers contenant leurs développements ;
— pour les tests. Si ce n’est pas indiqué explicitement, un binôme a le choix entre : ne pas tester, écrire une fonction de test, vérifier expérimentalement le résultat de la fonction. Dans tous les cas, le choix doit être justifié ; le cas échéant, la fonction de test doit être produite, ou les conditions d’expérimentation doivent
être indiquées ;
— l’ensemble du travail réalisé sur le jeu de serpent (1ère et 2ème parties) sera
noté : la note prendra en particulier en compte les qualités de la conception, du développement et des tests effectués, la qualité de l’organisation et la qualité des documents produits.
On souhaite réaliser un jeu de serpent. Un serpent se déplace dans un environnement rectan- gulaire. Il se déplace automatiquement, et la direction de déplacement est contrôlée à la souris. Si le serpent sort de son environnement, ou s’il se mord lui-même, le jeu s’arrête. La longueur du serpent peut varier, de même que sa vitesse de déplacement ; il peut ingurgiter des pastilles bonus de différents types, etc.
Plus précisément, on considère trois structures :
— l’environnement du serpent est représenté par une matrice (cf. section suivante). Dans
l’exemple de la figure 1, la taille de la matrice est de 100 x 100. Un élément de cette matrice est soit vide, soit il contient une partie du serpent, soit il contient une pastille “bonus” ;
— le serpent est défini par une liste de positions : chaque position contient en particulier un point se situant dans les limites de son environnement ;
— l’environnement (y compris le serpent et les pastilles “bonus”) est affiché dans une fenêtre d’affichage, avec en particulier un coefficient de dilatation donné.
La figure 1 illustre ceci, avec un coefficient de dilatation de 5 en x et un coefficient de dilatation de 5 en y : chaque emplacement de la matrice est représenté par un carré de 5 x 5 pixels (la partie de la fenêtre d’affichage correspondant à l’environnement du serpent est donc de taille 500 x 500).
Pour cette première partie de la réalisation, on s’intéresse au fonctionnement de base du jeu. La taille du serpent est constante, de même que sa vitesse ; il n’y pas de pastilles “bonus”. La conception générale est imposée, il vous est essentiellement demandé de concevoir et de développer les fonctions du jeu, ainsi que les (fonctions de) tests et la documentation.
1

2 Outils
Vous disposez des fonctions contenues dans les fichiers CPutil_sn.ml et CPtest_sn.ml. Le fichier CPinter_sn.ml peut être utilisé pour travailler en mode interprété. Tous ces fichiers sont disponibles sur Updago.
Les fonctions sont principalement celles que vous connaissez déjà. Les fonctions nouvelles et leurs utilisations seront précisées au moment opportun.
Le type ’a matrix permet de représenter des tableaux bidimensionnels, où chaque élément est indicé par deux entiers. La fonction mat_make(dx, dy, value : int * int * ’a) : ’a matrix a pour résultat une matrice comprenant dx colonnes, dy lignes et dont toutes les va- leurs sont égales à la valeur value. L’accès à l’élément d’indices i et j d’une matrice m se note m.(i).(j), par exemple :
# let m : int matrix = mat_make(2, 3, 0) ;;
val m : int matrix = [|[|0; 0; 0|]; [|0; 0; 0|]|]
# m.(1).(2) <- 4 ;; - : unit = () # m;; - : int matrix = [|[|0; 0; 0|]; [|0; 0; 4|]|] Figure 1. Le serpent (en noir) dans son environnement : les limites de l’environnement sont en vert, les pastilles bonus sont en rouge. 2 3 Fonctions graphiques Le serpent "se déplace" dans une matrice qui a une certaine taille, par exemple 100 x 100 : dans ce cas, les indices de ligne et de colonne varient donc entre 0 et 99. L’affichage se fait dans une fenêtre graphique de taille supérieure, par exemple 700 x 700 : dans ce cas, les pixels extrêmes (en bas à gauche et en haut à droite) ont pour coordonnées (0, 0) et (699, 699). L’affichage de la matrice n’occupe qu’une partie de cette fenêtre, par exemple la partie dont les pixels extrêmes ont pour coordonnées (100, 100) et (599, 599). Géométriquement parlant, la matrice subit donc pour son affichage une homothétie (dont les coefficients en x et en y sont ici tous deux égaux à 5), et une translation (dont les coefficients en x et en y sont ici tous deux égaux à 100). Question. Après avoir défini les fonctions mytranslation_x() :int, mytranslation_y() :int, mydilation_x() :int et mydilation_y() :int, dont les résultats sont respectivement les valeurs des coefficients de translation et d’homothétie en x et en y, définissez les fonctions mygraphic_x(x : int) : int et mygraphic_y(y : int) : int calculant les coordonnées en x et en y du pixel de la fenêtre d’affichage correspondant aux coordonnées d’un point de la matrice. Écrivez les fonctions de test test_mygraphic_x_functional et test_mygraphic_y_functional. Question. Écrivez la fonction myplot(x, y : int * int) : unit, qui trace dans la fe- nêtre d’affichage un rectangle correspondant à un point de la matrice. Pour mémoire, la fonction fill_rect(px, py, dx, dy : int * int * int * int) : unit trace un rectangle dont les côtés sont parallèles aux axes de la fenêtre d’affichage, dont le point en bas à gauche a pour coordonnées px et py dans la fenêtre d’affichage, et dont les longueurs des côtés en x et en y sont dx et dy. Question. Écrivez la fonction myfill_rect(px, py, dx, dy : int * int * int * int) : unit, qui trace dans la fenêtre d’affichage le rectangle correspondant au rectangle de la matrice dont le point en bas à gauche a pour coordonnées px et py, et dont les longueurs des côtés sont dx et dy. 4 Types et fonctions de base, initialisation Question. Le serpent se déplace selon quatre directions possibles : vers le haut, le bas, la droite ou la gauche. Définissez le type énuméré t_direction, dont chaque valeur correspond à une direction de déplacement. Question. Les types t_point et t_position ci-dessous permettent de représenter des points à coordonnées entières, ainsi que les éléments composant un serpent. Le type t_value permet en particulier de représenter les valeurs des élements de la matrice (ici les valeurs EMPTY et SNAKE), mais aussi d’autres valeurs utiles pour le jeu : la valeur PROBLEM sera utilisée pour indiquer par exemple que le serpent s’est mordu lui-même, la valeur FRAME correspond au cadre entourant l’environnement du serpent. type t_point = {x : int ; y : int} ;; type t_position = {pt : t_point ; dir : t_direction} ;; type t_value = EMPTY | SNAKE | FRAME | PROBLEM ;; Écrivez une fonction color_of_value(x : t_value) : t_color permettant d’associer une couleur à chaque valeur de type t_value. Cette couleur sera utilisée en particulier pour les affi- chages : par exemple, la couleur associée à la valeur EMPTY est white (pour la liste des couleurs prédéfinies, voir le fichier CPutil_sn.ml). 3 Question. Définissez les fonctions mymatrix_dx() : int et mymatrix_dy() : int donnant les tailles en x et en y de la matrice de jeu. La matrice, le serpent et le descriptif du jeu à un moment donné correspondent à des valeurs des types suivants : type t_matrix = t_value matrix;; type t_snake = t_position list ;; type t_play = {dt : float ref ; sn : t_snake ref ; mat : t_matrix} ;; Le champ dt du type t_play correspond à la vitesse de déplacement du serpent ; plus préci- sément, il s’agit de l’intervalle entre deux déplacements : plus l’intervalle est petit, plus la vitesse du serpent est élevée. Cette valeur peut évoluer au fil du jeu, c’est pour cela que le champ est mutable. De même, le serpent évolue au fil du jeu, ne serait ce que parce qu’il se déplace : le champ correspondant est donc mutable aussi. De même qu’un tableau, une matrice est mutable, dans la mesure où la valeur de chacun de ses éléments peut être modifiée. Question. Écrivez la fonction mydt_init() : float indiquant l’intervalle de temps dt entre deux déplacements, à l’initialisation du jeu. Comme dit, la valeur de cet intervalle de temps dt peut évoluer au cours du déroulement du jeu. Écrivez la fonction mydt_acc() : float indiquant l’intervalle de temps entre deux modifications de dt, et la fonction mydt_ratio() : float indi- quant le ratio entre la nouvelle et l’ancienne valeur de dt en cas de modification. Question.Écrivezlesfonctionsmysnake_length_init() : intetmysnake_position_init() : t_point indiquant le nombre d’éléments composant le serpent, ainsi que la position initiale de la tête du serpent dans la matrice, à l’initialisation du jeu. Question. Écrivez la fonction draw_frame() : unit qui trace un cadre autour de la zone d’affichage de la matrice, en utilisant la fonction myfill_rect (et non la fonction myplot). Question. Écrivez la fonction récursive draw_whole_snake(s : t_snake) : unit qui trace la totalité du serpent. Question. Écrivez la fonction récursive init_snake() : t_snake qui calcule le serpent à l’initialisation du jeu (tous les éléments du serpent auront la même direction). Faites une fonction permettant de tester structurellement votre fonction (et / ou son éventuelle fonction auxiliaire). Question. Écrivez la fonction init_matrix() : t_matrix qui initialise la matrice de jeu (tous les éléments ont la même valeur EMPTY). Question. Écrivez la fonction itérative init_snake_matrix() : t_snake * t_matrix dont le résultat est composé du serpent et de la matrice à l’initialisation du jeu, matrice dans laquelle le serpent a été inséré. Faites une fonction de test fonctionnel. Question. Écrivez la fonction init_play() : t_play qui initialise le jeu, en utilisant les fonctions précédentes. Cette fonction trace aussi le cadre de jeu, ainsi que le serpent initial. 5 Fonctions pour une étape de jeu Question.Écrivezunefonctioncompute_new_position(pos, d : t_position * t_direction) : t_position qui, à partir d’une position pos (en pratique, celle de la tête du serpent) et d’une direction dir, calcule la position correspondant au déplacement d’une case de la matrice dans la direction dir (on ne fait pas attention ici au fait que la case atteinte peut se situer en dehors de la matrice). 4 Question.Écrivezunefonctioncompute_move(pos, dir, m : t_position * t_direction * t_matrix) : t_position * t_value, qui a pour résultat la position correspondant au dépla- cement d’une case à partir de la position pos dans la direction donnée dir, ainsi que la valeur contenue dans la case atteinte de la matrice m (ou la valeur FRAME si la position calculée se situe en dehors de la matrice). Question. Écrivez la fonction remove_snake_tail(pl : t_play) : unit qui supprime la dernière position du serpent. La fonction efface aussi la trace de la dernière position du serpent dans la fenêtre graphique. Question. Écrivez la fonction add_snake_newhead(pl, newpos : t_play * t_position) : unit qui ajoute la position newpos en tête du serpent. La fonction affiche aussi la trace de cette nouvelle position dans la fenêtre graphique. Question. Écrrivez la fonction move_snake(pl, newpos : t_play * t_position) : unit qui simule le déplacement du serpent, la nouvelle position de la tête étant la position newpos. Question. Vous disposez de la fonction analyze(pos : t_position) : t_direction, qui, à partir de la position pos donnée en paramètre et de la localisation de la souris par rapport à la fenêtre d’affichage, calcule une direction de déplacement (cf. fichier CPsnake_misc.ml). Écrivez la fonction new_step(pl : t_play) : bool, qui simule une étape du jeu. Plus préci- sément, une direction de déplacement est calculée, en utilisant la fonction analyze. Une nouvelle position est alors calculée. En fonction du résultat du calcul, il faut traiter les cas suivants : — le serpent sort de son environnement de jeu, — le serpent se mord lui-même, — le serpent se déplace normalement d’une case. Dans les deux premiers cas, un message adapté s’affiche dans l’environnement de jeu, et la fonction retourne le résultat true ; sinon, la fonction retourne le résultat false. Question.Vousdisposezdesfonctionshandle_t_acc(t, t_acc, play : float ref * float ref * t_play) : unit, qui gère l’accélération du serpent, et de la fonction simulation() : unit, qui simule le déplacement du serpent (cf. fichier CPsnake_misc.ml). Expliquez leurs fonc- tionnements. 5