Programmation bas niveau (BNV) Help

Correction : Sokoban

# Makefile NAME = sokoban SRCS = main.c \ board.c \ game.c \ player.c \ all : $(NAME) $(NAME): $(SRCS) gcc $(SRCS) -o $(NAME) fclean: rm -f $(NAME) re: fclean all
#ifndef __SOKOBAN_H__ #define __SOKOBAN_H__ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <unistd.h> #define HEIGHT 10 #define WIDTH 10 struct s_pos { int pos_x; int pos_y; }; typedef struct s_pos pos; struct s_game { pos *box; pos *player; pos *place; }; typedef struct s_game game; /* board.c */ void print_board(game *sokoban); void print_board_to_file(game *sokoban); /* game.c */ game * init_game(); void game_loop(game *sokoban); /* player.c */ void move_up(game *sokoban); void move_down(game *sokoban); void move_left(game *sokoban); void move_right(game *sokoban); #endif
#include "sokoban.h" void print_board(game *sokoban) { int j; int i = 0; printf("Positions :\nJoueur: %d %d\n", sokoban->player->pos_y, sokoban->player->pos_x); printf("Boite: %d %d\n", sokoban->box->pos_y, sokoban->box->pos_x); printf("Emplacement: %d %d\n", sokoban->place->pos_y, sokoban->place->pos_x); while(i < HEIGHT) { j = 0; while(j < WIDTH) { if((i == sokoban->player->pos_y) && (j == sokoban->player->pos_x)) { printf("o"); } else if((i == sokoban->box->pos_y) && (j == sokoban->box->pos_x)) { printf("X"); } else if((i == sokoban->place->pos_y) && (j == sokoban->place->pos_x)) { printf("."); } else if((i == 0) || (j == 0) || (i == 9) || (j == 9)) { printf("#"); } else { printf(" "); } j++; } printf("\n"); i++; } } void print_board_to_file(game *sokoban) { int j; int i = 0; FILE *fp = fopen("end.txt", "w"); if (fp == NULL) { printf("Le fichier end.txt n'a pas pu être ouvert\n"); exit(EXIT_FAILURE); } fprintf(fp, "Positions :\nJoueur: %d %d\n", sokoban->player->pos_y, sokoban->player->pos_x); fprintf(fp, "Boite: %d %d\n", sokoban->box->pos_y, sokoban->box->pos_x); fprintf(fp, "Emplacement: %d %d\n", sokoban->place->pos_y, sokoban->place->pos_x); while(i < HEIGHT) { j = 0; while(j < WIDTH) { if((i == sokoban->player->pos_y) && (j == sokoban->player->pos_x)) { fprintf(fp, "o"); } else if((i == sokoban->box->pos_y) && (j == sokoban->box->pos_x)) { fprintf(fp, "X"); } else if((i == sokoban->place->pos_y) && (j == sokoban->place->pos_x)) { fprintf(fp, "."); } else if((i == 0) || (j == 0) || (i == 9) || (j == 9)) { fprintf(fp, "#"); } else { fprintf(fp," "); } j++; } fprintf(fp,"\n"); i++; } fclose(fp); }
#include "sokoban.h" game * init_game() { srand(time(NULL)); game * sokoban; sokoban = malloc(sizeof(*sokoban)); sokoban->box = malloc(sizeof(*(sokoban->box))); sokoban->place = malloc(sizeof(*(sokoban->place))); sokoban->player = malloc(sizeof(*(sokoban->player))); sokoban->box->pos_x = rand() % 6 + 2; sokoban->box->pos_y = rand() % 6 + 2; sokoban->place->pos_x = rand() % 8 + 1; sokoban->place->pos_y = rand() % 8 + 1; sokoban->player->pos_x = rand() % 8 + 1; sokoban->player->pos_y = rand() % 8 + 1; return(sokoban); } void game_loop(game *sokoban) { int end = 0; while(end == 0) { system("clear"); char move; print_board(sokoban); printf("\nChoisissez un mouvement : haut(w) bas(s) gauche(a) droite(d)\n"); scanf("%c", &move); if(move == 'w') { move_up(sokoban); } else if(move == 's') { move_down(sokoban); } else if(move == 'a') { move_left(sokoban); } else if(move == 'd') { move_right(sokoban); } if((sokoban->place->pos_x == sokoban->box->pos_x) &&(sokoban->place->pos_y == sokoban->box->pos_y)) { end = 1; } if((sokoban->place->pos_x != 1) &&(sokoban->box->pos_x == 1)) { end = -1; } if((sokoban->place->pos_y != 8) &&(sokoban->box->pos_y == 8)) { end = -1; } if((sokoban->place->pos_y != 1) &&(sokoban->box->pos_y == 1)) { end = -1; } if((sokoban->place->pos_x != 8) &&(sokoban->box->pos_x == 8)) { end = -1; } } if(end == 1) { printf("C'est gagné!\n"); } else { printf("C'est perdu!\n"); } print_board_to_file(sokoban); }
#include "sokoban.h" void move_up(game *sokoban) { if(sokoban->player->pos_y > 1) { // si la boite est sur la ligne au dessus du joueur if(sokoban->player->pos_y == sokoban->box->pos_y + 1) { // si la boite est juste au dessus du joueur if(sokoban->player->pos_x == sokoban->box->pos_x) { // et que la boite n'est pas collée en haut if(sokoban->box->pos_y != 1) { sokoban->box->pos_y--; } } } sokoban->player->pos_y--; } } void move_down(game *sokoban) { if(sokoban->player->pos_y < 8) { // si la boite est sur la ligne en dessous du joueur if(sokoban->player->pos_y == sokoban->box->pos_y - 1) { // si la boite est juste en dessous du joueur if(sokoban->player->pos_x == sokoban->box->pos_x) { // et que la boite n'est pas collée en bas if(sokoban->box->pos_y != 8) { sokoban->box->pos_y++; } } } sokoban->player->pos_y++; } } void move_left(game *sokoban) { if(sokoban->player->pos_x > 1) { if(sokoban->player->pos_x == sokoban->box->pos_x + 1) { if(sokoban->player->pos_y == sokoban->box->pos_y) { if(sokoban->box->pos_x != 1) { sokoban->box->pos_x--; } } } sokoban->player->pos_x--; } } void move_right(game *sokoban) { if(sokoban->player->pos_x < 8) { if(sokoban->player->pos_x == sokoban->box->pos_x - 1) { if(sokoban->player->pos_y == sokoban->box->pos_y) { if(sokoban->box->pos_x != 8) { sokoban->box->pos_x++; } } } sokoban->player->pos_x++; } }
#include "sokoban.h" int main() { game *sokoban = init_game(); game_loop(sokoban); free(sokoban->box); free(sokoban->place); free(sokoban->player); free(sokoban); return(0); }

Télécharger la correction

22 September 2025