Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <stdbool.h>
- #ifdef WIN32
- #define HAS_SOCKET
- #include <winsock2.h>
- #define close(s) closesocket(s)
- typedef int socket;
- typedef struct SOCKADDR_IN sockaddr_in;
- typedef struct SOCKADDR sockaddr;
- typedef struct IN_ADDR in_addr;
- #elif defined(linux)
- #define HAS_SOCKET
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <netdb.h>
- #define INVALID_SOCKET -1
- #define SOCKET_ERROR -1
- #endif
- /** Obtient une chaîne de caractères depuis l'entrée standard. Le
- * buffer doit être correctement alloué en mémoire avant l'appel.
- * @param buffer Pointeur sur le buffer.
- * @param buffer_size Taille du buffer en octet. */
- void get_string (char * buffer, size_t buffer_size)
- {
- fgets (buffer, buffer_size, stdin);
- char *ptr = strchr (buffer, '\n');
- if (ptr != NULL)
- *ptr = 0;
- else
- {
- char c;
- while ((c = getchar())!='\n' && c != EOF);
- }
- }
- /** Obtient un entier de 32 bits depuis l'entrée standard.
- * L'entier est interprété en représentation décimale.
- * @return Entier obtenu ou 0 en cas d'échec. */
- int get_int (void)
- {
- int integer = 0;
- char *buffer = malloc (11);
- char *endptr;
- if (buffer != NULL)
- {
- get_string (buffer, 11);
- errno = 0;
- integer = strtol (buffer, &endptr, 10);
- if (errno != 0)
- return integer;
- free (buffer);
- }
- return integer;
- }
- /** Obtient un caractère depuis l'entrée standard.
- * @return Caractère obtenu. */
- char get_char (void)
- {
- char c = getchar();
- while (getchar() != '\n');
- return c;
- }
- /** Structure représentant un noeud
- * de l'arbre. */
- typedef struct _Node
- {
- struct _Node **children;
- size_t child_n;
- struct _Node *parent;
- void *data;
- } Node;
- /** Crée un nouveau noeud.
- * @param data Pointeur sur les données.
- * @return Pointeur sur le nouveau noeud. */
- Node *node_new (void *data)
- {
- Node * node = (Node *)malloc (sizeof (*node));
- if (node != NULL)
- {
- node->children = NULL;
- node->child_n = 0;
- node->parent = NULL;
- node->data = data;
- }
- return node;
- }
- /** Libère la mémoire occupée par un noeud et
- * ses enfants.
- * @param node Pointeur sur le noeud. */
- void node_destroy (Node *node)
- {
- if (node != NULL)
- {
- int pos;
- for (pos=0; pos < node->child_n; pos++)
- node_destroy (node->children [pos]);
- if (node->children != NULL)
- free (node->children);
- free (node);
- }
- }
- /** Structure contenant un arbre
- * où chaque noeud possède un unique parent
- * mais une multitude d'enfants. */
- typedef struct _Tree Tree;
- struct _Tree
- {
- Node *root;
- };
- /** Crée un nouvel arbre dynamique.
- * @return Pointeur sur le nouvel arbre. */
- Tree *tree_new (void)
- {
- Tree *tree = (Tree *)malloc (sizeof (*tree));
- if (tree != NULL)
- {
- tree->root = NULL;
- }
- return tree;
- }
- /** Libère la mémoire occupée par l'arbre.
- * @param tree Pointeur sur l'arbre à libérer. */
- void tree_destroy (Tree *tree)
- {
- if (tree != NULL)
- {
- node_destroy (tree->root);
- free (tree);
- }
- }
- typedef struct _Menu Menu;
- typedef void (*Callback) (const Menu*, void *data);
- #define CALLBACK(func) (Callback)(func)
- typedef struct
- {
- const char *name;
- Callback callback;
- void *data;
- } Action;
- struct _Menu
- {
- const char *title;
- Action *actions;
- size_t action_n;
- unsigned int default_action;
- const Menu *parent;
- };
- Menu *menu_new (const char * title)
- {
- Menu *menu = (Menu *)malloc(sizeof (*menu));
- if (menu != NULL)
- {
- menu->title = title;
- menu->actions = NULL;
- menu->action_n = 0;
- menu->default_action = 0;
- menu->parent = NULL;
- }
- return menu;
- }
- void menu_add_action (Menu *menu, const char *entry, Callback callback, void *data)
- {
- menu->action_n++;
- menu->actions = (Action *)realloc (menu->actions, sizeof (Action)*menu->action_n);
- Action action = {entry, callback, data};
- size_t pos = menu->action_n - 1;
- menu->actions [pos] = action;
- }
- void menu_set_default_action (Menu *menu, unsigned int default_action)
- {
- if (default_action < menu->action_n)
- menu->default_action = default_action;
- }
- void menu_set_parent (Menu *menu, const Menu *parent)
- {
- menu->parent = parent;
- }
- void menu_exec (const Menu *menu)
- {
- printf ("\n%s\n", menu->title);
- int pos;
- for (pos=0; pos < menu->action_n; pos++)
- printf ("[%i]\t%s\t\n", pos+1, menu->actions [pos].name);
- if (menu->parent != NULL)
- printf ("[%i]\tRetour\t\n", ++pos);
- printf ("Entrez votre choix [1..%i](%i): ", pos, menu->default_action+1);
- fflush (stdout);
- int choice = get_int ()-1;
- if (choice >= -1 && choice < menu->action_n)
- {
- Callback callback = NULL;
- if (choice == -1 && menu->default_action < menu->action_n)
- callback = menu->actions [menu->default_action].callback;
- else if (choice >= 0)
- callback = menu->actions [choice].callback;
- if (callback != NULL)
- callback(menu, menu->actions [choice].data);
- }
- else if (choice == pos-1)
- menu_exec (menu->parent);
- else
- fprintf (stderr, "Entrée incorrecte :(\n");
- }
- void menu_sub_exec (const Menu *menu, void *data)
- {
- menu_exec ((const Menu *)(data));
- }
- void menu_destroy (Menu *menu)
- {
- if (menu != NULL)
- {
- if (menu->actions != NULL)
- free (menu->actions);
- free (menu);
- }
- }
- #define GRILLE_MAX_TAILLE 25
- #define GRILLE_MIN_TAILLE 6
- #define GRILLE_DEFAUT_TAILLE 7
- #define TAILLE_DU_NOM 256
- #define TAILLE_MAX_URL 256
- #define TAILLE_MSG_RES 5
- #define NOMBRE_DEFAUT_DE_JOUEURS 2
- #define NOMBRE_MAX_DE_JOUEURS 4
- #define PORT_SERVEUR_DEFAUT 4900
- typedef struct
- {
- char nom [TAILLE_DU_NOM];
- char jeton;
- bool avecIA;
- unsigned int score;
- } Joueur;
- enum {LOCAL, SERVEUR, CLIENT};
- typedef struct
- {
- /** Plateau du jeu. */
- int *grille;
- short int *remplissage;
- size_t largeur, hauteur;
- /** Joueurs. */
- Joueur joueurs [NOMBRE_MAX_DE_JOUEURS];
- size_t nombreDeJoueurs;
- /** Réseau. */
- int type;
- int sock;
- int *clientSocks;
- struct sockaddr_in *clientSins;
- unsigned int portServeur;
- bool finDuJeu;
- } Puissance4;
- typedef struct
- {
- size_t largeur, hauteur;
- char noms [NOMBRE_MAX_DE_JOUEURS][TAILLE_DU_NOM];
- size_t nombreDeJoueurs;
- } Puissance4Info;
- /** Initialise la structure Puissance4 avec
- * des valeurs par défaut. Configure une
- * partie avec deux joueurs humains sur une grilles
- * classique de puissance 4. */
- Puissance4 nouveauPuissance4 (void)
- {
- Puissance4 jeu;
- jeu.largeur = GRILLE_DEFAUT_TAILLE;
- jeu.hauteur = GRILLE_DEFAUT_TAILLE-1;
- jeu.grille = (int *)malloc(sizeof (*jeu.grille)*jeu.largeur*jeu.hauteur);
- jeu.remplissage = (short int *)malloc(sizeof (*jeu.remplissage)*jeu.largeur);
- jeu.nombreDeJoueurs = NOMBRE_DEFAUT_DE_JOUEURS;
- jeu.portServeur = PORT_SERVEUR_DEFAUT;
- jeu.type = LOCAL;
- char nomDuJoueur [TAILLE_DU_NOM];
- int pos;
- for (pos=0; pos < NOMBRE_MAX_DE_JOUEURS; pos++)
- {
- sprintf (nomDuJoueur, "Joueur %i", pos+1);
- strncpy (jeu.joueurs [pos].nom, nomDuJoueur, TAILLE_DU_NOM);
- jeu.joueurs [pos].jeton = 0x30 + pos + 1;
- jeu.joueurs [pos].avecIA = false;
- jeu.joueurs [pos].score = 0;
- }
- return jeu;
- }
- /** Libère la mémoire utilisée par le puissance 4. */
- void libererPuissance4 (Puissance4 *jeu)
- {
- if (jeu != NULL)
- {
- if (jeu->grille !=NULL)
- free (jeu->grille);
- if (jeu->remplissage != NULL)
- free (jeu->remplissage);
- }
- }
- /** Détermine si une case est dans la grille. */
- bool dansGrille (const Puissance4 *jeu, int x, int y)
- {
- return (x >= 0 && x < jeu->largeur &&
- y >= 0 && y < jeu->hauteur);
- }
- /** Détermine si un coup est possible ou non. */
- bool jouable (const Puissance4 *jeu, int x)
- {
- return (dansGrille(jeu, x, 0) &&
- jeu->remplissage[x] < jeu->hauteur);
- }
- /** Cherche un alignement de jeton à partir d'une
- * position donnée dans la grille. */
- unsigned int adjacent (const Puissance4 *jeu, int c, int l, int dirV, int dirH)
- {
- unsigned int nombreDeJetons = 0;
- int *jetonCourant = jeu->grille+c+l*jeu->largeur;
- int jetonDuJoueur = *jetonCourant;
- do
- {
- nombreDeJetons++;
- /** Incrémente le pointeur sur le jeton courant. */
- jetonCourant += dirV+dirH*jeu->largeur; c+=dirV; l+=dirH;
- /** Vérifie si le pointeur obtenu est valide et regarde
- * s'il s'agit bien d'un jeton du joueur courant. */
- } while(dansGrille(jeu, c,l) && *jetonCourant == jetonDuJoueur);
- return nombreDeJetons-1;
- }
- /** Détermine si la partie est finie ou pas. */
- bool partieEstGagneeOuPas (const Puissance4 *jeu, int c, int l)
- {
- int directions [][2] = {{0, 1}, {1, 0}, {1, 1}, {1, -1}};
- int pos;
- for (pos=0; pos < 4; pos++)
- {
- int dirV = directions [pos][0], dirH = directions [pos][1];
- unsigned int n1 = adjacent (jeu, c, l, dirV, dirH);
- unsigned int n2 = adjacent (jeu, c, l, -dirV, -dirH);
- if ((n1+n2+1) >= 4)
- return true;
- }
- return false;
- }
- /** Demande à l'utilisateur de saisir un coup à jouer. */
- unsigned int saisirCoup (const Puissance4 *jeu, const char *nom)
- {
- unsigned int x;
- do
- {
- printf ("Entrez le numéro de colonne %s [1-%i]: ", nom, jeu->largeur);
- x = get_int ();
- } while (!jouable (jeu, --x));
- return x;
- }
- /** Affiche une ligne de tirets pour séparer deux
- * lignes de la grille. */
- void afficherSeparateurDeLigne (unsigned int taille)
- {
- unsigned int x;
- for (x=0; x < taille; x++)
- printf ("+---");
- printf ("+\n");
- }
- /** Nettoye l'écran pour un meilleur affichage
- * de la grille. */
- void nettoyerEcran (void)
- {
- #ifdef WIN32
- system("cls");
- #else
- printf("\033[H\033[2J");
- #endif
- }
- /** Affiche la grille du jeu dans le terminal. */
- void afficherGrille (const Puissance4 *jeu)
- {
- nettoyerEcran();
- afficherSeparateurDeLigne (jeu->largeur);
- int x, y;
- for (y=jeu->hauteur-1; y >= 0; y--)
- {
- for (x=0; x < jeu->largeur; x++)
- {
- char str[] = "| ";
- const int valeur = *(jeu->grille+x+y*jeu->largeur);
- if (valeur >= 0 && valeur < NOMBRE_MAX_DE_JOUEURS)
- sprintf(str, "| %c ", jeu->joueurs [valeur].jeton);
- printf ("%s", str);
- }
- printf ("|\n");
- afficherSeparateurDeLigne (jeu->largeur);
- }
- /** Affiche une aide pour repérer le numéro des colonnes. */
- for (x=1; x <= jeu->largeur; x++)
- printf ("-%2i ", x);
- printf ("-\n");
- }
- /** Détermine si la grille est remplie ou non. */
- bool estRemplieOuNon (const Puissance4 *jeu)
- {
- int x;
- for (x=0; x < jeu->largeur; x++)
- if (jeu->remplissage [x] != jeu->hauteur-1)
- return false;
- return true;
- }
- /** Vide la grille de tous les jetons. */
- void nettoyerGrille (Puissance4 *jeu)
- {
- memset (jeu->grille, -1, sizeof (int)*jeu->largeur*jeu->hauteur);
- memset (jeu->remplissage, 0, sizeof (short int)*jeu->largeur);
- }
- /** Affiche le score de chaque joueur sous la forme
- * d'un tableau de deux colonnes. */
- void afficherScore (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- printf ("+------------+------------+\n");
- printf ("| Nom | Score |\n");
- printf ("+------------+------------+\n");
- int x;
- for (x=0; x < jeu->nombreDeJoueurs; x++)
- printf ("| %-11s| %-11i|\n", jeu->joueurs [x].nom, jeu->joueurs [x].score);
- printf ("+------------+------------+\n");
- }
- /** Lance une nouvelle partie de puissance 4.
- * Une fois la partie achevée les scores des joueurs sont affichés. */
- void lancerJeu (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- nettoyerGrille(jeu);
- afficherGrille(jeu);
- unsigned int tour = 0;
- while (!estRemplieOuNon (jeu))
- {
- Joueur *joueurCourant = &jeu->joueurs [tour%jeu->nombreDeJoueurs];
- unsigned int x = saisirCoup(jeu, joueurCourant->nom);
- unsigned int y = jeu->remplissage [x]++;
- *(jeu->grille+x+y*jeu->largeur) = tour%jeu->nombreDeJoueurs;
- afficherGrille(jeu);
- /** Vérifie si la partie n'est pas terminée. */
- if (partieEstGagneeOuPas (jeu,x,y))
- {
- printf ("Vous avez gagné %s!\n", joueurCourant->nom);
- joueurCourant->score++;
- break;
- }
- tour++;
- }
- afficherScore (menu, data);
- }
- /** Lance une partie en local. */
- void lancerPartieLocal (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- lancerJeu (menu, data);
- }
- /** Réceptionne le nom d'un client et l'enregistre
- * auprès du serveur. */
- void lireNomDuClient (Puissance4 *jeu, unsigned int pos)
- {
- /** Récupère le nom du joueur. */
- char nom[TAILLE_DU_NOM];
- unsigned int n;
- if ((n = recv(jeu->clientSocks [pos], nom, TAILLE_DU_NOM-1, 0)) >= 0)
- {
- nom[n] = '\0';
- strncpy (jeu->joueurs [pos+1].nom, nom, TAILLE_DU_NOM);
- printf ("%s a rejoint la partie.\n", nom);
- }
- else
- perror ("recv()");
- }
- /** Lance un serveur pour une partie en réseau. */
- void lancerServeur (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- jeu->type = SERVEUR;
- #ifdef HAS_SOCKET
- /** Tableaux contenant les sockets et les informations
- * sur les clients. */
- jeu->clientSocks = (int *)malloc(sizeof (*jeu->clientSocks)*(jeu->nombreDeJoueurs-1));
- jeu->clientSins = (struct sockaddr_in *)malloc(sizeof (*jeu->clientSins)*(jeu->nombreDeJoueurs-1));
- /** Création du socket pour le serveur. */
- jeu->sock = socket (AF_INET, SOCK_STREAM, 0);
- if (jeu->sock != INVALID_SOCKET)
- {
- struct sockaddr_in sin = {0};
- sin.sin_addr.s_addr = htonl (INADDR_ANY);
- sin.sin_family = AF_INET;
- sin.sin_port = htons (jeu->portServeur);
- if (bind (jeu->sock, (struct sockaddr *)&sin, sizeof (sin)) != SOCKET_ERROR)
- {
- Puissance4Info info;
- unsigned int joueurs;
- /** Mise en écoute sur le port jeu->portServeur. */
- if (listen (jeu->sock, jeu->nombreDeJoueurs-1) != SOCKET_ERROR)
- {
- /** Préparation des informations à transmettre
- * aux joueurs. */
- info.largeur = jeu->largeur;
- info.hauteur = jeu->hauteur;
- info.nombreDeJoueurs = jeu->nombreDeJoueurs;
- strncpy (info.noms [0], jeu->joueurs [0].nom, TAILLE_DU_NOM);
- printf ("En attente des autres joueurs... (%i)\n", jeu->nombreDeJoueurs-1);
- /** Attend que tous les clients soient connectés. */
- for (joueurs=0; joueurs < jeu->nombreDeJoueurs-1; joueurs++)
- {
- int csock;
- struct sockaddr_in csin = {0};
- socklen_t csocklen = sizeof (struct sockaddr_in);
- csock = accept (jeu->sock, (struct sockaddr *)&csin, &csocklen);
- /** Un nouveau client est accepté. */
- if (csock != INVALID_SOCKET)
- {
- jeu->clientSocks [joueurs] = csock;
- jeu->clientSins [joueurs] = csin;
- lireNomDuClient (jeu, joueurs);
- strncpy (info.noms [joueurs+1], jeu->joueurs [joueurs+1].nom,
- TAILLE_DU_NOM);
- }
- else
- perror ("accept()");
- }
- }
- /** Transmission des informations aux joueurs. */
- for (joueurs=0; joueurs < jeu->nombreDeJoueurs-1; joueurs++)
- if (send (jeu->clientSocks [joueurs], &info, sizeof (Puissance4Info), 0) < 0)
- perror ("send()");
- /** Une fois que tous les clients sont prêts, la partie est lancée. */
- lancerJeu (menu, data);
- }
- close (jeu->sock);
- }
- else
- perror ("socket()");
- /** Ferme les sockets des clients. */
- int pos;
- for (pos=0; pos < jeu->nombreDeJoueurs-1; pos++)
- close (jeu->clientSocks [pos]);
- free (jeu->clientSocks);
- free (jeu->clientSins);
- #endif /* HAS_SOCKET */
- jeu->type = LOCAL;
- }
- /** Envoie son nom au serveur. */
- void envoyerSonNomAuServeur (Puissance4 *jeu)
- {
- #ifdef HAS_SOCKET
- char nom [TAILLE_DU_NOM];
- do
- {
- printf ("Entrez votre nom: ");
- get_string (nom, TAILLE_DU_NOM);
- } while (strlen (nom) < 3);
- if (send (jeu->sock, nom, TAILLE_DU_NOM, 0) < 0)
- {
- perror ("send()");
- }
- #endif /* HAS_SOCKET */
- }
- /** Lance un client pour une partie en réseau. */
- void lancerClient (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- jeu->type = CLIENT;
- #ifdef HAS_SOCKET
- /** Demande l'url du serveur au joueur. */
- char hostname[TAILLE_MAX_URL];
- printf ("Entrez l'url du serveur: ");
- get_string (hostname, TAILLE_MAX_URL);
- /** Création du socket pour le serveur. */
- jeu->sock = socket (AF_INET, SOCK_STREAM, 0);
- if (jeu->sock != INVALID_SOCKET)
- {
- struct hostent *hostinfo = NULL;
- struct sockaddr_in sin = {0};
- /** Récupération des informations sur l'hôte. */
- hostinfo = gethostbyname (hostname);
- if (hostinfo != NULL)
- {
- sin.sin_addr = *(struct in_addr *)hostinfo->h_addr;
- sin.sin_port = htons (jeu->portServeur);
- sin.sin_family = AF_INET;
- /** Connexion au serveur. */
- printf ("Tentative de connexion à %s...\n", hostname);
- if (connect (jeu->sock, (struct sockaddr *)&sin, sizeof (struct sockaddr)) != SOCKET_ERROR)
- {
- printf ("Connexion établie.\n");
- envoyerSonNomAuServeur (jeu);
- /** Réception des informations sur la partie. */
- Puissance4Info info;
- if (recv (jeu->sock, &info, sizeof (Puissance4Info), 0) >= 0)
- {
- jeu->largeur = info.largeur;
- jeu->hauteur = info.hauteur;
- jeu->nombreDeJoueurs = info.nombreDeJoueurs;
- /** Récupère le nom des joueurs. */
- unsigned int joueurs;
- for (joueurs=0; joueurs < jeu->nombreDeJoueurs; joueurs++)
- strncpy (jeu->joueurs [joueurs].nom, info.noms [joueurs], TAILLE_DU_NOM);
- /** Redimensionne la grille. */
- lancerJeu (menu, data);
- }
- else
- perror ("recv()");
- }
- else
- fprintf (stderr, "Échec de la connexion.\n");
- }
- else
- fprintf (stderr, "L'hote %s est inconnu.\n", hostname);
- close (jeu->sock);
- }
- else
- perror ("socket()");
- #endif /* HAS_SOCKET */
- jeu->type = CLIENT;
- }
- /** Remet à zéro le score de tous les joueurs. */
- void reinitialiserLesScores (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- int pos;
- for (pos=0; pos < NOMBRE_MAX_DE_JOUEURS; pos++)
- jeu->joueurs [pos].score = 0;
- printf ("Les scores ont été remis à zéro.\n");
- }
- /** Change le nombre de joueurs dans la partie. */
- void changerNombreDeJoueurs (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- printf ("Entrez le nombre de joueurs [%i-%i]: ", NOMBRE_DEFAUT_DE_JOUEURS, NOMBRE_MAX_DE_JOUEURS);
- unsigned int nouveauNombreDeJoueurs = get_int();
- if (nouveauNombreDeJoueurs >= NOMBRE_DEFAUT_DE_JOUEURS &&
- nouveauNombreDeJoueurs <= NOMBRE_MAX_DE_JOUEURS)
- jeu->nombreDeJoueurs = nouveauNombreDeJoueurs;
- else
- fprintf (stderr, "Ce nombre de joueurs ne convient pas.\n");
- menu_exec (menu);
- }
- /** Demande de choisir un joueur afin de modifier
- * ses paramétres. */
- unsigned int choisirUnJoueur (const Puissance4 *jeu)
- {
- unsigned int n = 0;
- int pos;
- do
- {
- for(pos=0; pos < NOMBRE_MAX_DE_JOUEURS; pos++)
- {
- const char *statut = (pos < jeu->nombreDeJoueurs ) ? "Actif" : "Inactif";
- const char *typeDeJoueur = (jeu->joueurs [pos].avecIA) ? "IA" : "Humain";
- printf ("[%i]\t%-15s\t %-7s \t %-6s \n", pos+1,
- jeu->joueurs[pos].nom, statut, typeDeJoueur);
- }
- printf ("Choisissez le joueur que vous souhaitez modifier [1-%i]: ", pos);
- } while ((n=get_int ()-1) >= NOMBRE_MAX_DE_JOUEURS);
- return n;
- }
- /** Change le nom d'un des joueurs. La taille maximale
- * du nom est de 255 caractères. */
- void changerNomDuJoueur (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- unsigned int n = choisirUnJoueur (jeu);
- printf ("Entrez le nouveau nom de %s: ", jeu->joueurs [n].nom);
- char nouveauNom[TAILLE_DU_NOM];
- get_string (nouveauNom, TAILLE_DU_NOM);
- /** Vérifier si le nom n'est pas trop court. */
- if (strlen (nouveauNom) > 3)
- strncpy (jeu->joueurs [n].nom, nouveauNom, TAILLE_DU_NOM);
- else
- fprintf (stderr, "Le nom du joueur est trop court.\n");
- menu_exec (menu);
- }
- /** Activer ou désactiver l'IA sur un joueur. */
- void activerIADuJoueur (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- unsigned int n = choisirUnJoueur (jeu);
- printf ("Activer l'IA de %s [o/n]: ", jeu->joueurs[n].nom);
- char reponse = get_char ();
- jeu->joueurs[n].avecIA = (reponse == 'o') ? true : false;
- menu_exec (menu);
- }
- /** Demande un nouveau caractère pour symboliser le jeton
- * d'un joueur. */
- void choisirJetonDuJoueur (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- unsigned int n = choisirUnJoueur (jeu);
- printf ("Choisissez un jeton pour %s: ", jeu->joueurs [n].nom);
- char nouveauJeton = get_char();
- /** Vérifier si un autre joueur n'a pas déjà le même jeton. */
- bool jetonValide = true;
- int pos;
- for(pos=0; pos < NOMBRE_MAX_DE_JOUEURS; pos++)
- {
- if (jeu->joueurs [pos].jeton == nouveauJeton)
- {
- jetonValide = false;
- break;
- }
- }
- if (jetonValide)
- jeu->joueurs [n].jeton = nouveauJeton;
- else
- fprintf (stderr, "Le jeton est déjà pris par un autre joueur.\n");
- menu_exec (menu);
- }
- /** Redimensionne la grille avec
- * des valeurs entrées par l'utilisateur. */
- void redimensionnerGrille (const Menu *menu, void *data)
- {
- Puissance4 *jeu = (Puissance4 *)data;
- printf ("Entrez la largeur de la grille [%i-%i]: ", GRILLE_MIN_TAILLE, GRILLE_MAX_TAILLE);
- unsigned int largeur = get_int();
- printf ("Entrez la hauteur de la grille [%i-%i]: ", GRILLE_MIN_TAILLE, GRILLE_MAX_TAILLE);
- unsigned int hauteur = get_int();
- if (largeur > GRILLE_MIN_TAILLE && largeur < GRILLE_MAX_TAILLE &&
- hauteur > GRILLE_MIN_TAILLE && hauteur < GRILLE_MAX_TAILLE)
- {
- jeu->grille = (int *)realloc(jeu->grille, sizeof (*jeu->grille)*largeur*hauteur);
- jeu->remplissage = (short int *)realloc(jeu->remplissage, sizeof (*jeu->remplissage)*largeur);
- jeu->largeur = largeur; jeu->hauteur = hauteur;
- }
- else
- fprintf (stderr, "Taille incorrecte.\n");
- menu_exec (menu);
- }
- /** Affiche l'aide de l'application. */
- void aProposDe (void)
- {
- printf ("Ceci est un logiciel libre.\n");
- }
- /** Termine le programme. */
- void fermerJeu (const Menu *menu, void * data)
- {
- bool *fini = (bool *)data;
- *fini = true;
- }
- int main (void)
- {
- Puissance4 jeu = nouveauPuissance4 ();
- bool fini = false;
- #ifdef HAS_SOCKET
- #ifdef WIN32
- WSADATA wsa;
- int err = WSAStartup (MAKEWORD(2, 2), &wsa);
- #endif
- #endif
- Menu *menuJeuReseau = menu_new ("Jouer en réseau");
- menu_add_action (menuJeuReseau, "Héberger une partie", CALLBACK(lancerServeur), &jeu);
- menu_add_action (menuJeuReseau, "Rejoindre une partie", CALLBACK(lancerClient), &jeu);
- Menu *menuJeu = menu_new ("Jouer une partie");
- menu_add_action (menuJeu, "En local", CALLBACK(lancerPartieLocal), &jeu);
- #ifdef HAS_SOCKET
- menu_add_action (menuJeu, "En réseau", CALLBACK(menu_sub_exec), menuJeuReseau);
- #endif
- Menu *menuConfigJoueur = menu_new ("Configuration des joueurs");
- menu_add_action (menuConfigJoueur, "Nom d'un joueur", CALLBACK (changerNomDuJoueur), &jeu);
- menu_add_action (menuConfigJoueur, "Activer l'IA d'un joueur", CALLBACK (activerIADuJoueur), &jeu);
- menu_add_action (menuConfigJoueur, "Choisir le jeton d'un joueur", CALLBACK (choisirJetonDuJoueur), &jeu);
- Menu *menuConfig = menu_new ("Configuration");
- menu_add_action (menuConfig, "Nombre de joueurs", CALLBACK (changerNombreDeJoueurs), &jeu);
- menu_add_action (menuConfig, "Paramétrer les joueurs", CALLBACK (menu_sub_exec), menuConfigJoueur);
- menu_add_action (menuConfig, "Taille de la grille", CALLBACK(redimensionnerGrille), &jeu);
- Menu *menuPrincipal = menu_new("Bienvenue sur Puissance 4 !");
- menu_add_action (menuPrincipal, "Jouer", CALLBACK(menu_sub_exec), menuJeu);
- menu_add_action (menuPrincipal, "Voir les scores", CALLBACK(afficherScore), &jeu);
- menu_add_action (menuPrincipal, "Réinitialiser les scores", CALLBACK(reinitialiserLesScores), &jeu);
- menu_add_action (menuPrincipal, "Configurer", CALLBACK(menu_sub_exec), menuConfig);
- menu_add_action (menuPrincipal, "À propos de...", CALLBACK(aProposDe), NULL);
- menu_add_action (menuPrincipal, "Quitter", CALLBACK(fermerJeu), &fini);
- menu_set_parent (menuJeu, menuPrincipal);
- menu_set_parent (menuConfig, menuPrincipal);
- menu_set_parent (menuConfigJoueur, menuConfig);
- menu_set_parent (menuJeuReseau, menuJeu);
- do { menu_exec (menuPrincipal); } while (!fini);
- menu_destroy (menuJeuReseau);
- menu_destroy (menuJeu);
- menu_destroy (menuConfig);
- menu_destroy (menuConfigJoueur);
- menu_destroy (menuPrincipal);
- #ifdef HAS_SOCKET
- #ifdef WIN32
- WSACleanup();
- #endif
- #endif
- libererPuissance4(&jeu);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement