diff --git a/Makefile b/Makefile index 2d32de9e594334c84002230c70ef9b8c3d85e9af..a8065e49454f8289a2df51bead05bdccfd119156 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ CC = gcc CFLAGS = -Wall -cheval: main.o user.o - $(CC) -o cheval main.o user.o +cheval: main.o user.o message.o + $(CC) -o cheval main.o user.o message.o clean: rm *.o diff --git a/message.c b/message.c new file mode 100644 index 0000000000000000000000000000000000000000..fe734ba188dfc5393a52d7f80d0434cd4c7bdbdb --- /dev/null +++ b/message.c @@ -0,0 +1,83 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/param.h> + +#include "message.h" +#include "user.h" +#include "request.h" +#include "response.h" + + +void receive_loop(user_t* u){ + receive_data_t* data = u->r_data; + message in; + read(data->pipes[0], &in, sizeof(message)); + + if(in.dest_id != data->id || in.dest_id == ID_WILDCARD){ // si le message ne nous est pas destine on le passe au suivant de facon transparente + write(data->pipes[1], &in, sizeof(message)); + if(in.dest_id != ID_WILDCARD) + return; + } + + //printf("%d received message type %d\n", data->id, in.t); + + if(in.t == M_CONT){ + if(in.id != data->cont_id){ + fprintf(stderr, "Continuation message of an unknown source, dropping it"); + return; + } + if(in.t != data->cont_type){ + fprintf(stderr, "Continuation message of the wrong type, dropping it"); + return; + } + } + else{ + data->content_off = 0; + } + + data->r_buf = realloc(data->r_buf, data->content_off + in.content_size); + memcpy(data->r_buf, &in.content + data->content_off, in.content_size); + data->content_off += in.content_size; + + if(in.cont_id != -1){ // si ce n'est pas le dernier message + data->cont_id = in.cont_id; + data->cont_type = in.t; + return; + } + + switch(in.t){ + case M_REQUEST: + data->onRequest(u); + break; + + case M_CONT: + break; + + case M_RESPONSE: + data->onResponse(u); + break; + } +} + +void send_message(int pipe, int dest_id, void* content, int content_size, M_TYPE type){ + int id = abs(rand()); + for(int i = 0; i < content_size; i += M_SIZE){ + int chunk_size = MIN(M_SIZE, content_size - i); + message out = { + .t = type, + .id = id, + .dest_id = dest_id, + .content_size = chunk_size, + }; + memcpy(out.content, content + i, chunk_size); + if(chunk_size == M_SIZE){ + id = abs(rand()); + out.cont_id = id; + } + else out.cont_id = -1; + + write(pipe, &out, sizeof(out)); + } +} diff --git a/message.h b/message.h new file mode 100644 index 0000000000000000000000000000000000000000..391c7b058efa1e004b7d7b1abdb685ed0331d179 --- /dev/null +++ b/message.h @@ -0,0 +1,37 @@ +#pragma once + +#include "user.h" + +#define ID_WILDCARD -64 // ID special, tout les utilisateurs peuvent y repondre mais il vont quand meme le transmettre au suivants + +#define M_SIZE 64 + +typedef enum M_TYPE {M_REQUEST, M_CONT, M_RESPONSE} M_TYPE; + +typedef struct { + M_TYPE t; // type + int id; + int dest_id; // id de l'utilisateur destinataire du message + char content[M_SIZE]; + int content_size; + int cont_id; // id du message continuant celui-ci -1 si c'est le dernier +} message; + +#define R_CHUNK_SIZE 64 + +typedef void (*m_onRequest)(user_t* buf); +typedef void (*m_onResponse)(user_t* buf); + +struct receive_data { + int* pipes; + int id; + char * r_buf; + int cont_id; // id du prochain message attendu + M_TYPE cont_type; // type de message en cours de reception + int content_off; //offset de reception actuel + m_onRequest onRequest; + m_onResponse onResponse; +}; + +void receive_loop(user_t* data); +void send_message(int pipe, int dest_id, void* content, int content_size, M_TYPE type); diff --git a/request.h b/request.h new file mode 100644 index 0000000000000000000000000000000000000000..a4fc0e270c562ef49231aed9c55b81d41902acf8 --- /dev/null +++ b/request.h @@ -0,0 +1,33 @@ +#pragma once + +#define REQ_SIZE 64 + +typedef enum REQ_TYPE { + REQ_ID, // request d'id (sert a rien, juste un test) + REQ_CASE, // request si il y as un pion sur la case + REQ_PLAY, // demande a un joueur de jouer + REQ_DICE, // demande un lancer de de +} REQ_TYPE; + +typedef struct { + REQ_TYPE t; + int send_id; // id de l'emetteur de la requete +} request; + +typedef struct { + request parent; +} id_request; + +typedef struct { + request parent; + int case_nb; +} case_request; + +typedef struct { + request parent; +} play_request; + +typedef struct { + request parent; +} dice_request; + diff --git a/response.h b/response.h new file mode 100644 index 0000000000000000000000000000000000000000..bb6edf2536d12e140fdba5fdce309af9120b0970 --- /dev/null +++ b/response.h @@ -0,0 +1,28 @@ + +typedef enum RESP_TYPE {RESP_ID, RESP_CASE, RESP_PLAY, RESP_DICE} RESP_TYPE; + +typedef struct { + RESP_TYPE t; + int id; +} response; + +typedef struct { + response parent; + int id; +} id_response; + +typedef struct { + response parent; + int filled; + int player_id; +} case_response; + +typedef struct { + response parent; + int can; // boolean si le joueur a pu joueur (ex si il as besoin d'un lancer de avant de jouer) +} play_response; + +typedef struct { + response parent; + unsigned int nb; +} dice_response; diff --git a/user.c b/user.c index 63df118b6a5548c1dfd7b31dddfaca86c150acd6..acdeb442e01ea549b5814e9625b1f9b05e1ab717 100644 --- a/user.c +++ b/user.c @@ -2,9 +2,11 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> -#include <sys/param.h> #include "user.h" +#include "message.h" +#include "request.h" +#include "response.h" user_t user_init(unsigned int id, unsigned int nb_cheval, int pipes[], int start){ cheval_t cheval = { @@ -44,77 +46,6 @@ void user_loop(user_t* user){ receive_loop(user); } -void receive_loop(user_t* u){ - receive_data_t* data = u->r_data; - message in; - read(data->pipes[0], &in, sizeof(message)); - - if(in.dest_id != data->id || in.dest_id == ID_WILDCARD){ // si le message ne nous est pas destine on le passe au suivant de facon transparente - write(data->pipes[1], &in, sizeof(message)); - if(in.dest_id != ID_WILDCARD) - return; - } - - //printf("%d received message type %d\n", data->id, in.t); - - if(in.t == M_CONT){ - if(in.id != data->cont_id){ - fprintf(stderr, "Continuation message of an unknown source, dropping it"); - return; - } - if(in.t != data->cont_type){ - fprintf(stderr, "Continuation message of the wrong type, dropping it"); - return; - } - } - else{ - data->content_off = 0; - } - - data->r_buf = realloc(data->r_buf, data->content_off + in.content_size); - memcpy(data->r_buf, &in.content + data->content_off, in.content_size); - data->content_off += in.content_size; - - if(in.cont_id != -1){ // si ce n'est pas le dernier message - data->cont_id = in.cont_id; - data->cont_type = in.t; - return; - } - - switch(in.t){ - case M_REQUEST: - data->onRequest(u); - break; - - case M_CONT: - break; - - case M_RESPONSE: - data->onResponse(u); - break; - } -} - -void send_message(int pipe, int dest_id, void* content, int content_size, M_TYPE type){ - int id = abs(rand()); - for(int i = 0; i < content_size; i += M_SIZE){ - int chunk_size = MIN(M_SIZE, content_size - i); - message out = { - .t = type, - .id = id, - .dest_id = dest_id, - .content_size = chunk_size, - }; - memcpy(out.content, content + i, chunk_size); - if(chunk_size == M_SIZE){ - id = abs(rand()); - out.cont_id = id; - } - else out.cont_id = -1; - - write(pipe, &out, sizeof(out)); - } -} void user_onRequest(user_t* u){ request req; @@ -166,14 +97,13 @@ void user_onRequest(user_t* u){ .can = 0, }; - printf("%d : pret à jouer (de=%d / %d)\n", u->id, u->dice, &u->dice); if(u->dice == -1){ // si on as besoin d'un nouveau lancer de de - p_resp.can = 0; // on dis qu'on peut pas jouer - send_message(u->pipes[1], req.send_id, &p_resp, sizeof(p_resp), M_RESPONSE); - - request d_req = { .t = REQ_DICE, .send_id = u->id }; + request d_req = { .t = REQ_DICE, .send_id = u->id }; // on demande le de dice_request dc_req = { .parent = d_req }; send_message(u->pipes[1], req.send_id, &dc_req, sizeof(dc_req), M_REQUEST); + + p_resp.can = 0; // on dis qu'on peut pas jouer + send_message(u->pipes[1], req.send_id, &p_resp, sizeof(p_resp), M_RESPONSE); } else{ p_resp.can = 1; @@ -210,6 +140,20 @@ void user_onResponse(user_t* u){ } void user_play(user_t* user){ + int free_horse = 0; // si il y as au moins un cheval libre + for(int i = 0; i < user->nb_chevals; i++){ + if(!user->c[i].enclos) free_horse = 1; + } + + if(!free_horse){ + if(user->dice == 6){ + // TODO: on sort un cheval + } + else{ + // TODO: on repond qu'on ne peut pas jouer + } + user->dice = -1; + } printf("user %d pret à jouer\n", user->id); //user->dice = -1; // on invalide le lancer de de maintenant qu'on l'a utilise } \ No newline at end of file diff --git a/user.h b/user.h index a6b813ad7f56dec7eab92c2953860deca3533473..f960368661c2d930e495d86dc481a4fa509db105 100644 --- a/user.h +++ b/user.h @@ -1,4 +1,4 @@ -#define ID_WILDCARD -64 // ID special, tout les utilisateurs peuvent y repondre mais il vont quand meme le transmettre au suivants +#pragma once typedef struct { int pos; @@ -17,100 +17,13 @@ typedef struct { receive_data_t* r_data; } user_t; -#define M_SIZE 64 -typedef enum M_TYPE {M_REQUEST, M_CONT, M_RESPONSE} M_TYPE; -typedef struct { - M_TYPE t; // type - int id; - int dest_id; // id de l'utilisateur destinataire du message - char content[M_SIZE]; - int content_size; - int cont_id; // id du message continuant celui-ci -1 si c'est le dernier -} message; - -#define REQ_SIZE 64 - -typedef enum REQ_TYPE { - REQ_ID, // request d'id (sert a rien, juste un test) - REQ_CASE, // request si il y as un pion sur la case - REQ_PLAY, // demande a un joueur de jouer - REQ_DICE, // demande un lancer de de -} REQ_TYPE; - -typedef struct { - REQ_TYPE t; - int send_id; // id de l'emetteur de la requete -} request; - -typedef struct { - request parent; -} id_request; - -typedef struct { - request parent; - int case_nb; -} case_request; - -typedef struct { - request parent; -} play_request; - -typedef struct { - request parent; -} dice_request; - -typedef enum RESP_TYPE {RESP_ID, RESP_CASE, RESP_PLAY, RESP_DICE} RESP_TYPE; - -typedef struct { - RESP_TYPE t; - int id; -} response; - -typedef struct { - response parent; - int id; -} id_response; - -typedef struct { - response parent; - int filled; - int player_id; -} case_response; - -typedef struct { - response parent; - int can; // boolean si le joueur a pu joueur (ex si il as besoin d'un lancer de avant de jouer) -} play_response; - -typedef struct { - response parent; - unsigned int nb; -} dice_response; - -#define R_CHUNK_SIZE 64 - -typedef void (*m_onRequest)(user_t* buf); -typedef void (*m_onResponse)(user_t* buf); - -struct receive_data { - int* pipes; - int id; - char * r_buf; - int cont_id; // id du prochain message attendu - M_TYPE cont_type; // type de message en cours de reception - int content_off; //offset de reception actuel - m_onRequest onRequest; - m_onResponse onResponse; -}; user_t user_init(unsigned int id, unsigned int nb_cheval, int pipes[], int start); void user_loop(user_t* user); -void receive_loop(user_t* data); void user_play(user_t* user); -void send_message(int pipe, int dest_id, void* content, int content_size, M_TYPE type); void user_onRequest(user_t* data); void user_onResponse(user_t* data); \ No newline at end of file