game.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * File: game.c
  3. * Author: Arthur Brandao
  4. *
  5. * Created on 28 novembre 2018
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include "error.h"
  10. #include "str.h"
  11. #include "file.h"
  12. #include "game.h"
  13. #include "bomberstudent_server.h"
  14. /* --- Extern --- */
  15. Game game[MAXGAME];
  16. int nbGame = 0;
  17. /* --- Fonctions privées --- */
  18. /**
  19. * Transforme le fichier map en un tableau 2D
  20. * @param char* Le contenu du fichier map
  21. * @param int Largeur de la map
  22. * @param int Hauteur de la map
  23. * @return char** La map parser
  24. */
  25. char** parse_map(char* mapContent, int width, int height){
  26. char** map = malloc(sizeof(char*) * width);
  27. //Creation des colonnes
  28. for(int i = 0; i < width; i++){
  29. map[i] = malloc(sizeof(char) * height);
  30. }
  31. //Remplissage
  32. for(int i = 0; i < height; i++){
  33. for(int j = 0; j < width; j++){
  34. map[j][i] = *mapContent;
  35. mapContent++;
  36. }
  37. mapContent++;
  38. }
  39. return map;
  40. }
  41. /* --- Fonctions publiques --- */
  42. void ini_games(){
  43. for(int i = 0; i < MAXGAME; i++){
  44. game[i].active = false;
  45. }
  46. }
  47. JsonArray* list_map(){
  48. char** result;
  49. int nbResult;
  50. JsonArray* ja;
  51. //Initialisation json
  52. ja = malloc(sizeof(JsonArray));
  53. ini_array_encoder(ja);
  54. //Regarde les fichiers dans le dossier
  55. result = file_list(MAPDIR, &nbResult);
  56. for(int i = 0; i < nbResult; i++){
  57. add_array_string(ja, result[i]);
  58. free(result[i]);
  59. }
  60. free(result);
  61. return ja;
  62. }
  63. JsonArray* list_game(){
  64. JsonArray* ja;
  65. JsonEncoder* je;
  66. int compteur = 0, i = 0;
  67. //Si il n' y a aucune game
  68. if(nbGame == 0){
  69. return NULL;
  70. }
  71. //Initialisation json
  72. ja = malloc(sizeof(JsonArray));
  73. ini_array_encoder(ja);
  74. //Ajoute chaque game
  75. while(compteur < nbGame && i < MAXGAME){
  76. if(!game[i].active){
  77. i++;
  78. continue;
  79. }
  80. //Creation objet json
  81. je = malloc(sizeof(JsonEncoder));
  82. ini_encoder(je);
  83. add_string(je, "name", game[i].name);
  84. add_integer(je, "nbPlayer", game[i].nbPlayer);
  85. add_string(je, "map", game[i].mapName);
  86. //Ajout dans le tableau
  87. add_array_object(ja, je);
  88. //Suppr encoder objet
  89. clean_json_encoder(je);
  90. free(je);
  91. //Incremente
  92. i++;
  93. compteur++;
  94. }
  95. return ja;
  96. }
  97. int* map_size(char* map){
  98. int* res;
  99. res = malloc(sizeof(int) * 2);
  100. res[WIDTH] = 0;
  101. res[HEIGHT] = 1;
  102. //Parcours la 1er ligne pour compter le nombre de caractère
  103. while(*map != '\n' && *map != '\0'){
  104. res[WIDTH]++;
  105. map++;
  106. }
  107. if(*map == '\0'){
  108. return res;
  109. }
  110. //Compte les lignes
  111. map++;
  112. while(*map != '\0'){
  113. if(*map == '\n'){
  114. res[HEIGHT]++;
  115. }
  116. map++;
  117. }
  118. return res;
  119. }
  120. int create_game(char* name, char* map){
  121. int length, index = 0;
  122. char* path;
  123. int* size;
  124. //Regarde si il reste une game de disponnible
  125. if(nbGame == MAXGAME){
  126. return ERR;
  127. }
  128. //Cherche une game libre
  129. while(index < MAXGAME){
  130. if(game[index].active == false){
  131. break;
  132. }
  133. index++;
  134. }
  135. //Recup la map
  136. length = strlen(MAPDIR) + strlen(map);
  137. path = new_string(length);
  138. sprintf(path, "%s%s", MAPDIR, map);
  139. game[index].mapContent = file_get_content(path);
  140. //Calcul taille de la map
  141. size = map_size(game[index].mapContent);
  142. //Set Up
  143. length = strlen(name) + 1;
  144. game[index].active = true;
  145. game[index].name = string_copy(name);
  146. game[index].nbPlayer = 0;
  147. game[index].mapName = string_copy(map);
  148. game[index].width = size[WIDTH];
  149. game[index].height = size[HEIGHT];
  150. game[index].map = parse_map(game[index].mapContent, size[WIDTH], size[HEIGHT]);
  151. for(int i = 0; i < MAXPLAYER; i++){
  152. game[index].player[i] = malloc(sizeof(Player));
  153. game[index].player[i]->ini = false;
  154. }
  155. //Retourne la position de la partie dans le tableau
  156. nbGame++;
  157. free(path);
  158. free(size);
  159. return index;
  160. }
  161. int add_player(Game* g, int cliId){
  162. int index = 0;
  163. Client* cli;
  164. //Verif que la game n'est pas deja pleine
  165. if(g->nbPlayer >= MAXPLAYER){
  166. return ERR;
  167. }
  168. //Cherche un joueur non initialisé
  169. while(index < MAXPLAYER){
  170. if(!g->player[index]->ini){
  171. break;
  172. }
  173. index++;
  174. }
  175. //Recup du client
  176. cli = get_client(cliId);
  177. if(cli == NULL){
  178. return ERR;
  179. }
  180. //Creation du joueur
  181. create_player(g->player[index], cli);
  182. g->nbPlayer++;
  183. return index;
  184. }
  185. JsonEncoder* describe_game(Game* g, int playerIndex){
  186. JsonEncoder* player;
  187. JsonEncoder* desc = malloc(sizeof(JsonEncoder));
  188. JsonEncoder* map = malloc(sizeof(JsonEncoder));
  189. JsonArray* players = malloc(sizeof(JsonArray));
  190. char* content;
  191. //Initialisation
  192. ini_encoder(desc);
  193. ini_encoder(map);
  194. ini_array_encoder(players);
  195. //Info map
  196. content = remove_char(g->mapContent, '\n'); //La map sans \n car interdit en JSON
  197. add_integer(map, "width", g->width);
  198. add_integer(map, "height", g->height);
  199. add_string(map, "content", content);
  200. free(content);
  201. //Ajout info
  202. add_integer(desc, "nbPlayers", g->nbPlayer);
  203. add_object(desc, "map", map);
  204. //Ajout info courte joueur
  205. //printf("Add players\n");
  206. for(int i = 0; i < MAXPLAYER; i++){
  207. if(g->player[i]->ini){
  208. player = describe_short_player(g->player[i]);
  209. add_array_object(players, player);
  210. clean_json_encoder(player);
  211. free(player);
  212. }
  213. }
  214. //printf("Fin Add players\n");
  215. add_array(desc, "players", players);
  216. //Si besoins ajout un joueur
  217. if(playerIndex >= 0 && playerIndex < MAXPLAYER && g->player[playerIndex]->ini){
  218. player = describe_player(g->player[playerIndex]);
  219. add_object(desc, "player", player);
  220. clean_json_encoder(player);
  221. free(player);
  222. }
  223. //Nettoyage
  224. clean_json_encoder(map);
  225. free(map);
  226. return desc;
  227. }
  228. boolean notify_player(Game* g, char* method, char* ressource, JsonEncoder* param, int excludePlayerId){
  229. boolean res = true;
  230. //Regarde si la game est active
  231. if(!g->active){
  232. return false;
  233. }
  234. //Parcours les joeurs de la game
  235. for(int i = 0; i < MAXPLAYER; i++){
  236. //Si joueur actif
  237. if(g->player[i]->ini && g->player[i]->id != excludePlayerId){
  238. res = res && notify_client(g->player[i]->cli, method, ressource, param);
  239. }
  240. }
  241. return res;
  242. }
  243. void stop_game(Game* g){
  244. //Indique comme inactive
  245. g->active = false;
  246. //Suppr les joueurs
  247. for(int i = 0; i < MAXPLAYER; i++){
  248. if(g->player[i]->ini){
  249. delete_player(g->player[i]);
  250. }
  251. free(g->player[i]);
  252. }
  253. //Libere la memoire
  254. for(int i = 0; i < g->width; i++){
  255. free(g->map[i]);
  256. }
  257. free(g->map);
  258. free(g->mapName);
  259. free(g->mapContent);
  260. }
  261. void clean_games(){
  262. for(int i = 0; i < MAXGAME; i++){
  263. if(game[i].active){
  264. stop_game(&game[i]);
  265. }
  266. }
  267. }