Rendu TP5
This commit is contained in:
277
game.c
277
game.c
@@ -1,159 +1,4 @@
|
||||
/**
|
||||
*
|
||||
* Ce programme montre comment il est possible de dessiner les figures
|
||||
* géométriques suivantes :
|
||||
*
|
||||
* cercle
|
||||
* disque ( cercle plein )
|
||||
* ellipse
|
||||
* ellipse pleine
|
||||
* rectangle
|
||||
* rectangle plein
|
||||
* ligne
|
||||
* point
|
||||
* Courbe de Bézier
|
||||
* polygone
|
||||
* polygone plein
|
||||
*
|
||||
* Pour cela le programme utilise les fonctions suivantes :
|
||||
*
|
||||
*------------------------------------------------------------------------------
|
||||
* MLV_draw_circle: Dessine un cercle à une position et un rayon spécifiés en
|
||||
* paramètres.
|
||||
*
|
||||
* void MLV_draw_circle(
|
||||
* int x, Coordonnée en X du centre du cercle
|
||||
* int y, Coordonnée en Y du centre du cercle
|
||||
* int radius, Rayon du cercle
|
||||
* MLV_Color color Couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_filled_circle : Dessine un disque plein dont le centre et le rayon
|
||||
* sont passés en parametres.
|
||||
*
|
||||
* void MLV_draw_filled_circle(
|
||||
* int x, Coordonnée en X du centre du cercle
|
||||
* int y, Coordonnée en Y du centre du cercle
|
||||
* int radius, Rayon du cercle
|
||||
* MLV_Color color Couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_ellipse : Dessine une ellipse dont la position, les rayons et la
|
||||
* couleur sont passés en paramètres.
|
||||
*
|
||||
* MLV_draw_ellipse(
|
||||
* int x, Coordonnée en X du centre de l'ellipse
|
||||
* int y, Coordonnée en Y du centre de l'ellipse
|
||||
* int radius_x, Rayon en X de l'ellipse
|
||||
* int radius_y, Rayon en Y de l'ellipse
|
||||
* MLV_Color color Couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_filled_ellipse : Dessine une ellipse pleine dont la position, les
|
||||
* rayons et la couleur sont passés en paramètres.
|
||||
*
|
||||
* void MLV_draw_filled_ellipse(
|
||||
* int x, Coordonnee en X du centre de l'ellipse
|
||||
* int y, Coordonnee en Y du centre de l'ellipse
|
||||
* int radius_x, Rayon en X de l'ellipse
|
||||
* int radius_y, Rayon en Y de l'ellipse
|
||||
* MLV_Color color Couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_rectangle : Dessine un rectangle dont la taille, la couleur et la
|
||||
* position du sommet Nord-Ouest sont données en
|
||||
* paramètres.
|
||||
*
|
||||
* void MLV_draw_rectangle(
|
||||
* int x, Coordonnée en X du sommet Nord-Ouest du rectangle
|
||||
* int y, Coordonnée en Y du sommet Nord-Ouest du rectangle
|
||||
* int width, Largeur du rectangle
|
||||
* int height, Hauteur du rectangle
|
||||
* MLV_Color color Couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_filled_rectangle : Dessine un rectangle dont la taille, la couleur
|
||||
* et la position du sommet Nord-Ouest sont données
|
||||
* en paramètres.
|
||||
* void MLV_draw_filled_rectangle(
|
||||
* int x, Coordonnée en X du sommet Nord-Ouest du rectangle
|
||||
* int y, Coordonnée en Y du sommet Nord-Ouest du rectangle
|
||||
* int width, Largeur du rectangle
|
||||
* int height, Hauteur du rectangle
|
||||
* MLV_Color color Couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_line : Dessine une ligne dont les coordonnées des deux extrémités
|
||||
* sont passées en paramètres.
|
||||
* void MLV_draw_line(
|
||||
* int x1, Coordonnée en X de la première extrémité de la ligne
|
||||
* int y1, Coordonnée en Y de la première extrémité de la ligne
|
||||
* int x2, Coordonnée en X de la deuxième extrémité de la ligne
|
||||
* int y2, Coordonnée en Y de la deuxième extrémité de la ligne
|
||||
* MLV_Color color Couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_point : Dessine un point dont les coordonées sont passées
|
||||
* en paramètres.
|
||||
*
|
||||
* void MLV_draw_point(
|
||||
* int x, Coordonnée en X du point
|
||||
* int y, Coordonnée en Y du point
|
||||
* MLV_Color color Couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_bezier_curve: Dessine une courbe de Bézier à partir d'une liste de
|
||||
* sommets.
|
||||
*
|
||||
* void MLV_draw_bezier_curve(
|
||||
* const int* vx, La liste des coordonnées en X des différents
|
||||
* sommets de la courbe.
|
||||
* const int* vy, La liste des coordonnées en Y des différents
|
||||
* sommets de la courbe.
|
||||
* int npoints, Le nombre de sommets de la courbe de Bézier.
|
||||
* MLV_Color color La couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_polygon: Dessine un polygone à partir d'une liste de sommets.
|
||||
*
|
||||
* void MLV_draw_polygon(
|
||||
* const int* vx, La liste des coordonnées en X des différents
|
||||
* sommets du polygone.
|
||||
* const int* vy, La liste des coordonnées en Y des différents
|
||||
* sommets du polygone.
|
||||
* int npoints, Le nombre de sommets du polygone.
|
||||
* MLV_Color color La couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* MLV_draw_polygon: Dessine un polygone plein à partir d'une liste de sommets.
|
||||
*
|
||||
* void MLV_draw_filled_polygon(
|
||||
* const int* vx, La liste des coordonnées en X des différents
|
||||
* sommets du polygone.
|
||||
* const int* vy, La liste des coordonnées en Y des différents
|
||||
* sommets du polygone.
|
||||
* int npoints, Le nombre de sommets du polygone.
|
||||
* MLV_Color color La couleur du tracé
|
||||
* );
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Il existe d'autres fonctions de dessin. Vous les trouverez en consultant
|
||||
* le fichier MLV_shape.h ou en tapant dans le terminal la commande :
|
||||
*
|
||||
* man MLV_shape.h
|
||||
*/
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <MLV/MLV_all.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -175,62 +20,19 @@ void print_help()
|
||||
printf("Press ESC to exit the game.\n");
|
||||
}
|
||||
|
||||
int read_grid_from_file(const char *filename, char grid[NBL][NBC + 1])
|
||||
{
|
||||
int i, j, nb_fruit = 0;
|
||||
FILE *file = fopen(filename, "r");
|
||||
if (!file)
|
||||
{
|
||||
fprintf(stderr, "Error: Could not open file %s\n", filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (i = 0; i < NBL; i++)
|
||||
{
|
||||
if (!fgets(grid[i], NBC + 2, file))
|
||||
{
|
||||
fprintf(stderr, "Error: File %s does not contain enough lines\n", filename);
|
||||
fclose(file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
grid[i][strcspn(grid[i], "\n")] = '\0';
|
||||
|
||||
for (j = 0; j < NBC; j++)
|
||||
{
|
||||
if (grid[i][j] == FRUIT)
|
||||
{
|
||||
nb_fruit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return nb_fruit;
|
||||
}
|
||||
|
||||
int count_fruits(char grid[NBL][NBC + 1])
|
||||
{
|
||||
int i, j, nb_fruit = 0;
|
||||
for (i = 0; i < NBL; i++)
|
||||
{
|
||||
for (j = 0; j < NBC; j++)
|
||||
{
|
||||
if (grid[i][j] == FRUIT)
|
||||
{
|
||||
nb_fruit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nb_fruit;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int opt, option_index = 0, loop_count = 0, nb_fruit = 0;
|
||||
FILE *stream;
|
||||
char *buf = NULL;
|
||||
size_t size_buf = 0;
|
||||
int nbl, nbc, i;
|
||||
int opt, option_index = 0;
|
||||
int loop_count = 0, nb_fruit = 0;
|
||||
char *input_file = NULL;
|
||||
MLV_Keyboard_button touche = MLV_KEYBOARD_NONE;
|
||||
int width = 640, height = 480;
|
||||
char grid[NBL][NBC + 1] = {0};
|
||||
MLV_Keyboard_button touche = MLV_KEYBOARD_NONE;
|
||||
|
||||
Grid *g;
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
@@ -264,24 +66,56 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (input_file == NULL)
|
||||
{
|
||||
input_file = "levels/default";
|
||||
}
|
||||
stream = fopen(input_file, "r");
|
||||
if (!stream)
|
||||
{
|
||||
fprintf(stderr, "Error: unable to open file\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
nbl = count_nb_lines(stream);
|
||||
rewind(stream);
|
||||
nbc = getline(&buf, &size_buf, stream);
|
||||
if (nbc == -1)
|
||||
{
|
||||
fprintf(stderr, "Error: malformed file\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
nbc--;
|
||||
|
||||
g = allocate_grid(nbl, nbc);
|
||||
|
||||
copy(buf, g->grid[0]);
|
||||
for (i = 1; i < nbl; i++)
|
||||
{
|
||||
int size_tmp = getline(&buf, &size_buf, stream);
|
||||
if (size_tmp != nbc + 1)
|
||||
{
|
||||
fprintf(stderr, "Error: inconsistent line length\n");
|
||||
free(buf);
|
||||
fclose(stream);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
copy(buf, g->grid[i]);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
fclose(stream);
|
||||
|
||||
if (input_file)
|
||||
{
|
||||
nb_fruit = read_grid_from_file(input_file, grid);
|
||||
nb_fruit = count_fruits(input_file, g);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < NBL; i++)
|
||||
{
|
||||
for (j = 0; j < NBC; j++)
|
||||
{
|
||||
grid[i][j] = EMPTY;
|
||||
}
|
||||
}
|
||||
nb_fruit = count_fruits(grid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
place_snake(grid, &snake);
|
||||
place_snake(g, &snake);
|
||||
|
||||
MLV_create_window("SNAKE", "3R-IN1B", width, height);
|
||||
MLV_change_frame_rate(24);
|
||||
@@ -300,7 +134,7 @@ int main(int argc, char *argv[])
|
||||
loop_count = (loop_count + 1) % DIFFICULTY;
|
||||
if (loop_count == 0)
|
||||
{
|
||||
result = move_snake(&snake, grid);
|
||||
result = move_snake(&snake, g);
|
||||
|
||||
if (result == WALL || result == SNAKE)
|
||||
{
|
||||
@@ -328,7 +162,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
draw_grid(grid);
|
||||
draw_grid(g);
|
||||
MLV_actualise_window();
|
||||
|
||||
switch (touche)
|
||||
@@ -358,5 +192,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
MLV_free_window();
|
||||
free_grid(g);
|
||||
return 0;
|
||||
}
|
||||
136
grid.c
136
grid.c
@@ -1,41 +1,84 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <MLV/MLV_all.h>
|
||||
#include "grid.h"
|
||||
#include "snake.h"
|
||||
|
||||
void debug(char grid[NBL][NBC + 1])
|
||||
Grid *allocate_grid(int n, int m)
|
||||
{
|
||||
Grid *g = malloc(sizeof(Grid));
|
||||
int i;
|
||||
if (!g)
|
||||
{
|
||||
fprintf(stderr, "Error: could not allocate Grid.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
g->nbl = n;
|
||||
g->nbc = m;
|
||||
g->grid = malloc(n * sizeof(char *));
|
||||
if (!g->grid)
|
||||
{
|
||||
fprintf(stderr, "Error: could not allocate g->grid.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
g->grid[i] = calloc(m + 1, sizeof(char));
|
||||
if (!g->grid[i])
|
||||
{
|
||||
fprintf(stderr, "Error: could not allocate row.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
void free_grid(Grid *g)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < NBL; i++)
|
||||
if (!g)
|
||||
return;
|
||||
for (i = 0; i < g->nbl; i++)
|
||||
{
|
||||
printf("%s\n", grid[i]);
|
||||
free(g->grid[i]);
|
||||
}
|
||||
free(g->grid);
|
||||
free(g);
|
||||
}
|
||||
|
||||
void debug(Grid *g)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < g->nbl; i++)
|
||||
{
|
||||
printf("%s\n", g->grid[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int compute_size(int w, int h)
|
||||
int compute_size(Grid *g, int w, int h)
|
||||
{
|
||||
int size_width = w / NBC;
|
||||
int size_height = h / NBL;
|
||||
int size_width = w / g->nbc;
|
||||
int size_height = h / g->nbl;
|
||||
return (size_width < size_height) ? size_width : size_height;
|
||||
}
|
||||
|
||||
void draw_grid(char grid[NBL][NBC + 1])
|
||||
void draw_grid(Grid *g)
|
||||
{
|
||||
int i, j;
|
||||
int window_width = MLV_get_window_width();
|
||||
int window_height = MLV_get_window_height();
|
||||
int cell_size = compute_size(window_width, window_height);
|
||||
int cell_size = compute_size(g, window_width, window_height);
|
||||
|
||||
MLV_draw_filled_rectangle(0, 0, window_width, window_height, MLV_COLOR_BLACK);
|
||||
|
||||
for (i = 0; i < NBL; i++)
|
||||
for (i = 0; i < g->nbl; i++)
|
||||
{
|
||||
for (j = 0; j < NBC; j++)
|
||||
for (j = 0; j < g->nbc; j++)
|
||||
{
|
||||
int x = j * cell_size;
|
||||
int y = i * cell_size;
|
||||
|
||||
switch (grid[i][j])
|
||||
switch (g->grid[i][j])
|
||||
{
|
||||
case WALL:
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_BROWN);
|
||||
@@ -57,29 +100,86 @@ void draw_grid(char grid[NBL][NBC + 1])
|
||||
}
|
||||
}
|
||||
|
||||
void place_snake(char grid[NBL][NBC + 1], Snake *snake)
|
||||
void place_snake(Grid *g, struct SnakeStruct *snake)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SNAKE_SIZE; i++)
|
||||
{
|
||||
Coord part = snake->pos[i];
|
||||
grid[part.y][part.x] = 's';
|
||||
g->grid[part.y][part.x] = 's';
|
||||
}
|
||||
}
|
||||
|
||||
Element move_snake(Snake *snake, char grid[NBL][NBC + 1]) {
|
||||
Element move_snake(struct SnakeStruct *snake, Grid *g)
|
||||
{
|
||||
Coord tail = snake->pos[SNAKE_SIZE - 1];
|
||||
Coord head;
|
||||
Element element_at_head;
|
||||
|
||||
grid[tail.y][tail.x] = EMPTY;
|
||||
g->grid[tail.y][tail.x] = EMPTY;
|
||||
|
||||
crawl(snake);
|
||||
crawl(snake, g);
|
||||
|
||||
head = snake->pos[0];
|
||||
element_at_head = grid[head.y][head.x];
|
||||
element_at_head = g->grid[head.y][head.x];
|
||||
|
||||
grid[head.y][head.x] = SNAKE;
|
||||
g->grid[head.y][head.x] = SNAKE;
|
||||
|
||||
return element_at_head;
|
||||
}
|
||||
|
||||
int count_nb_lines(FILE *stream)
|
||||
{
|
||||
int count = 0;
|
||||
char buffer[256];
|
||||
while (fgets(buffer, sizeof(buffer), stream))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
rewind(stream);
|
||||
return count;
|
||||
}
|
||||
|
||||
int count_fruits(const char *filename, Grid *g)
|
||||
{
|
||||
int i, j, nb_fruit = 0;
|
||||
FILE *file = fopen(filename, "r");
|
||||
if (!file)
|
||||
{
|
||||
fprintf(stderr, "Error: Could not open file %s\n", filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (i = 0; i < g->nbl; i++)
|
||||
{
|
||||
if (!fgets(g->grid[i], g->nbc + 2, file))
|
||||
{
|
||||
fprintf(stderr, "Error: File %s does not contain enough lines\n", filename);
|
||||
fclose(file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
g->grid[i][strcspn(g->grid[i], "\n")] = '\0';
|
||||
|
||||
for (j = 0; j < g->nbc; j++)
|
||||
{
|
||||
if (g->grid[i][j] == FRUIT)
|
||||
{
|
||||
nb_fruit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return nb_fruit;
|
||||
}
|
||||
|
||||
void copy(const char *src, char *dst)
|
||||
{
|
||||
int i = 0;
|
||||
while (src[i] != '\0' && src[i] != '\n')
|
||||
{
|
||||
dst[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
dst[i] = '\0';
|
||||
}
|
||||
29
grid.h
29
grid.h
@@ -1,10 +1,18 @@
|
||||
#ifndef GRID_H
|
||||
#define GRID_H
|
||||
|
||||
#include "snake.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define NBL 22
|
||||
#define NBC 36
|
||||
struct SnakeStruct;
|
||||
|
||||
struct GridStruct
|
||||
{
|
||||
char **grid;
|
||||
int nbl;
|
||||
int nbc;
|
||||
};
|
||||
|
||||
typedef struct GridStruct Grid;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -14,10 +22,15 @@ typedef enum
|
||||
SNAKE = 's'
|
||||
} Element;
|
||||
|
||||
void debug(char grid[NBL][NBC + 1]);
|
||||
int compute_size(int w, int h);
|
||||
void draw_grid(char grid[NBL][NBC + 1]);
|
||||
void place_snake(char grid[NBL][NBC + 1], Snake *snake);
|
||||
Element move_snake(Snake* snake, char grid[NBL][NBC+1]);
|
||||
Grid* allocate_grid(int n, int m);
|
||||
void free_grid(Grid *g);
|
||||
void debug(Grid *g);
|
||||
int compute_size(Grid *g, int w, int h);
|
||||
void draw_grid(Grid *g);
|
||||
void place_snake(Grid *g, struct SnakeStruct *snake);
|
||||
Element move_snake(struct SnakeStruct *snake, Grid *g);
|
||||
int count_nb_lines(FILE *stream);
|
||||
int count_fruits(const char *filename, Grid *g);
|
||||
void copy(const char *src, char *dst);
|
||||
|
||||
#endif /* GRID_H */
|
||||
@@ -19,4 +19,4 @@ w w
|
||||
f f
|
||||
|
||||
f
|
||||
w w
|
||||
w w
|
||||
10
snake.c
10
snake.c
@@ -1,23 +1,23 @@
|
||||
#include "grid.h"
|
||||
#include "snake.h"
|
||||
|
||||
void crawl(Snake *snake)
|
||||
void crawl(Snake *snake, Grid *g)
|
||||
{
|
||||
int i;
|
||||
Coord new_head = snake->pos[0];
|
||||
switch (snake->dir)
|
||||
{
|
||||
case LEFT:
|
||||
new_head.x = (new_head.x - 1 + NBC) % NBC;
|
||||
new_head.x = (new_head.x - 1 + g->nbc) % g->nbc;
|
||||
break;
|
||||
case RIGHT:
|
||||
new_head.x = (new_head.x + 1) % NBC;
|
||||
new_head.x = (new_head.x + 1) % g->nbc;
|
||||
break;
|
||||
case TOP:
|
||||
new_head.y = (new_head.y - 1 + NBL) % NBL;
|
||||
new_head.y = (new_head.y - 1 + g->nbl) % g->nbl;
|
||||
break;
|
||||
case BOTTOM:
|
||||
new_head.y = (new_head.y + 1) % NBL;
|
||||
new_head.y = (new_head.y + 1) % g->nbl;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
10
snake.h
10
snake.h
@@ -1,6 +1,8 @@
|
||||
#ifndef SNAKE_H
|
||||
#define SNAKE_H
|
||||
|
||||
struct GridStruct;
|
||||
|
||||
#define SNAKE_SIZE 4
|
||||
|
||||
typedef struct
|
||||
@@ -17,12 +19,14 @@ typedef enum
|
||||
RIGHT
|
||||
} Direction;
|
||||
|
||||
typedef struct
|
||||
struct SnakeStruct
|
||||
{
|
||||
Coord pos[SNAKE_SIZE];
|
||||
Direction dir;
|
||||
} Snake;
|
||||
};
|
||||
|
||||
void crawl(Snake *snake);
|
||||
typedef struct SnakeStruct Snake;
|
||||
|
||||
void crawl(Snake *snake, struct GridStruct *g);
|
||||
|
||||
#endif /* SNAKE_H */
|
||||
Reference in New Issue
Block a user