#include #include #include #include #include "sock.h" #include "sockdist.h" #include "partie.h" // Le jeu #include "position.h" #include "grille.h" // Grille #include //sprintf #include //strcmp #include #include //fenetres #include //fenetres #include //fenetres // ===== Variables ===== int numero; // numéro de joueur char saisie[256]; // saisies au clavier bool aurevoir; // pour la boucle char joueur_nom[10][256]; // Tableau des NOM de Joueurs int nb_joueurs = 0; // On gère 10 joueurs maxi. bool demarrage = false; // gere le commencement de la partie bool demarrage_jeu = false; // gere le commencement du jeu char action[256]; // Dernière action demandée par joueur ( pour gérer multi saisies) bool premier = false; // Passe à true si le joueur est le premier. bool mort = false; bool tour_de_jeu = true; // ===== Gestion des communications ===== int desc; int connection; int envoie; int reception; fd_set table; fd_set erreurs; int appel; int descfen1; int descfen2; int descfen3; // ===== Données échangées ===== int typercv; int typeenv; char msgenv[256]; char msgrcv[256]; // ===== Le jeu ===== Partie *p; Position* pos; //pour jouer un coup ///////////////////////////////////// ////// DIVERSES FONCTIONS ////// ///////////////////////////////////// /* Affichage */ void Affiche(char* t, int i){ switch (i) { case 0:{ cout << t << endl; break; } case 1:{ write(descfen1, t, strlen(t)); write(descfen1, "\n", 1); break; } case 2:{ write(descfen2, t, strlen(t)); write(descfen2, "\n", 1); break; } case 3:{ write(descfen3, t, strlen(t)); write(descfen3, "\n", 1); break; } } } /* Termine(joueur) */ void Termine(char* t){ Affiche(t, 0); // -1-message d'erreur Affiche(" Partie terminée ..." , 1); close(descfen1); // -2 bis-fermeture du descripteur de fenetre close(desc); // -2-ferme la connection avec le serveur exit(0); // -3-Fermeture } ///////////////////////////////////// ////// JOUEURS ///////// ///////////////////////////////////// /* Recoit_joueurs() */ void RecoitJoueurs(){ recv(desc, &nb_joueurs, sizeof(nb_joueurs), 0); //-1- recoit le nombre de joueurs de la partie for (int i = 0; i < nb_joueurs; i++){ recv(desc, &joueur_nom[i], sizeof(joueur_nom[i]), 0);//-2- recoit le nom de tous les joueurs } } /* ListeJoueurs */ void ListeJoueurs(){ Affiche(" Liste des joueurs : ", 1); Affiche(" --------------------", 1); char texte[256]; for (int i = 0; i < nb_joueurs; i++){ sprintf(texte, " %i -> %s", i, joueur_nom[i]); Affiche(texte, 1); } sprintf(texte, " %i -> Tous", nb_joueurs); Affiche(texte, 1); Affiche(" --------------------", 1); } ///////////////////////////////////// ////// CHAT ///////// ///////////////////////////////////// /*Affichage entete du Chat */ void AccueilChat(){ Affiche("\n ####################################", 1); Affiche(" # Demarrage de la page de chat ... #", 1); Affiche(" ####################################\n", 1); } /* Réception du message chat */ void RecoitChat(){ char latan[256]; recv(desc, &latan, sizeof(latan), 0); Affiche(latan, 1); } /* Envoi du message chat */ void EnvoitChat(char* t){ // On previent le serveur qu'un message chat arrive typeenv = 4; if(send(desc, &typeenv, sizeof(typeenv), 0)==-1) {Termine(" Erreur d'envoi ... ");} // Recherche du destinataire typeenv = (int)t[0] - int('0'); if(send(desc, &typeenv, sizeof(typeenv), 0)==-1) {Termine(" Erreur d'envoi ... ");} char message[256]; strcpy(message, t+2); // Affichage du message envoyé if (nb_joueurs!=typeenv) sprintf(msgenv, " %s -> %s", message, joueur_nom[typeenv]); else sprintf(msgenv, " %s -> Tous", message); Affiche(msgenv, 1); // Message sprintf(msgenv, " %s > %s", joueur_nom[numero], message); if(send(desc, &message, 256, 0)==-1) {Termine(" Erreur d'envoi ... ");} } ///////////////////////////////////// ////// MESSAGES ///////// ///////////////////////////////////// /* Accueil */ void Accueil(){ system("clear"); Affiche("\n ###################################################", 0); Affiche(" # Bienvenue sur le serveur de Bataille Navale ... #", 0); Affiche(" ###################################################\n", 0); } /* Menu */ void Menu(){ Affiche(" Menu ... ", 0); Affiche(" -------------------------", 0); Affiche(" Liste des joueurs -> dir ", 0); Affiche(" Jouer -> joue ", 0); Affiche(" Grille -> grille ", 0); Affiche(" Message -> chat ", 0); Affiche(" Quitter -> stop", 0); } ///////////////////////////////////// ////// GRILLE ///////// ///////////////////////////////////// /* RecoitGrille() */ void RecoitGrille(){ char temp[1000]; if(recv(desc, &temp, sizeof(temp),0)==-1) {Termine(" Erreur d'envoi ... ");} Affiche(temp, 3); } /* DemandeGrille() */ void DemandeGrille(int t){ typeenv = 5; if(send(desc, &typeenv, sizeof(typeenv), 0)==-1) {Termine(" Erreur d'envoi ... ");} // requete serveur if(send(desc, &t, sizeof(t), 0)==-1) {Termine(" Erreur d'envoi ... ");} // Numéro du joueur RecoitGrille(); // En attente des coordonnées de la grille adverse } /* EnvoieGrille() */ void EnvoieGrille(){ int dest; if(recv(desc, &dest, sizeof(dest), 0)==-1) {Termine(" Erreur d'envoi ... ");} // Numéro destinataire typeenv = 6; if(send(desc, &typeenv, sizeof(typeenv), 0)==-1) {Termine(" Erreur d'envoi ... ");} // requete au serveur if(send(desc, &dest, sizeof(dest), 0)==-1) {Termine(" Erreur d'envoi ... ");} //destinataire char dasso[1000]; // Grille strcpy(dasso, p->getGrille().VersChaine()); if(send(desc, &dasso, strlen(dasso)+1, 0)==-1) {Termine(" Erreur d'envoi ... "); } } ///////////////////////////////////// ////// COUPS ///////// ///////////////////////////////////// /* AnalyseCoup() */ void AnalyseCoup(){ if(recv(desc, &msgrcv, sizeof(msgrcv), 0)==-1) {Termine(" Erreur d'envoi ... ");} // coup joué char col = msgrcv[0]; int colonne = p->getGrille().transformation(col); int ligne = ((int)msgrcv[1] - int('0'))*10; ligne += (int)msgrcv[2] - int('0'); ligne -= 1; pos->setColonne(colonne); pos->setLigne(ligne); char res[2]; res[0] = p->result_attak(pos); res[1] = '\0'; //Envoie la réponse if(send(desc, &res, strlen(res)+1, 0)==-1) {Termine(" Erreur d'envoi ... ");} // requete au serveur if(p->fin_de_jeu()) { //il est mort Affiche("! Vous etes mort(e) !!! Toute votre flotte a sombré dans les abisses!",1); mort = true; typeenv = 8; if(send(desc, &typeenv, sizeof(typeenv), 0)==-1) {Termine(" Erreur d'envoi ... ");} // requete au serveur } } void JoueCoup(){ if(tour_de_jeu) { //Analyse de la chaine saisie char temp[256]; strcpy(temp,saisie+5); int num_joueur = (int)temp[0] - int('0'); char coup[256]; strcpy(coup,temp+2); // Controle de saisie char col = coup[0]; int colonne = p->getGrille().transformation(col); int ligne = ((int)coup[1] - int('0'))*10; ligne += (int)coup[2] - int('0'); ligne -= 1; if( ligne<0 || ligne>15 || colonne<0 || colonne>15 || num_joueur==numero || num_joueur==nb_joueurs) { Affiche("! Votre saisie n'est pas valide.",1); } else { tour_de_jeu = false; typeenv = 7; if(send(desc, &typeenv, sizeof(typeenv), 0)==-1) {Termine(" Erreur d'envoi ... ");} // requete au serveur if(send(desc, &num_joueur, sizeof(num_joueur), 0)==-1) {Termine(" Erreur d'envoi ... ");} //destinataire if(send(desc, &coup, strlen(coup)+1, 0)==-1) {Termine(" Erreur d'envoi ... ");} //coup joué Affiche(" Attente des autres joueurs ", 1); } } else {Affiche("! Veuillez attendre le prochain tour de jeu.S.V.P",1);} } ///////////////////////////////////// ////// PRINCIPAL ///////// ///////////////////////////////////// /* Programme principal */ void main(int agrc, char** argv){ // ===== Le Client ===== Sock maBr(SOCK_STREAM, short(2000)); //Boite Reseau locale desc = maBr.getsDesc(); //Descripteur de la BR // ===== Message d'Accueil ===== Accueil(); // ===== Adresse de l'hote ===== Affiche(" Adresse de l'hote : ", 0); cin.getline(saisie,256,'\n'); // ===== Le Serveur ===== SockDist BrDist(saisie, short(14415)); //Boite Reseau distante sockaddr_in* adrDist = BrDist.getAdrDist(); //La socket distante // ===== Connection aux autres fenetres descfen1 = open(argv[1], O_RDWR); if(descfen1==-1){Affiche(" Fenetre 1 absente... ", 0);} else {Affiche(" Fenetre 1 connectée ... ", 1);} descfen2 = open(argv[2], O_RDWR); if(descfen2==-1){Affiche(" Fenetre 2 absente... ", 0);} else {Affiche(" Fenetre 2 connectée ... ", 2);} AccueilChat(); descfen3 = open(argv[3], O_RDWR); if(descfen3==-1){Affiche(" Fenetre 3 absente... ", 0);} else {Affiche(" Fenetre 3 connectée ... ", 3);} // ===== Creation jeu ===== p = new Partie(descfen2); p->affiche(); pos = new Position(); // ===== Connection à la socket distante ===== connection = connect(desc, (sockaddr*)adrDist,sizeof(sockaddr)); if(connection == -1){Affiche(" Erreur de connection", 0);} else { // Nom du joueur Affiche(" Nom : ", 0); cin.getline(saisie,256,'\n'); sprintf(msgenv,"%s", saisie); envoie = send(desc, &msgenv, sizeof(msgenv), 0); if(envoie==-1) {Termine(" Erreur d'envoi ... ");} else{ while (true){ // Init de la table d'écoute + table erreurs FD_ZERO(&table); // BR publique FD_SET(desc, &table); // Entrée clavier FD_SET(0, &table); // Départ de l'écoute (blocante) appel = select(99999, &table, NULL, NULL, NULL); // Test si interruption clavier if (FD_ISSET(0, &table)) { cin.getline(saisie, 256,'\n'); if (strcmp(saisie,"stop")==0){Termine(" Au revoir...");} else if ((strcmp(saisie,"start")==0) && !demarrage&&premier){// ===== Envoi du signal de début ===== typeenv = 1; if(send(desc, &typeenv, sizeof(typeenv), 0)==-1) {Termine(" Erreur d'envoi ... ");} } else if ((strcmp(saisie,"dir")==0) && demarrage_jeu){// ===== liste des joueurs ===== Accueil(); ListeJoueurs(); Menu(); } else if ((strncmp(saisie,"joue",4)==0) && demarrage_jeu && !mort){// ===== un coup est joué ===== JoueCoup(); Accueil(); Menu(); } else if ((strncmp(saisie,"grille",6)==0) && demarrage_jeu){// ===== une grille est demandée ===== char temp[256]; strcpy(temp,saisie+7); int t = (int)temp[0] - int('0'); if (t == numero) p->affiche(); else if(t=0) DemandeGrille(t); if(demarrage_jeu){ Accueil(); Menu(); } } else if ((strncmp(saisie,"chat",4)==0)){// ===== un message est envoyé ===== char temp[256]; strcpy(temp,saisie+5); EnvoitChat(temp); if(demarrage_jeu){ Accueil(); Menu(); } } } // Test si interruption BR if (FD_ISSET(desc, &table)) { // ===== Reception type message ===== reception = recv(desc, &typercv, sizeof(typercv), 0); if (reception <= 0) {Termine(" La communication avec le serveur a échoué ...");} else { switch (typercv){ case 1:{ // Joueur accepté dans la partie //Reception numero joueur recv(desc, &numero, sizeof(numero), 0); Accueil(); Affiche(" Attente du début de partie ... ", 0); break; } case 2:{ // Joueur refusé Termine(" Joueur refusé par le serveur... "); break; } case 3:{ // Le joueur doit taper 'start' pour commencer premier = true; Accueil(); Affiche(" Taper 'start' pour commencer la partie", 0); break; } case 4:{ // Signal de début de partie demarrage = true; Accueil(); Affiche(" Positionnement des embarquations..." , 0); for (int i = 0; i<11; i++){ p->init(i); p->affiche(); } typeenv = 2; if(send(desc, &typeenv, sizeof(typeenv), 0)==-1) {Termine(" Erreur d'envoi ... ");} Affiche(" Attente des autres joueurs...", 1); break; } case 5:{ // Début du jeu demarrage_jeu = true; Accueil(); Affiche(" Le jeu vient de commencer !!!", 0); Menu(); break; } case 8:{ // Liste des joueurs RecoitJoueurs(); // Reception des noms de joueur if (!demarrage_jeu) ListeJoueurs(); break; } case 9:{ // Message chat RecoitChat(); // Reception du message break; } case 10:{ // Grille demandée EnvoieGrille(); break; } case 11:{ // Coup recu AnalyseCoup(); break; } case 12:{ // nouveau tour de jeu tour_de_jeu=true; Affiche("! Nouveau tour de jeu",1); break; } default :{ break; } } } } } } } }