123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /*
- * File: game.c
- * Author: Arthur Brandao
- *
- * Created on 28 novembre 2018
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include "error.h"
- #include "str.h"
- #include "file.h"
- #include "game.h"
- #include "bomberstudent_server.h"
- /* --- Extern --- */
- Game game[MAXGAME];
- int nbGame = 0;
- /* --- Fonctions privées --- */
- /**
- * Transforme le fichier map en un tableau 2D
- * @param char* Le contenu du fichier map
- * @param int Largeur de la map
- * @param int Hauteur de la map
- * @return char** La map parser
- */
- char** parse_map(char* mapContent, int width, int height){
- char** map = malloc(sizeof(char*) * width);
- //Creation des colonnes
- for(int i = 0; i < width; i++){
- map[i] = malloc(sizeof(char) * height);
- }
- //Remplissage
- for(int i = 0; i < height; i++){
- for(int j = 0; j < width; j++){
- map[j][i] = *mapContent;
- mapContent++;
- }
- mapContent++;
- }
- return map;
- }
- /* --- Fonctions publiques --- */
- void ini_games(){
- for(int i = 0; i < MAXGAME; i++){
- game[i].active = false;
- }
- }
- JsonArray* list_map(){
- char** result;
- int nbResult;
- JsonArray* ja;
- //Initialisation json
- ja = malloc(sizeof(JsonArray));
- ini_array_encoder(ja);
- //Regarde les fichiers dans le dossier
- result = file_list(MAPDIR, &nbResult);
- for(int i = 0; i < nbResult; i++){
- add_array_string(ja, result[i]);
- free(result[i]);
- }
- free(result);
- return ja;
- }
- JsonArray* list_game(){
- JsonArray* ja;
- JsonEncoder* je;
- int compteur = 0, i = 0;
- //Si il n' y a aucune game
- if(nbGame == 0){
- return NULL;
- }
- //Initialisation json
- ja = malloc(sizeof(JsonArray));
- ini_array_encoder(ja);
- //Ajoute chaque game
- while(compteur < nbGame && i < MAXGAME){
- if(!game[i].active){
- i++;
- continue;
- }
- //Creation objet json
- je = malloc(sizeof(JsonEncoder));
- ini_encoder(je);
- add_string(je, "name", game[i].name);
- add_integer(je, "nbPlayer", game[i].nbPlayer);
- add_string(je, "map", game[i].mapName);
- //Ajout dans le tableau
- add_array_object(ja, je);
- //Suppr encoder objet
- clean_json_encoder(je);
- free(je);
- //Incremente
- i++;
- compteur++;
- }
- return ja;
- }
- int* map_size(char* map){
- int* res;
- res = malloc(sizeof(int) * 2);
- res[WIDTH] = 0;
- res[HEIGHT] = 1;
- //Parcours la 1er ligne pour compter le nombre de caractère
- while(*map != '\n' && *map != '\0'){
- res[WIDTH]++;
- map++;
- }
- if(*map == '\0'){
- return res;
- }
- //Compte les lignes
- map++;
- while(*map != '\0'){
- if(*map == '\n'){
- res[HEIGHT]++;
- }
- map++;
- }
- return res;
- }
- int create_game(char* name, char* map){
- int length, index = 0;
- char* path;
- int* size;
- //Regarde si il reste une game de disponnible
- if(nbGame == MAXGAME){
- return ERR;
- }
- //Cherche une game libre
- while(index < MAXGAME){
- if(game[index].active == false){
- break;
- }
- index++;
- }
- //Recup la map
- length = strlen(MAPDIR) + strlen(map);
- path = new_string(length);
- sprintf(path, "%s%s", MAPDIR, map);
- game[index].mapContent = file_get_content(path);
- //Calcul taille de la map
- size = map_size(game[index].mapContent);
- //Set Up
- length = strlen(name) + 1;
- game[index].active = true;
- game[index].name = string_copy(name);
- game[index].nbPlayer = 0;
- game[index].mapName = string_copy(map);
- game[index].width = size[WIDTH];
- game[index].height = size[HEIGHT];
- game[index].map = parse_map(game[index].mapContent, size[WIDTH], size[HEIGHT]);
- for(int i = 0; i < MAXPLAYER; i++){
- game[index].player[i] = malloc(sizeof(Player));
- game[index].player[i]->ini = false;
- }
- //Retourne la position de la partie dans le tableau
- nbGame++;
- free(path);
- free(size);
- return index;
- }
- int add_player(Game* g, int cliId){
- int index = 0;
- Client* cli;
- //Verif que la game n'est pas deja pleine
- if(g->nbPlayer >= MAXPLAYER){
- return ERR;
- }
- //Cherche un joueur non initialisé
- while(index < MAXPLAYER){
- if(!g->player[index]->ini){
- break;
- }
- index++;
- }
- //Recup du client
- cli = get_client(cliId);
- if(cli == NULL){
- return ERR;
- }
- //Creation du joueur
- create_player(g->player[index], cli);
- g->nbPlayer++;
- return index;
- }
- JsonEncoder* describe_game(Game* g, int playerIndex){
- JsonEncoder* player;
- JsonEncoder* desc = malloc(sizeof(JsonEncoder));
- JsonEncoder* map = malloc(sizeof(JsonEncoder));
- JsonArray* players = malloc(sizeof(JsonArray));
- char* content;
- //Initialisation
- ini_encoder(desc);
- ini_encoder(map);
- ini_array_encoder(players);
- //Info map
- content = remove_char(g->mapContent, '\n'); //La map sans \n car interdit en JSON
- add_integer(map, "width", g->width);
- add_integer(map, "height", g->height);
- add_string(map, "content", content);
- free(content);
- //Ajout info
- add_integer(desc, "nbPlayers", g->nbPlayer);
- add_object(desc, "map", map);
- //Ajout info courte joueur
- //printf("Add players\n");
- for(int i = 0; i < MAXPLAYER; i++){
- if(g->player[i]->ini){
- player = describe_short_player(g->player[i]);
- add_array_object(players, player);
- clean_json_encoder(player);
- free(player);
- }
- }
- //printf("Fin Add players\n");
- add_array(desc, "players", players);
- //Si besoins ajout un joueur
- if(playerIndex >= 0 && playerIndex < MAXPLAYER && g->player[playerIndex]->ini){
- player = describe_player(g->player[playerIndex]);
- add_object(desc, "player", player);
- clean_json_encoder(player);
- free(player);
- }
- //Nettoyage
- clean_json_encoder(map);
- free(map);
- return desc;
- }
- boolean notify_player(Game* g, char* method, char* ressource, JsonEncoder* param, int excludePlayerId){
- boolean res = true;
- //Regarde si la game est active
- if(!g->active){
- return false;
- }
- //Parcours les joeurs de la game
- for(int i = 0; i < MAXPLAYER; i++){
- //Si joueur actif
- if(g->player[i]->ini && g->player[i]->id != excludePlayerId){
- res = res && notify_client(g->player[i]->cli, method, ressource, param);
- }
- }
- return res;
- }
- void stop_game(Game* g){
- //Indique comme inactive
- g->active = false;
- //Suppr les joueurs
- for(int i = 0; i < MAXPLAYER; i++){
- if(g->player[i]->ini){
- delete_player(g->player[i]);
- }
- free(g->player[i]);
- }
- //Libere la memoire
- for(int i = 0; i < g->width; i++){
- free(g->map[i]);
- }
- free(g->map);
- free(g->mapName);
- free(g->mapContent);
- }
- void clean_games(){
- for(int i = 0; i < MAXGAME; i++){
- if(game[i].active){
- stop_game(&game[i]);
- }
- }
- }
|