Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Projet REVERSIA - Prog C Avancées - ING4SE - Promo 2021
- *
- * Valentin Brunet & Arthur DESUTTER
- *
- *
- *
- */
- /*Les lignes suivantes doivent être supprimées avant la compilation,
- * elles permettent à mon éditeur de code de charger les bonnes librairies pour l'autocomplétion
- */
- #ifndef MINGW32
- #define MINGW32
- #endif
- /*
- * Chargement des librairies
- */
- #include <stdlib.h>
- #include <sys/types.h>
- #ifdef MINGW32
- // Libraries for Windows
- #include<winsock2.h>
- #include <windows.h>
- #else
- // Libraries for Linux
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #define INVALID_SOCKET -1
- #define SOCKET_ERROR -1
- #define closesocket(s) close(s)
- typedef int SOCKET;
- typedef struct sockaddr_in SOCKADDR_IN;
- typedef struct sockaddr SOCKADDR;
- typedef struct in_addr IN_ADDR;
- #endif
- #include <string.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdbool.h>
- #include <string.h>
- // messages constants
- #define BUFFER_SIZE 1024
- #define PORT 8888
- #define IP_SERVER 137.74.113.61
- #define MAX_CLIENT 1
- #define BLACK_PLAYER 0x01
- #define WHITE_PLAYER 0x02
- #define NOK_RESPONSE 0x00
- #define OK_RESPONSE 0x01
- #define SYNCRO 0x55
- #define FIELDSIZE 8
- #define OKNOK_MESSAGE 0x02
- #define CONNECT_MESSAGE 0x01
- #define PLAYEROK_MESSAGE 0x10
- #define NEWMOVE_MESSAGE 0x03
- #define END_MESSAGE 0x04
- #define NEXTTURN_MESSAGE 0x05
- #define STATUS1_MESSAGE 0x06
- #define STATUS2_MESSAGE 0x07
- #define CONTROL_MESSAGE 0x08
- #define PING_MESSAGE 0x11
- //PERMET DE DEFINIR LES MESSAGES DE DEBUG QUE L'ON VEUT VOIR OU NON
- #define DEBUG_MESSAGE 1
- #define DEBUG_BUFFER 0
- #define DEBUG_SOCKET 0
- #define DEBUG_BOARD 0
- #define DEBUG_HEX_CONVERTER 0
- #define DEBUG_CONVERTER 0
- int run = 1;
- typedef struct
- {
- int port;
- char name;
- }Client;
- typedef struct
- {
- SOCKET sock;
- char name[BUFFER_SIZE];
- }Cliente;
- //STRCUTURE DES MESSAGES
- typedef struct
- {
- char type;
- int length;
- char *data;
- char valid_message;
- }Message;
- //STRUCTURE DU JEU
- typedef struct
- {
- char color;
- char **tab;
- int lig;
- int col;
- }Game;
- int eatPion(Game *game, int ligEmpty, int colEmpty, int ligPion, int colPion){
- int i = ligPion; int j = colPion;
- // Cas ou on est NOIR
- if (game->color == 'b')
- {
- // On cherche dans la direction qui convient, un pion de notre couleur
- // Si trouvé, on peut jouer en l(igEmpty ; colEmpty), sinon non
- int runLocal =1;
- while(runLocal){
- // On se déplace selon l'axe formé par l'emplacement vide et le pion adverse
- i += ligPion - ligEmpty; j += colPion - colEmpty;
- if(i >= 0 && j >= 0 && i < game->lig && j < game->col) {
- if(game->tab[i][j] == 'w'){
- } else {
- runLocal = 0;
- }
- } else {
- runLocal = 0;
- }
- }
- }
- // Cas ou on est BLANC
- else{
- int runLocal =1;
- while(runLocal){
- // On se déplace selon l'axe formé par l'emplacement vide et le pion adverse
- i += ligPion - ligEmpty; j += colPion - colEmpty;
- if(i >= 0 && j >= 0 && i < game->lig && j < game->col){
- if(game->tab[i][j] == 'b'){
- } else {
- runLocal = 0;
- }
- } else {
- runLocal = 0;
- }
- }
- }
- if(i>=game->lig || j>=game->col || i<0 || j<0){
- return 0;
- }
- if (game->tab[i][j] == game->color){
- return 1; // On peut jouer ici
- } else {
- return 0; // On ne peut pas jouer ici
- }
- }
- void valid_case(Game *game,int ** coordValid){
- for (int i = 0; i < game->col; ++i)
- {
- for (int j = 0; j < game->lig; ++j)
- {
- // Si case vide
- if(game->tab[i][j] == 'e'){
- // Si on est NOIR
- if (game->color == 'b')
- { // Parcout les 8 cases (max) autour, s'arrete si trouve un pion blanc
- for (int a = i-1; a < i+2; ++a) // on commence dans le coin en haut à gauche
- {
- for (int b = j-1; b < j+2; ++b)
- { // Test si on est pas hors de la grille
- if (a >= 0 && b >= 0 && a < game->lig && b < game->col)
- {
- if (game->tab[a][b] == 'w')
- {
- // fonction test si on peut manger des pions adverses (et donc jouer)
- if (eatPion(game, i,j,a,b) == 1)
- {
- coordValid[i][j] = 1;
- }
- }
- }
- }
- }
- }
- // Si on est BLANC
- else{
- // Parcout les 8 cases (max) autour, s'arrete si trouve un pion blanc
- for (int a = i-1; a < i+2; ++a) // on commence dans le coin en haut à gauche
- {
- for (int b = j-1; b < j+2; ++b)
- { // Test si on est pas hors de la grille
- if (a >= 0 && b >= 0 && a < game->lig && b < game->col)
- {
- if (game->tab[a][b] == 'b')
- {
- // fonction test si on peut manger des pions adverses (et donc jouer)
- if (eatPion(game, i,j,a,b) == 1)
- {
- coordValid[i][j] = 1;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- int getBestMove(Game *game, int * bestMove){
- int ** coordValid = malloc(game->col*sizeof(*coordValid));
- for(int i = 0; i < game->col; ++i){
- coordValid[i] = malloc(game->lig*sizeof(**coordValid));
- }
- for (int a = 0; a < game->col; a++)
- {
- for (int b = 0; b < game->lig; b++)
- {
- coordValid[a][b] = 0;
- }
- }
- valid_case(game, coordValid);
- if(DEBUG_BOARD){
- printf("\n");
- for (int a = 0; a < game->col; a++)
- {
- for (int b = 0; b < game->lig; b++)
- {
- printf("%d", coordValid[a][b]);
- }
- printf("\n");
- }
- }
- for (int a = 0; a < game->col; a++)
- {
- for (int b = 0; b < game->lig; b++)
- {
- if(coordValid[a][b] == 1){
- if(DEBUG_BOARD){
- printf("x: %d\ny: %d\nval: %d\n", a, b, coordValid[a][b]);
- }
- bestMove[0] = a;
- bestMove[1] = b;
- return 1;
- }
- }
- }
- return 0;
- }
- //FONCTION DONNEE DANS LE PROJET
- int init_connection(void){
- SOCKET sock_client;
- SOCKADDR_IN server;
- WSADATA wsa;
- #ifdef MINGW32
- // code for windows only
- printf("\nInitialising Winsock...");
- if(WSAStartup(MAKEWORD(2,2),&wsa) != 0)
- {
- printf("Failed. Error Code : %d",WSAGetLastError());
- return 1;
- }
- #endif
- //Create socket
- sock_client = socket(AF_INET, SOCK_STREAM, 0);
- if (sock_client == INVALID_SOCKET) {
- printf("Could not create socket");
- exit (EXIT_FAILURE);
- }
- puts("Client Socket created");
- // Define the socket remote address : 192.168.0.111:8888
- server.sin_addr.s_addr = inet_addr("127.0.0.1");
- server.sin_family = AF_INET;
- server.sin_port = htons(PORT);
- //Connect to remote server
- if (connect(sock_client, (SOCKADDR *) &server, sizeof(server)) < 0) {
- perror("connect failed. Error");
- exit (EXIT_FAILURE);
- }
- puts("Connected\n");
- return sock_client;
- }
- //PERMET DE NETTOYER LE BUFFER POUR N'AVOIR QUE DES 0 (USE ONLY FOR DEV - DEBUG SOCKET PROBLEM)
- void clearBuffer(char * buffer){
- int i;
- for(i=0; i<BUFFER_SIZE; i++){
- buffer[i] = 0;
- }
- }
- //PERMET D'AFFICHER LE BUFFER DE FACON BRUT
- void displayBuffer(char * buffer, int length){
- int i;
- printf("\nSTART OF BUFFER\n");
- for(i=0; i<length; i++){
- printf(" %X ", buffer[i]);
- }
- printf("\nEND OF BUFFER\n");
- }
- // function to convert
- // Hexadecimal to Binary Number
- void HexToBin(char hexNb, char* bin)
- {
- if(DEBUG_HEX_CONVERTER){
- printf("START HEX TO BIN ********************\n");
- printf("We are going to work with those value : \n");
- printf("%02X ", (unsigned int)(hexNb & 0xFF));
- }
- int i = 0;
- char hex[3];
- if(sprintf(hex, "%02X", (unsigned int)(hexNb & 0xFF)) > 0){
- if(DEBUG_HEX_CONVERTER){printf("\nCopy well done\n");}
- }else{
- if(DEBUG_HEX_CONVERTER){printf("\nerror copy\n");}
- }
- for(i=0; i<2; i++)
- {
- if(DEBUG_HEX_CONVERTER){printf("\nThe current conversion is on bit : %c \n", hex[i]);}
- if(hex[i] == '0'){
- strcat(bin, "0000");
- } else if (hex[i] == '1'){
- strcat(bin, "0001");
- } else if (hex[i] == '2'){
- strcat(bin, "0010");
- } else if (hex[i] == '3'){
- strcat(bin, "0011");
- } else if (hex[i] == '4'){
- strcat(bin, "0100");
- } else if (hex[i] == '5'){
- strcat(bin, "0101");
- } else if (hex[i] == '6'){
- strcat(bin, "0110");
- } else if (hex[i] == '7'){
- strcat(bin, "0111");
- } else if (hex[i] == '8'){
- strcat(bin, "1000");
- } else if (hex[i] == '9'){
- strcat(bin, "1001");
- } else if (hex[i] == 'A'){
- strcat(bin, "1010");
- } else if (hex[i] == 'B'){
- strcat(bin, "1011");
- } else if (hex[i] == 'C'){
- strcat(bin, "1100");
- } else if (hex[i] == 'D'){
- strcat(bin, "1101");
- } else if (hex[i] == 'E'){
- strcat(bin, "1110");
- } else if (hex[i] == 'F'){
- strcat(bin, "1111");
- } else {
- printf("Invalid hexadecimal input.\n");
- }
- }
- if(DEBUG_HEX_CONVERTER){
- puts(bin);
- printf("END HEX TO BIN ********************\n\n\n\n\n\n");
- }
- }
- char getContentFromDecodedHex(char a, char b){
- if(a == '0' && b == '0'){
- return 'e';
- } else if (a == '1' && b == '0') {
- return 'w';
- } else if (a == '0' && b == '1') {
- return 'b';
- }
- }
- //PERMET D'AFFICHER LE TYPE ET LE CONTENU DU MESSAGE
- void displayMessage(Message * recieved_message){
- int i;
- printf("\nSTART OF MESSAGE\n");
- printf("The type is : %X \n", recieved_message->type);
- printf("The data is : ");
- for(i=0; i<recieved_message->length; i++){
- printf(" %02X ", (unsigned int)(recieved_message->data[i] & 0xFF));
- }
- printf("\nEND OF MESSAGE\n");
- }
- void displayBoard(Game * game){
- int i,j;
- printf("\nThis is the game board :\n");
- for(i=0; i<game->col; i++){
- for(j=0; j<game->lig; j++){
- printf("%c", game->tab[i][j]);
- }
- printf("\n");
- }
- printf("\nEnd of the game board.");
- }
- //PERMET D'ENVOYER UN MESSAGE - DONNEE DANS LE PROJET
- void sendMessage(SOCKET sock, const char *ecrit, int nbOctet) {
- //Variables locales
- int l = 0;
- int fin;
- //En cas d'erreur lors de l'envoi
- if (send (sock, ecrit, nbOctet, 0) < 0)
- {
- printf ("Error : When sending new message\n");
- }
- //Affichage du message envoyé
- printf("Message sent : ");
- fin = (int) ecrit[1]+4;
- for (l = 0; l < fin ; l++) {
- printf(" %X ", ecrit[l]);
- }
- printf("\n");
- }
- void send_coord(SOCKET sock, int * bestMove){
- //Variables locales
- char message[100], server_reply[2000];
- int e, i, playerColor;
- char CRC = 0;
- // Create the "Connect Message"
- message[0] = SYNCRO; // Synchro
- message[1] = 2; // Message Length
- message[2] = NEWMOVE_MESSAGE; // Connect message
- message[3] = bestMove[1] & 0xff; // x
- message[4] = bestMove[0] & 0xff; // y
- message[5] = (NEWMOVE_MESSAGE + message[3] + message[4]) & 0xff;
- // Send "ok message" to the GM
- sendMessage(sock, message, 6);
- }
- void send_ok(SOCKET sock){
- //Variables locales
- char message[100], server_reply[2000];
- int e, i, playerColor;
- char CRC = 0;
- // Create the "Connect Message"
- message[0] = SYNCRO; // Synchro
- message[1] = 1; // Message Length
- message[2] = OKNOK_MESSAGE; // Connect message
- message[3] = OK_RESPONSE; // OK info
- message[4] = 0x03; //CRC
- // Send "ok message" to the GM
- sendMessage(sock, message, 5);
- }
- //PERMET D'ENVOYER LE MESSAGE DE CONNECTION - DONNE DANS LE PROJET
- int connect_message(SOCKET sock, char *name){
- //Variables locales
- char message[100], server_reply[2000];
- int e, i, playerColor;
- char CRC = 0;
- // Create the "Connect Message"
- message[0] = SYNCRO; // Synchro
- message[1] = strlen(name)+1; // Message Length
- message[2] = CONNECT_MESSAGE; // Connect message
- message[3] = strlen(name); // Name Length
- //Récupération du nom
- for(i=4; i < (strlen(name)+4); i++)
- message[i] = name[i-4];
- //Calcul du CRC lors du choix du nom
- for (e = 2; e < (strlen(name)+4); e++)
- CRC += message[e];
- message[strlen(name)+4] = CRC;
- // Send "connect message" to the GM
- sendMessage(sock, message, (strlen(name)+5));
- }
- //PERMET DE RECEVOIR UN MESSAGE
- Message* readMessage(SOCKET sock) {
- //on alloue un nouveau message
- Message *received_message = (Message *) malloc(sizeof (Message));
- received_message->valid_message = 0;
- //on alloue le buffer pour recevoir le message
- char buffer[BUFFER_SIZE];
- if(DEBUG_SOCKET){
- clearBuffer(buffer);
- }
- int status, i;
- status = recv (sock, buffer, BUFFER_SIZE, 0);
- if (status < 0) //En cas d'erreur lors de la reception
- {
- printf ("Error : When reading new message\n");
- perror("read");
- } else if (status == 0){ //En cas de deconnection du serveur
- printf ("Error : peer disconnected\n");
- run = 0;
- } else {
- //Affichage du buffer
- if(DEBUG_BUFFER){
- displayBuffer(buffer, status);
- }
- //Enregistrement du message reçu
- received_message->length = buffer[1];
- received_message->type = buffer[2];
- received_message->data = (char *)malloc(received_message->length * sizeof(char));
- for(i=3; i<received_message->length+3; i++){
- received_message->data[i-3] = buffer[i];
- }
- received_message->valid_message = 1;
- }
- return received_message; //on renvoi le pointeur du message
- }
- //inet_addr
- int main(int argc, char *argv[]) {
- //DECLARATION DES VARIABLES
- char decoded_hex[9];
- int i, j, indexData, resultOfModulo, ret;
- int * bestMove = (int *)malloc(2*sizeof(int));
- Game * game = (Game *)malloc(sizeof(Game));
- Message *received_message;
- SOCKET sock_client = init_connection();
- bestMove[0] = 0;
- bestMove[1] = 0;
- //ON SE CONNECTE AU SERVEUR VIA LA FONCTION DONNEE DANS LE SUJET
- connect_message(sock_client, argv[1]);
- //ON AFFICHE NOTRE NOM
- printf("You are : %s \n", argv[1]);
- //ON ENTRE DANS LA BOUCLE DE JEU
- while(run){
- //ON ATTEND UN NOUVEAU MESSAGE
- received_message = readMessage(sock_client);
- if(received_message->valid_message){ // ON S'ASSURE QUE LE MESSAGE EST BON
- //ON AFFICHE LE MESSAGE DU SERVEUR
- if(DEBUG_MESSAGE){
- displayMessage(received_message);
- }
- /*
- #define OKNOK_MESSAGE 0x02
- #define CONNECT_MESSAGE 0x01
- #define NEWMOVE_MESSAGE 0x03
- #define END_MESSAGE 0x04
- */
- switch(received_message->type){
- case PLAYEROK_MESSAGE : //MESSAGE DE COULEUR
- printf("\nVous jouez avec la couleur :");
- if(received_message->data[0] == 0x01){
- game->color = 'b';
- printf(" Black\n");
- } else if(received_message->data[0] == 0x02){
- game->color = 'w';
- printf(" White\n");
- }
- break;
- case NEXTTURN_MESSAGE :
- printf("It's your turn now !\n");
- game->lig = received_message->data[2];
- game->col = received_message->data[3];
- game->tab = (char **)malloc(game->col * sizeof(char*));
- for(i=0; i<game->lig; i++){
- game->tab[i] = (char *)malloc(game->lig * sizeof(char));
- }
- indexData = -1;
- for(i = 0; i < game->col; i++){
- for(j = 0; j < game->lig; j++){
- //chaque case de data fait 4 case de tab donc on augmente la variable indexData tous les 4 tours
- if(j == 0 || j == 4){
- indexData++;
- strcpy(decoded_hex, "");
- HexToBin(received_message->data[indexData+4], decoded_hex);
- }
- if(j == 0 || j == 4){
- if(DEBUG_CONVERTER){
- printf("i: %d - j:%d - %c%c - ", i, j, decoded_hex[0], decoded_hex[1]);
- printf("%c\n", getContentFromDecodedHex(decoded_hex[0], decoded_hex[1]));
- }
- //on prend les 2 premiers bits
- game->tab[i][j] = getContentFromDecodedHex(decoded_hex[0], decoded_hex[1]);
- } else if(j == 1 || j == 5){
- if(DEBUG_CONVERTER){
- printf("i: %d - j:%d - %c%c - ", i, j, decoded_hex[2], decoded_hex[3]);
- printf("%c\n", getContentFromDecodedHex(decoded_hex[2], decoded_hex[3]));
- }
- //on prend les 2 bits d'après
- game->tab[i][j] = getContentFromDecodedHex(decoded_hex[2], decoded_hex[3]);
- } else if(j == 2|| j == 6){
- if(DEBUG_CONVERTER){
- printf("i: %d - j:%d - %c%c - ", i, j, decoded_hex[4], decoded_hex[5]);
- printf("%c\n", getContentFromDecodedHex(decoded_hex[4], decoded_hex[5]));
- }
- //on prend les 2 bits avant derniers
- game->tab[i][j] = getContentFromDecodedHex(decoded_hex[4], decoded_hex[5]);
- } else if(j == 3 || j == 7){
- if(DEBUG_CONVERTER){
- printf("i: %d - j:%d - %c%c - ", i, j, decoded_hex[6], decoded_hex[7]);
- printf("%c\n", getContentFromDecodedHex(decoded_hex[6], decoded_hex[7]));
- }
- //on prend les 2 dernier bits
- game->tab[i][j] = getContentFromDecodedHex(decoded_hex[6], decoded_hex[7]);
- } else {
- printf("ERROR WHEN DECODE DATA");
- }
- }
- if(DEBUG_CONVERTER){
- printf("\n\n");
- }
- }
- displayBoard(game);
- printf("let's find a move\n");
- if(getBestMove(game, bestMove)){
- printf("We want to play this : {%d;%d}\n", bestMove[0], bestMove[1]);
- send_coord(sock_client, bestMove);
- } else {
- printf("We can't play !\n");
- bestMove[0] = -1;
- bestMove[1] = -1;
- send_coord(sock_client, bestMove);
- }
- break;
- case PING_MESSAGE:
- printf("SERVER ASK IF I'M HERE !");
- send_ok(sock_client);
- break;
- case END_MESSAGE : //MESSAGE END
- run = 0;
- printf("Server stop the game, go sleep !");
- break;
- default :
- //code
- break;
- }
- }
- free(received_message); //le message ne nous servira plus, on libere de l'espace
- }
- close(sock_client);
- sleep(60);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement