Files
Sokoban/script/function.c
cyjullien1 8bc1813d60 editor bug
2025-01-08 15:36:00 +01:00

971 lines
31 KiB
C

/**
* \file function.c
* Ce fichier contient toute les fonction utile pour le jeu. Sauf pour
* l'affichage.
*
*/
#include "../include/function.h"
#include "../include/display.h"
#include "../include/read.h"
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_rect.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_scancode.h>
#include <SDL2/SDL_timer.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/**
* \brief Cette fonction permet de creer une liste 2D
* \param x Nombre de ligne.
* \param y Nombre de colonne.
* \return Le pointeur du tableau 2D de char (1 octet).
*/
char **creatArea2D (const int x, const int y)
{
char **tab2d;
tab2d = calloc (x, sizeof (char *));
if (tab2d == NULL)
{
return NULL;
}
bool fail = false;
int i;
for (i = 0; i < x && !fail; ++i)
{
tab2d[i] = calloc (y, sizeof (char));
if (tab2d[i] == NULL)
{
fail = true;
}
}
if (fail)
{
int j;
for (j = 0; j < i; ++j)
{
free (tab2d[j]);
}
free (tab2d);
return NULL;
}
return tab2d;
}
/**
* \brief Cette fontion permet de liberer l'espace tu tableau 2D de char.
* \param tab Le tableau 2D.
* \param x Le nombre de ligne.
* \return Void.
*/
void free2D (char **tab, int x)
{
int i;
for (i = 0; i < x; ++i)
{
free (tab[i]);
}
free (tab);
return;
}
/**
* \brief La fontction permet de savoir si le joueur peut ce deplacer dans une
* direction.
* \param valueOfNCase La valeur de la case dans la direction que le joueur
* veut aller.
* \param valueOfNPlusOneCase La valeur de la case dans la direction que le
* joueur veut aller mais une fois de plus.
* \return 0 Si c'est un mur devant le joueur, 1 si c'est vide devant le
* joueur, 2 si c'est une boite mais qu'on peux la pousser ,3 si le joueur
* pousse une boite sur un point d'interer, 4 si le joueur bouge sur un point
* d'interer, 5 si le joueur peux pousser une boite mais le joueur se place sur
* un point d'interer et 6 si le joueur pousse une boite sur un point d'interer
* et que le joueur est aussi sur un point d'interer. 7 si valueOfNCase est un bouton.
*/
char canIGoDirection (char valueOfNCase, char valueOfNPlusOneCase)
{
if (valueOfNCase != WALL)
{
if ((valueOfNCase == BOX && valueOfNPlusOneCase == EMPTY)
|| (valueOfNCase == BOX && valueOfNPlusOneCase == TARGET))
{
if (valueOfNPlusOneCase == TARGET)
{
// Box on target
return 3;
}
// move the box
return 2;
}
if ((valueOfNCase == BOX_ON_TARGET && valueOfNPlusOneCase == EMPTY)
|| (valueOfNCase == BOX_ON_TARGET
&& valueOfNPlusOneCase == TARGET))
{
if (valueOfNPlusOneCase == TARGET)
{
// Box on target and player on target too
return 6;
}
// move the box but player on a target
return 5;
}
if (valueOfNCase == BUTTON || valueOfNCase == BUTTON_CUSTOM )
{
return 7;
}
if (valueOfNCase == TARGET)
{
// move player on target
return 4;
}
if (valueOfNCase == EMPTY)
{
// move player
return 1;
}
}
return 0;
}
/**
* \brief Cette fonction effectue les deplacements du joueur et des boites en
* fonction de la situation.
* \param tab Le tableau 2D du plateau de jeu.
* \param playerpos La position actuel du joueur.
* \param direction La direction que le joueur veut effectuer.
* \param score_user Toutes les données nécessaire pour calculer le score fini
* du joueur.
* \return int return 1 si le joueur n'a pas bouger.
*
*/
int move (char **tab, vect *playerPos, vect direction, score *score_user)
{
short int valueOfNCase
= tab[playerPos->x + direction.x][playerPos->y + direction.y];
vect add = plusVect (*playerPos, direction);
add = plusVect (add, direction);
short int valueOfNPlusOneCase;
if (add.x < 0 || add.y < 0)
{
valueOfNPlusOneCase = WALL;
}
else
{
valueOfNPlusOneCase = tab[add.x][add.y];
}
short int returnValue
= canIGoDirection (valueOfNCase, valueOfNPlusOneCase);
short int playerState = tab[playerPos->x][playerPos->y];
if (returnValue != 0)
score_user->move_player++;
switch (returnValue)
{
case 0:
playAudio(2);
return 1;
break;
case 1:
//move player
playAudio(4);
tab[playerPos->x + direction.x][playerPos->y + direction.y] = PLAYER;
break;
case 2:
// move player and the box
playAudio(5);
tab[playerPos->x + direction.x][playerPos->y + direction.y] = PLAYER;
tab[playerPos->x + direction.x * 2][playerPos->y + direction.y * 2]
= BOX;
score_user->move_box++;
break;
case 3:
// move player and the box is well-placed
playAudio(3);
tab[playerPos->x + direction.x][playerPos->y + direction.y] = PLAYER;
tab[playerPos->x + direction.x * 2][playerPos->y + direction.y * 2]
= BOX_ON_TARGET;
score_user->move_box++;
break;
case 4:
// move player on a target
playAudio(4);
tab[playerPos->x + direction.x][playerPos->y + direction.y]
= PLAYER_ON_TARGET;
break;
case 5:
// move box and player on a target
playAudio(4);
tab[playerPos->x + direction.x * 2][playerPos->y + direction.y * 2]
= BOX;
tab[playerPos->x + direction.x][playerPos->y + direction.y]
= PLAYER_ON_TARGET;
score_user->move_box++;
break;
case 6:
// move player on a target and box on a target
playAudio(3);
tab[playerPos->x + direction.x * 2][playerPos->y + direction.y * 2]
= BOX_ON_TARGET;
tab[playerPos->x + direction.x][playerPos->y + direction.y]
= PLAYER_ON_TARGET;
score_user->move_box++;
break;
case 7:
playAudio(3);
tab[playerPos->x + direction.x][playerPos->y + direction.y]
= PLAYER_ON_BUTTON;
break;
default:
printf ("Commande inconnue !\n");
}
if (returnValue != 0)
{
if (playerState == PLAYER_ON_TARGET)
{
tab[playerPos->x][playerPos->y] = TARGET;
}
else if (playerState == PLAYER_ON_BUTTON)
{
tab[playerPos->x][playerPos->y] = BUTTON;
}
else
{
tab[playerPos->x][playerPos->y] = EMPTY;
}
playerPos->x = playerPos->x + direction.x;
playerPos->y = playerPos->y + direction.y;
}
return 0;
}
/**
*
* \brief La fonction permet de faire la boucle de jeu et le menu.
* \param tab2d Le tableau 2d carre.
* \param N LE nombre d'element de tab2d.
* \param playerPos La position de depart du joueur.
* \param targets Le tableau de toutes les positions des points d'interer de la
* maps.
* \param int nbr_targets Le nombre de point d'interer.
* \param display_user Tout les information SDL pour afficher le jeu.
* \param score_user Toute les données nécessaire pour calculer le score fini
* du joueur.
*\param menu True si c'est la loop du menu.
* \return L'indice de la map si c'est un menu, sinon renvoie -1
*/
int inGameLoop (char **tab2d, vect *dim_tab, vect *playerPos, vect *targets,
int nbr_targets, dis *display_user, score *score_user,
bool menu)
{
int fov = -1;
int indice_button = -1;
vect size_menu
= { display_user->size_menu - 10, display_user->size_window / 3 - 10 };
vect coor_time
= { 40, display_user->size_window - display_user->size_menu + 50 };
vect coor_move_player
= { display_user->size_window / 3 + 60,
display_user->size_window - display_user->size_menu + 50 };
vect coor_move_box
= { (display_user->size_window / 3) * 2 + 10,
display_user->size_window - display_user->size_menu + 50 };
if (menu)
fov = 5;
else
{
displayTextSDL (display_user, "MP : 0", coor_move_player, size_menu,
30);
displayTextSDL (display_user, "MB : 0", coor_move_box, size_menu, 30);
}
time_t time_start = time (NULL);
time_t current_time = time (NULL);
time_t delay = 0;
vect direction = { 0, 0 };
char input;
bool finish = false;
SDL_Event event;
screenDisplayGameSDL (tab2d, *dim_tab, display_user, playerPos, fov,direction);
while (!finish)
{
while (SDL_PollEvent (&event))
{
if (event.type == SDL_QUIT) {
return 0; // Quitter si l'utilisateur ferme la fenêtre
}
if (event.type == SDL_KEYDOWN)
{
input = event.key.keysym.scancode;
switch (input)
{
case SDL_SCANCODE_ESCAPE:
if(menu) return 0;
return -1000;
finish = true;
break;
case SDL_SCANCODE_D:
direction.y = 1;
direction.x = 0;
break;
case SDL_SCANCODE_A:
direction.y = -1;
direction.x = 0;
break;
case SDL_SCANCODE_W:
direction.x = -1;
direction.y = 0;
break;
case SDL_SCANCODE_S:
direction.x = 1;
direction.y = 0;
break;
case SDL_SCANCODE_RETURN:
if (tab2d[playerPos->x][playerPos->y] == PLAYER_ON_BUTTON)
return indice_button;
break;
default:
direction.x = 0;
direction.y = 0;
}
int tmp = move (tab2d, playerPos, direction, score_user);
if(tmp == 1){direction.x = 0; direction.y = 0;}
screenDisplayGameSDL (tab2d, *dim_tab, display_user, playerPos,
fov,direction);
if (!menu)
{
char nbr_p[20];
snprintf (nbr_p, 20, "MP : %d", score_user->move_player);
char nbr_b[20];
snprintf (nbr_b, 20, "MB : %d", score_user->move_box);
displayTextSDL (display_user, nbr_p, coor_move_player,
size_menu, 30);
displayTextSDL (display_user, nbr_b, coor_move_box,
size_menu, 30);
if (isWin (tab2d, targets, nbr_targets))
{
return 1;
finish = true;
}
if (islose (tab2d, dim_tab->x))
{
return 0;
finish = true;
}
}
else if (tab2d[playerPos->x][playerPos->y] == PLAYER_ON_BUTTON)
{
vect size_txt = { display_user->size_menu,
display_user->size_window };
char txt_empty[100]
= " "
" ";
displayTextSDL (display_user, txt_empty, coor_time,
size_txt, 30);
char txt_button[70] = "";
indice_button = playerPos->y / 5;
if (indice_button <= 3)
{
snprintf (txt_button, 63,
" - : Niveau %d : - ",
indice_button);
}
else if (indice_button == dim_tab->y / 5)
{
snprintf (txt_button, 63,
" - : Creer un niveau %d : -",
indice_button - 3);
}
else
{
snprintf (txt_button, 63,
" - : Niveau custom %d : - ",
indice_button - 3);
}
displayTextSDL (display_user, txt_button, coor_time,
size_txt, 30);
}
else
{
vect size_txt = { display_user->size_menu-50,
display_user->size_window };
char txt_empty[70]
= " - : Echap pour quitter : - ";
displayTextSDL (display_user, txt_empty, coor_time,
size_txt, 25);
}
}
}
current_time = time (NULL);
if (current_time > delay)
{
delay = current_time;
char *char_time = timeToText (time (NULL) - time_start);
if (!menu)
displayTextSDL (display_user, char_time, coor_time, size_menu,
30);
free (char_time);
}
SDL_Delay (16);
}
return -1;
}
/**
*
* \brief La fonction permet de faire la boucle de l'éditeur.
* \param tab2d Le tableau 2d carre.
* \param N LE nombre d'element de tab2d.
* \param playerPos La position de depart du joueur.
* \param targets Le tableau de toutes les positions des points d'interer de la
* maps.
* \param int nbr_targets Le nombre de point d'interer.
* \param display_user Tout les information SDL pour afficher le jeu.
* \param score_user Toute les données nécessaire pour calculer le score fini
* du joueur.
* \param num_fichier Simplement le numéro de la map actuel.
* \return renvoie -2 ce qui signifie l'editeur
*/
int inEditorLoop (char **tab2d, vect *dim_tab, vect *playerPos, vect *targets,
int nbr_targets, dis *display_user,score *score_user, int num_fichier)
{
vect direction = { 0, 0 };
int fov = -1;
int indice_button = -1;
vect size_menu
= { display_user->size_menu - 10, display_user->size_window / 3 - 10 };
vect coor_time
= { 40, display_user->size_window - display_user->size_menu + 50 };
vect coor_move_player
= { display_user->size_window / 3 + 60,
display_user->size_window - display_user->size_menu + 50 };
vect coor_move_box
= { (display_user->size_window / 3) * 2 + 10,
display_user->size_window - display_user->size_menu + 50 };
char input;
bool finish = false;
SDL_Event event;
screenDisplayGameSDL (tab2d, *dim_tab, display_user, playerPos, fov,direction);
int GRID_SIZE = display_user->size_box;
int BLOCK_SIZE = (display_user->size_window- (display_user->size_menu/2))/GRID_SIZE;
int GRID_X_OFFSET =display_user->size_window - display_user->size_menu/2;
int GRID_Y_OFFSET =0;
while (!finish)
{
while (SDL_PollEvent (&event))
{
if (event.type == SDL_QUIT) {
save_grid_to_file(num_fichier,tab2d);
return 0; // Quitter si l'utilisateur ferme la fenêtre
}
if (event.type == SDL_MOUSEBUTTONDOWN) {
if (event.button.button == SDL_BUTTON_LEFT) {
// Lorsque le clic gauche est effectué
playAudio(2);
int click_x, click_y;
SDL_GetMouseState(&click_x, &click_y); // Récupérer la position de la souris
if (click_x >= GRID_X_OFFSET && click_x < GRID_X_OFFSET + GRID_SIZE * BLOCK_SIZE &&
click_y >= GRID_Y_OFFSET && click_y < GRID_Y_OFFSET + GRID_SIZE * BLOCK_SIZE) {
// Calcul des indices de la case
int col = (click_x - GRID_X_OFFSET) / BLOCK_SIZE;
int row = (click_y - GRID_Y_OFFSET) / BLOCK_SIZE;
// Met à jour la case correspondante
if(tab2d[row][col] ==3)
{
tab2d[row][col] =0;
}
else if(tab2d[row][col] <3)
{
tab2d[row][col] += 1;
}
// Met à jour l'affichage
screenDisplayGameSDL (tab2d, *dim_tab, display_user, playerPos, fov,direction);
}
}
if (event.button.button == SDL_BUTTON_RIGHT) {
// Lorsque le clic gauche est effectué
playAudio(2);
int click_x, click_y;
SDL_GetMouseState(&click_x, &click_y); // Récupérer la position de la souris
if (click_x >= GRID_X_OFFSET && click_x < GRID_X_OFFSET + GRID_SIZE * BLOCK_SIZE &&
click_y >= GRID_Y_OFFSET && click_y < GRID_Y_OFFSET + GRID_SIZE * BLOCK_SIZE) {
// Calcul des indices de la case
int col = (click_x - GRID_X_OFFSET) / BLOCK_SIZE;
int row = (click_y - GRID_Y_OFFSET) / BLOCK_SIZE;
// Met à jour la case correspondante
if(tab2d[row][col] ==0)
{
tab2d[row][col] =3;
}
else if(tab2d[row][col] <=3)
{
tab2d[row][col] -= 1;
}
// Met à jour l'affichage
screenDisplayGameSDL (tab2d, *dim_tab, display_user, playerPos, fov,direction);
}
}
}
if (event.type == SDL_KEYDOWN)
{
input = event.key.keysym.scancode;
switch (input)
{
case SDL_SCANCODE_ESCAPE:
save_grid_to_file(num_fichier,tab2d);
return -1;
finish = true;
break;
case SDL_SCANCODE_D:
direction.y = 1;
direction.x = 0;
break;
case SDL_SCANCODE_A:
direction.y = -1;
direction.x = 0;
break;
case SDL_SCANCODE_W:
direction.x = -1;
direction.y = 0;
break;
case SDL_SCANCODE_S:
direction.x = 1;
direction.y = 0;
break;
case SDL_SCANCODE_RETURN:
if (tab2d[playerPos->x][playerPos->y] == PLAYER_ON_BUTTON )
return indice_button;
break;
default:
direction.x = 0;
direction.y = 0;
}
int tmp = move (tab2d, playerPos, direction, score_user);
if(tmp == 1){direction.x = 0; direction.y = 0;}
screenDisplayGameSDL (tab2d, *dim_tab, display_user, playerPos,
fov,direction);
}
}
SDL_Delay (16);
}
return -2;
}
/**
*
* \brief La fonction permet d' afficher le title screen.
* \param display_user Tout les information SDL pour afficher le jeu.
* \return renvoie -3 ce qui signifie le title screen
*/
int titleScreen (dis *display_user)
{
char input;
bool finish = false;
SDL_Event event;
int indice_button = -1;
vect size_menu
= { display_user->size_menu - 10, display_user->size_window / 3 - 10 };
vect coor_time
= { 40, display_user->size_window - display_user->size_menu + 30 };
vect coor_move_player
= { 190, display_user->size_window - display_user->size_menu + 100 };
char txt_button[70] = "";
vect size_txt = { display_user->size_menu,display_user->size_window };
snprintf (txt_button, 63," Aubin and Cyprien",indice_button);
displayTextSDL (display_user, txt_button, coor_time,size_txt, 30);
int tab[7] = {0,4,8,12,16,20,24};
int sinus[7] = {10,14,18,22,26,30,34};
while (!finish)
{
while (SDL_PollEvent (&event))
{
if (event.type == SDL_QUIT) {
return 0; // Quitter si l'utilisateur ferme la fenêtre
}
if (event.type == SDL_KEYDOWN)
{
input = event.key.keysym.scancode;
switch (input)
{
case SDL_SCANCODE_RETURN:
playAudio(0);
return -1;
break;
}
}
}
for(int i=0;i<7;i++)
{
tab[i]++;
if (tab[i] >30){sinus[i]--; } else{sinus[i]++;}
if(tab[i]>60){ tab[i]=0; }
}
tab[0]>30? snprintf(txt_button, 63," press enter ",indice_button):snprintf(txt_button, 63," ",indice_button);
displayTextSDL (display_user, txt_button, coor_move_player,size_txt, 20);
vect s = { display_user->size_window /2-200, 50 + sinus[0] * 2 };
vect o = { display_user->size_window /2-200+60, 50 + sinus[1] * 2 };
vect k = { display_user->size_window /2-200+120, 50 + sinus[2] * 2 };
vect oo = { display_user->size_window/2-200+180, 50 + sinus[3] * 2 };
vect b = { display_user->size_window /2-200+240, 50 + sinus[4] * 2 };
vect a = { display_user->size_window /2-200+300, 50 + sinus[5] * 2 };
vect n = { display_user->size_window /2-200+360, 50 + sinus[6] * 2 };
snprintf (txt_button, 63,"S",indice_button);
displayTextSDL (display_user, txt_button, s,size_txt, 50);
snprintf (txt_button, 63,"O",indice_button);
displayTextSDL (display_user, txt_button, o,size_txt, 50);
snprintf (txt_button, 63,"K",indice_button);
displayTextSDL (display_user, txt_button, k,size_txt, 50);
snprintf (txt_button, 63,"O",indice_button);
displayTextSDL (display_user, txt_button, oo,size_txt, 50);
snprintf (txt_button, 63,"B",indice_button);
displayTextSDL (display_user, txt_button, b,size_txt, 50);
snprintf (txt_button, 63,"A",indice_button);
displayTextSDL (display_user, txt_button, a,size_txt, 50);
snprintf (txt_button, 63,"N",indice_button);
displayTextSDL (display_user, txt_button, n,size_txt, 50);
SDL_Delay (16);
}
return -3;
}
/**
* \brief Cette fonction verrifie si la partie est gagnante.
* \param tab2d Le tableau 2D du jeu.
* \param targets Le tableau de toute les positions des points d'interer.
* \param nbr_targets Le nombre de points d'interer.
* \return True si le joueur a remplis tout les points d'interer, false si ce
* n'est pas le cas .
*/
bool isWin (char **tab2d, vect *targets, int nbr_targets)
{
int i;
for (i = 0; i < nbr_targets; ++i)
{
int x = targets[i].x;
int y = targets[i].y;
if (tab2d[x][y] != BOX_ON_TARGET)
{
return false;
}
}
return true;
}
/**
* \brief La fonction renvois si la partie est perdante.
* \param tab2d Le tableau 2d carre du plateau de jeu.
* \param N Le nombre d'éléments dans le tab2d. (zone de jeu est carré)
* \return True si c'est perdu, false si c'est pas perdu a cette instant.
*
*/
bool islose (char **tab2d, const int N)
{
int x = 0, y = 0;
for (x = 0; x < N; ++x)
{
for (y = 0; y < N; ++y)
{
bool isblock = false;
if (tab2d[x][y] == BOX)
{
vect box;
box.x = x;
box.y = y;
isblock = blockBox (tab2d, box);
}
if (isblock)
{
return true;
}
}
}
return false;
}
/**
* \brief La fonction fait une addition de vecteur, (x1+x2, y1+y2).
* \param one Premier vecteur.
* \param two Deuzieme vecteur.
* \return vect Un vecteur de l'addition de one et two.
*/
vect plusVect (vect one, vect two)
{
vect result;
result.x = one.x + two.x;
result.y = one.y + two.y;
return result;
}
/**
* \brief Renvois la longeur Manhattan
*/
int lengthVect (vect vector) { return abs (vector.x) + abs (vector.y); }
/**
* \brief La fonction permet de savoir si une boite est dans une situation ou
* le joueur ne poura pas la debloqué.
* \param tab2d Le tableau 2D carre du plateau de jeu.
* \param box_coor Les corrdonnée de la boite que la fonction test.
* \return True si la la boite est bloquer, sinon false.
*/
bool blockBox (char **tab2d, vect box_coor)
{
int nbr_touch = 0;
vect card[4] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } };
int indice_card[4] = { 0 };
int id_box = -1;
int i;
for (i = 0; i < 4; ++i)
{
vect test = plusVect (box_coor, card[i]);
char val = tab2d[test.x][test.y];
if (val == BOX || val == WALL || val == BOX_ON_TARGET)
{
nbr_touch++;
if (val == BOX || val == BOX_ON_TARGET)
{
id_box = nbr_touch - 1;
}
indice_card[nbr_touch - 1] = i;
}
}
if (nbr_touch == 0)
return false;
if (nbr_touch >= 3)
{
if (id_box != -1)
{
vect other1 = card[indice_card[(id_box + 1) % 3]];
vect other2 = card[indice_card[(id_box + 2) % 3]];
vect test_add_other = plusVect (other1, other2);
vect coor_box = plusVect (card[indice_card[id_box]], box_coor);
vect other_plus_box1 = plusVect (other1, coor_box);
vect other_plus_box2 = plusVect (other2, coor_box);
int val1 = tab2d[other_plus_box1.x][other_plus_box1.y];
int val2 = tab2d[other_plus_box2.x][other_plus_box2.y];
if (test_add_other.x == 0 && test_add_other.y == 0)
{
if ((val1 == WALL || val1 == BOX || val1 == BOX_ON_TARGET)
|| (val2 == WALL || val2 == BOX || val2 == BOX_ON_TARGET))
{
return true;
}
return false;
}
}
return true;
}
if (nbr_touch == 2)
{
int id1 = indice_card[0];
int id2 = indice_card[1];
vect add = plusVect (card[id1], card[id2]);
if (lengthVect (add) == 2)
{
if (id_box == -1)
return true;
vect test = plusVect (card[indice_card[id_box]],
card[indice_card[(id_box + 1) % 2]]);
test = plusVect (test, box_coor);
if (tab2d[test.x][test.y] == WALL)
return true;
}
return false;
}
vect normal = card[indice_card[0]];
vect director1 = card[(indice_card[0] + 1) % 4];
vect director2 = card[(indice_card[0] + 3) % 4];
vect dir_test[2] = { director1, director2 };
bool wall = false;
for (int i = 0; i < 2; ++i)
{
wall = false;
vect current = plusVect (box_coor, dir_test[i]);
while (!wall)
{
char val = tab2d[current.x][current.y];
vect cur_nor = plusVect (current, normal);
char val_nor = tab2d[cur_nor.x][cur_nor.y];
if (val == WALL)
wall = true;
else if (val == TARGET)
return false;
if (val_nor != WALL)
{
return false;
}
current = plusVect(current, dir_test[i]);
}
}
return true;
}
/**
* \brief Cette fonction renvois transforme le forma time en texte. (min:sec)
* \param time Le temps qu'on veux convertire.
* \return char Le string du texte.
*/
char *timeToText (time_t time)
{
char *result = calloc (20, sizeof (char));
result[0] = '\0';
unsigned int min = time / 60;
unsigned int sec = time % 60;
snprintf (result, 20, "Time : %02d:%02d", min, sec);
return result;
}
/**
* \brief Mets à 0 le score.
* \param player_score Le score a mettre à 0.
* \return void
*/
void nullScore(score *player_score)
{
player_score->after = 0;
player_score->before = 0;
player_score->move_box = 0;
player_score->move_player = 0;
}
/**
* \brief Fonction de loop pour la win ou la lose.
* \param display_user Tout les information du display de l'utilisateur utile.
* \param win Si on veut un affichage de victoire ou non.
*/
void winOrLoseLoop(dis *display_user,score *score_user, bool win)
{
SDL_Surface *img;
SDL_Texture *texture;
if(win){ img = IMG_Load("image/win.png");playAudio(0);}
else {img = IMG_Load("image/lose.png");playAudio(1);}
texture = SDL_CreateTextureFromSurface (display_user->renderer, img);
vect pos = {0, 0};
vect size = {display_user->size_window, display_user->size_window};
displayImage(display_user->renderer, texture, pos, size);
char text[50] = "";
snprintf(text, 50, "Score : %u",scoreCalculatorCyp(score_user, win));
vect pos_score = {10, (display_user->size_window*3) / 4};
vect size_score = {display_user->size_window / 4, display_user->size_window - 10};
displayTextSDL(display_user, text , pos_score, size_score, 80);
SDL_RenderPresent (display_user->renderer);
bool finish = false;
SDL_Event event;
SDL_Delay(100);
while(!finish)
{
SDL_PollEvent(&event);
if(event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_RETURN) finish = true;
SDL_Delay(16);
}
SDL_FreeSurface (img);
SDL_DestroyTexture (texture);
return;
}
unsigned int scoreCalculator(score *score_user, bool win)
{
unsigned short int result = 65535; //plus grand nombre
int time = score_user->after - score_user->before;
result -= (score_user->move_box + score_user->move_player) * time;
if (!win)
{
result /= 50;
}
return result;
}
unsigned int scoreCalculatorCyp(score *score_user, bool win)
{
unsigned short int result = 10000; //plus grand nombre
int time = score_user->after - score_user->before;
result -= (score_user->move_box + score_user->move_player) * time;
if (!win)
{
result /= 50;
}
if(result <0)
{
result=0;
}
return result;
}