Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (60)
BasedOnStyle: Microsoft
IndentWidth: 2
---
Language: Cpp
*.o
sokoban
unittest
minunit.h
suvegardedesfonctioin.c
**/html
**/latex
\ No newline at end of file
This diff is collapsed.
CFLAGS=-Wall -Wextra
clean_all :
rm -f sokoban unittest *.o
all: build unittest
build: sokoban
test: unittest
@./unittest
distrib:
tar -zcvf Arnaud_Albiez.tar.gz main.c grid.c grid.h Makefile
clean :
rm -f sokoban *.o
doc :
doxygen
main.o : main.c grid.h
gcc -c $(CFLAGS) main.c
grid.o : grid.c grid.h
gcc -c $(CFLAGS) grid.c
player.o : player.c player.h
gcc -c $(CFLAGS) player.c
sokoban : main.o grid.o player.o
gcc -o sokoban main.o grid.o player.o
test.o : test.c grid.h player.h
gcc -c test.c
unittest : test.o grid.o player.o
gcc -o unittest test.o grid.o player.o
This diff is collapsed.
#include "grid.h" #include "grid.h"
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
int coordonner_vers_indice(struct Grid *grid, int col, int row)
{
return ((row * grid->column_number) + col);
}
enum CaseType *init_grid(int width, int height)
{
size_t taille_grid = width * height;
enum CaseType *new_grid = (enum CaseType *)malloc(taille_grid * sizeof(enum CaseType));
for (size_t i = 0; i < taille_grid; i++)
{
new_grid[i] = NONE;
}
return new_grid;
}
struct Player *init_player()
{
struct Player *player = (struct Player *)malloc(sizeof(struct Player));
player->col = 0;
player->row = 0;
return player;
}
struct Grid *new_grid(int width, int height)
{
struct Grid *new_strut_grid = (struct Grid *)malloc(sizeof(struct Grid));
new_strut_grid->column_number = width;
new_strut_grid->row_number = height;
new_strut_grid->game_grid = init_grid(width, height);
new_strut_grid->position = init_player();
new_strut_grid->tabGoal = NULL;
return new_strut_grid;
}
struct Grid *init_level(const char *file_path)
{
// ouverture du fichier en mode lecture
FILE *file = fopen(file_path, "r");
if (!file)
{
fprintf(stderr, "Error %s not found", file_path);
exit(-1);
}
char line[100] = {0};
int number_column = 0; // nombre de colonne
int number_row = 0; /// nombre de ligne
int number_goals = 0;
// on lit la première ligne du fichier
fgets(line, 100, file);
sscanf(line, "%d %d %d", &number_column, &number_row, &number_goals);
struct Grid *grid = new_grid(number_column, number_row);
int current_row = 0;
grid->number_goal = number_goals;
grid->tabGoal = malloc(number_goals * (sizeof(struct Goal)));
int current_goal = 0;
// On lit le fichier ligne par ligne jusqu'à la fin du fichier
while (fgets(line, 100, file) != NULL)
{
char *buffer = line;
int current_column = 0;
while (*buffer && *buffer != '\n')
{
if (buffer[0] == '@')
{
grid->position->col = current_column;
grid->position->row = current_row;
}
else if (buffer[0] == '.')
{
grid->tabGoal[current_goal].col = current_column;
grid->tabGoal[current_goal].row = current_row;
current_goal = +1;
}
else
{
change_cell_grid(grid, current_column, current_row, buffer[0]);
}
current_column += 1;
buffer += 1;
}
current_row += 1;
}
// fermeture du fichier
fclose(file);
return grid;
}
enum CaseType get_grid(struct Grid *grid, int col, int row)
{
if (0 <= col && col < grid->column_number && 0 <= row && row < grid->row_number)
{
return grid->game_grid[coordonner_vers_indice(grid, col, row)];
}
else
{
return -1;
}
}
int get_goal(struct Grid *grid, int col, int row)
{
if (0 <= col && col < grid->column_number && 0 <= row && row < grid->row_number)
{
for (int indice = 0; indice < grid->number_goal; indice++)
{
if (grid->tabGoal[indice].col == col && grid->tabGoal[indice].row == row)
{
return 1;
}
}
return -1;
}
else
{
return -1;
}
}
void Affichage_grid(struct Grid *grid)
{
for (int row = 0; row < grid->row_number; row++)
{
for (int col = 0; col < grid->column_number; col++)
{
switch (get_grid(grid, col, row))
{
case NONE: {
if (grid->position->col == col && grid->position->row == row)
{
printf("@");
}
else if (get_goal(grid, col, row) == 1)
{
printf(".");
}
else
{
printf(" ");
}
break;
}
case WALL: {
printf("#");
break;
}
case BOX: {
printf("$");
break;
}
case PLAYER: {
printf("@");
break;
}
case GOAL: {
printf(".");
break;
}
}
}
printf("\n");
}
}
void change_cell_grid(struct Grid *grid, int col, int row, enum CaseType new_valeur)
{
grid->game_grid[coordonner_vers_indice(grid, col, row)] = new_valeur;
}
void init_level(const char* file_path){ void free_grid(struct Grid *grid)
// ouverture du fichier en mode lecture {
FILE* file = fopen(file_path, "r"); free(grid->game_grid);
if(!file){ free(grid->tabGoal);
fprintf(stderr, "Error %s not found", file_path); free(grid->position);
exit(-1); free(grid);
}
char line[100] = {0};
int number_column = 0; // nombre de colonne
int number_row = 0; /// nombre de ligne
int number_goals = 0;
// on lit la première ligne du fichier
fgets(line, 100, file);
sscanf(line, "%d %d %d", &number_column, &number_row, &number_goals);
int current_row = 0;
int current_goal = 0;
// On lit le fichier ligne par ligne jusqu'à la fin du fichier
while(fgets(line, 100, file) != NULL){
char* buffer = line;
int current_column = 0;
while(*buffer && *buffer != '\n'){
current_column += 1;
buffer += 1;
}
current_row += 1;
}
// fermeture du fichier
fclose(file);
} }
#ifndef GRID_HEADER #ifndef GRID_HEADER
#define GRID_HEADER #define GRID_HEADER
enum CaseType{ #include "player.h"
WALL = '#',
BOX = '$', /** Liste des element du niveau
PLAYER = '@', */
GOAL = '.', enum CaseType
NONE = ' ' {
WALL = '#',
BOX = '$',
PLAYER = '@',
GOAL = '.',
NONE = ' '
}; };
/**
* @struct Goal grid.h
* @brief Cette structure contient des piont de Goal
*/
struct Goal
{
int col, row;///< Position colone et ligne
};
/** /**
* @struct Grid grid.h * @struct Grid grid.h
* @brief Cette structure contient les informations * @brief Cette structure contient les informations
* concernant la grille du jeu et son contenu * concernant la grille du jeu et son contenu
*/ */
struct Grid{ struct Grid
enum CaseType** game_grid; ///< Tableau contenant les entités présents dans le jeu {
int column_number; ///< Nombre de colonne de game_grid enum CaseType *game_grid; ///< Tableau contenant les entités présents dans le jeu
int row_number; ///< Nomber de ligne de game_grid int column_number; ///< Nombre de colonne de game_grid
int row_number; ///< Nomber de ligne de game_grid
struct Player *position; ///< Positioin du joueur
struct Goal *tabGoal; ///< Liste des but
int number_goal; ///< nombre de goal
}; };
void init_level(const char* file_path);
/** Trouve l'indice a partire d'une coordonnée
* revoye un int
*
* @param grid la struct grid pour recuperer la taille total du tableau
* @param col position colonne
* @param row position ligne
*/
int coordonner_vers_indice(struct Grid *grid, int col, int row);
/** Initialise un grid templie de NONE
*
* @param widht Hauteur du tableau
* @param height Largueur du tableau
*/
enum CaseType *init_grid(int width, int height);
/** Initialise les coordonner du player en 0, 0
*
*/
struct Player *init_player();
/** Initialise l'emsemble de la structure grid
*
* @param widht Hauteur du tableau
* @param height Largueur du tableau
*/
struct Grid *new_grid(int width, int height);
/** Initialise dans la struct grid un niveau demander
*
* @param file_path un fichier .txt avec un niveau du sokoban dedans
*/
struct Grid *init_level(const char *file_path);
/** Cherche un element de la grid
*
* @param grid struct grid pour chercher dans la grid
* @param col l'emplacement colone de la donnée demander
* @param row l'emplacement ligne de la donnée demander
*/
enum CaseType get_grid(struct Grid *grid, int col, int row);
/** Cherche si la coordonner donner et un goal
* renovoye -1 si il a pas de goals a l'emplacement demander sinon renvoye 1
*
* @param grid struct grid pour chercher dans la grid
* @param col l'emplacement colone
* @param row l'emplacement ligne
*/
int get_goal(struct Grid *grid, int col, int row);
/** Affiche la grid qui se trouvent dans la struct grid
*
* @param grid struct grid
*/
void Affichage_grid(struct Grid *grid);
/** Cherche un element de la grid
*
* @param grid struct grid pour chercher dans la grid
* @param col l'emplacement colone de la nouvelle valeur
* @param row l'emplacement ligne de la nouvelle valeur
* @param new_valeur nouvelle valeur a l'emplacement demander
*/
void change_cell_grid(struct Grid *grid, int col, int row, enum CaseType new_valeur);
/** Libere tout les donner qui se trouve dans la structure
*
* @param grid struct grid
*/
void free_grid(struct Grid *grid);
#endif #endif
#include <stdio.h>
#include "grid.h" #include "grid.h"
#include <stdbool.h> #include <stdbool.h>
int main(void){ #include <stdio.h>
bool run = true; enum Event
while(run){ {
char entry = fgetc(stdin); EVT_QUIT = 0,
switch(entry){ EVT_TOP = 1,
case 'q' :{ EVT_BOTTOM = 2,
run = false; EVT_RIGTH = 3,
break; EVT_LEFT = 4,
} };
}
} enum Event next_event()
{
while (true)
{
char entry = fgetc(stdin);
switch (entry)
{
case 'e':
return EVT_QUIT;
case 'z':
return EVT_TOP;
case 's':
return EVT_BOTTOM;
case 'q':
return EVT_LEFT;
case 'd':
return EVT_RIGTH;
}
}
} }
int main(void)
{
struct Grid *grid = init_level("./level1.txt");
bool run = true;
while (run)
{
Affichage_grid(grid);
if (win_condition(grid) == 1)
{
run = false;
}
enum Event event = next_event();
switch (event)
{
case EVT_QUIT: {
run = false;
break;
}
case EVT_TOP: {
move_player(grid, TOP);
break;
}
case EVT_BOTTOM: {
move_player(grid, BOTTOM);
break;
}
case EVT_LEFT: {
move_player(grid, LEFT);
break;
}
case EVT_RIGTH: {
move_player(grid, RIGHT);
break;
}
}
}
free_grid(grid);
}
#include "player.h"
#include "grid.h"
struct coordonee position_to(int col, int row, enum Direction direction)
{
struct coordonee result;
switch (direction)
{
case TOP:
result.col = col;
result.row = row - 1;
break;
case BOTTOM:
result.col = col;
result.row = row + 1;
break;
case LEFT:
result.col = col - 1;
result.row = row;
break;
case RIGHT:
result.col = col + 1;
result.row = row;
break;
}
return result;
}
int move_box(struct Grid *grid, int position_col, int position_row, enum Direction direction)
{
struct coordonee next_position = position_to(position_col, position_row, direction);
if (get_grid(grid, next_position.col, next_position.row) == NONE)
{
change_cell_grid(grid, position_col, position_row, NONE);
change_cell_grid(grid, next_position.col, next_position.row, BOX);
return 1;
}
else{
return -1;
}
}
void move_player(struct Grid *grid, enum Direction direction)
{
struct coordonee next_position = position_to(grid->position->col, grid->position->row, direction);
if (get_grid(grid, next_position.col, next_position.row) == NONE)
{
grid->position->col = next_position.col;
grid->position->row = next_position.row;
}
else if(get_grid(grid, next_position.col, next_position.row) == BOX)
{
if(move_box(grid, next_position.col, next_position.row, direction) == 1){
grid->position->col = next_position.col;
grid->position->row = next_position.row;
}
else{
return;
}
}
else{
return;
}
}
int win_condition(struct Grid *grid)
{
for(int indice = 0; indice<grid->number_goal; indice++)
{
if(get_grid(grid, grid->tabGoal[indice].col, grid->tabGoal[indice].row) != BOX)
{
return -1;
}
}
return 1;
}
\ No newline at end of file
#ifndef __PLAYER_H
#define __PLAYER_H
struct Grid;
/** Liste des direction possible
*/
enum Direction
{
TOP = 'z',
LEFT = 'q',
RIGHT = 'd',
BOTTOM = 's'
};
/**
* @struct coordonee player.h
* @brief Cette structure contient une position colone ligne
*/
struct coordonee
{
int col, row;
};
/**
* @struct Player player.h
* @brief Cette structure contient une position colone ligne du joueur
*/
struct Player
{
int col, row;
};
/** renvoye la position du joueur en fonction d'un mouvement
*
* @param col position colonne du joueur
* @param row position ligne du joueur
* @param direction direction du joueur
*/
struct coordonee position_to(int col, int row, enum Direction direction);
/** En fonction d'un movement regarde si c'est posible et fait les changement des coordonner du joueur
*
* @param grid la struct grid pour recuperer la taille total du tableau
* @param direction direction du joueur
*/
void move_player(struct Grid *grid, enum Direction direction);
/** En fonction d'un movement regarde si c'est posible et fait les changement des coordonner du joueur
*
* @param grid la struct grid
* @param position_col position de la box col
* @param position_row position de la box row
* @param direction direction du joueur
*/
int move_box(struct Grid *grid, int position_col, int position_row, enum Direction direction);
int win_condition(struct Grid *grid);
#endif
\ No newline at end of file
#include "cester.h"
#include "grid.h"
#include "player.h"
#include <stdio.h>
CESTER_TEST(test_grid_get_cell, grid, {
struct Grid *grid = new_grid(5, 5);
for (int x = 0; x < 5; ++x)
{
for (int y = 0; y < 5; ++y)
{
cester_assert_equal(NONE, get_grid(grid, x, y));
}
}
})
CESTER_TEST(test_grid_change_cell, grid, {
struct Grid *grid = new_grid(5, 5);
change_cell_grid(grid, 1, 2, GOAL);
Affichage_grid(grid);
cester_assert_equal(GOAL, get_grid(grid, 1, 2));
})
CESTER_TEST(test_move_direction, grid,
{
struct Grid *grid = init_level("./level1.txt");
Affichage_grid(grid);
move_player(grid, TOP);
Affichage_grid(grid);
cester_assert_equal(PLAYER, get_grid(grid, 11, 5));
}
)