Parcourir la source

Import source code from old project

xayon40-12 il y a 4 ans
commit
c597b34ef5
42 fichiers modifiés avec 1495 ajouts et 0 suppressions
  1. 40 0
      TwoKobanClient/.gitignore
  2. 68 0
      TwoKobanClient/Flux/Client.cpp
  3. 54 0
      TwoKobanClient/Flux/Client.h
  4. 25 0
      TwoKobanClient/Flux/LecteurSSD.cpp
  5. 10 0
      TwoKobanClient/Flux/LecteurSSD.h
  6. 67 0
      TwoKobanClient/Flux/SpriteLoader.cpp
  7. 30 0
      TwoKobanClient/Flux/SpriteLoader.h
  8. 288 0
      TwoKobanClient/Niveau.cpp
  9. 48 0
      TwoKobanClient/Niveau.h
  10. BIN
      TwoKobanClient/Textures/bleu.bmp
  11. BIN
      TwoKobanClient/Textures/boutonA.bmp
  12. BIN
      TwoKobanClient/Textures/boutonR.bmp
  13. BIN
      TwoKobanClient/Textures/caisse.bmp
  14. BIN
      TwoKobanClient/Textures/end.bmp
  15. BIN
      TwoKobanClient/Textures/mur.bmp
  16. BIN
      TwoKobanClient/Textures/patientez.bmp
  17. BIN
      TwoKobanClient/Textures/porteF.bmp
  18. BIN
      TwoKobanClient/Textures/porteO.bmp
  19. BIN
      TwoKobanClient/Textures/rouge.bmp
  20. BIN
      TwoKobanClient/Textures/sol.bmp
  21. 98 0
      TwoKobanClient/Thread.cpp
  22. 36 0
      TwoKobanClient/Thread.h
  23. 2 0
      TwoKobanClient/config.txt
  24. 253 0
      TwoKobanClient/main.cpp
  25. 26 0
      TwoKobanClient/makefile
  26. 40 0
      TwokobanServeur/.gitignore
  27. 74 0
      TwokobanServeur/Methodes.cpp
  28. 11 0
      TwokobanServeur/Methodes.h
  29. 5 0
      TwokobanServeur/Niveaux/0index.txt
  30. 2 0
      TwokobanServeur/Niveaux/debug.txt
  31. 18 0
      TwokobanServeur/Niveaux/laby.txt
  32. 18 0
      TwokobanServeur/Niveaux/portal.txt
  33. 18 0
      TwokobanServeur/Niveaux/test.txt
  34. 90 0
      TwokobanServeur/Serveur.cpp
  35. 55 0
      TwokobanServeur/Serveur.h
  36. 93 0
      TwokobanServeur/main.cpp
  37. 26 0
      TwokobanServeur/makefile
  38. BIN
      TwokobanServeur/skins/Sans titre.xcf
  39. BIN
      TwokobanServeur/skins/bleu.bmp
  40. BIN
      TwokobanServeur/skins/caisse.bmp
  41. BIN
      TwokobanServeur/skins/caisse.xcf
  42. BIN
      TwokobanServeur/skins/rouge.bmp

+ 40 - 0
TwoKobanClient/.gitignore

@@ -0,0 +1,40 @@
+# Created by https://www.toptal.com/developers/gitignore/api/c++
+# Edit at https://www.toptal.com/developers/gitignore?templates=c++
+
+### C++ ###
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+# End of https://www.toptal.com/developers/gitignore/api/c++
+
+bin/

+ 68 - 0
TwoKobanClient/Flux/Client.cpp

@@ -0,0 +1,68 @@
+#include "Client.h"
+
+Client::Client(std::string IP, int port): m_IP(IP), m_port(port)
+{
+    m_csock.recsize = sizeof(m_csock.sin);
+    std::cout << "-°*,-Programme Client-,*°-" << std::endl;
+    std::cout << "Initialisation..." << std::endl;
+    #ifdef WIN32
+        m_erreur = WSAStartup(MAKEWORD(2,2), &m_WSAData);
+    #else
+        m_erreur = 0;
+    #endif // WIN32
+}
+
+Client::~Client()
+{
+    std::cout << "Fermeture de la socket client" << std::endl;
+    closesocket(m_csock.sock);
+    std::cout << "Fermeture du client termine" << std::endl;
+    #ifdef WIN32
+        WSACleanup();
+    #endif // WIN32
+}
+
+
+
+bool Client::rendreUtilisable()
+{
+    if(!m_erreur)
+    {
+        m_csock.sock = socket(AF_INET,SOCK_STREAM, 0);
+        if(m_csock.sock != INVALID_SOCKET)
+        {
+            std::cout << "La socket " << m_csock.sock << " est maintenant ouverte en mode TCP/IP" << std::endl;
+            m_csock.sin.sin_addr.s_addr = inet_addr(m_IP.c_str());
+            m_csock.sin.sin_family = AF_INET;
+            m_csock.sin.sin_port = htons(m_port);
+
+            if(connect(m_csock.sock, (SOCKADDR*)&m_csock.sin, m_csock.recsize) != SOCKET_ERROR)
+            {
+                std::cout << "Connection a " << inet_ntoa(m_csock.sin.sin_addr) << " sur le port " << htons(m_csock.sin.sin_port) << " reussie" << std::endl;
+            }
+            else
+                return false;
+        }
+        else
+            return false;
+    }
+    else
+        return false;
+    return true;
+}
+
+void Client::envoyer(void* donnee, int tailleByte)
+{
+    if(tailleByte != 0)
+        send(m_csock.sock, (char*)donnee, tailleByte, 0);
+    else
+        send(m_csock.sock, (char*)donnee, sizeof(donnee), 0);
+}
+
+void Client::recevoir(void* donnee, int tailleByte)
+{
+    if(tailleByte != 0)
+        recv(m_csock.sock, (char*)donnee, tailleByte, 0);
+    else
+        recv(m_csock.sock, (char*)donnee, sizeof(donnee), 0);
+}

+ 54 - 0
TwoKobanClient/Flux/Client.h

@@ -0,0 +1,54 @@
+#ifndef CLIENT_H_INCLUDED
+#define CLIENT_H_INCLUDED
+
+#ifdef WIN32
+    #include <winsock2.h>
+    typedef int socklen_t;
+#elif defined (linux)
+    #include <sys/types.h>
+    #include <sys/socket.h>
+    #include <netinet/in.h>
+    #include <arpa/inet.h>
+    #include <unistd.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;
+
+#endif // WIN32
+#include <iostream>
+
+struct Sock
+{
+    SOCKADDR_IN sin;
+    SOCKET sock;
+    socklen_t recsize;
+};
+
+class Client
+{
+public:
+    Client(std::string IP, int port);
+    ~Client();
+
+    bool rendreUtilisable();
+    void envoyer(void* donnee, int tailleByte);
+    void recevoir(void* donnee, int tailleByte);
+
+private:
+    #ifdef WIN32
+    WSADATA m_WSAData;
+    #endif
+
+    Sock m_csock;
+
+    std::string m_IP;
+    int m_port;
+    int m_erreur;
+};
+
+#endif // CLIENT_H_INCLUDED

+ 25 - 0
TwoKobanClient/Flux/LecteurSSD.cpp

@@ -0,0 +1,25 @@
+#include "LecteurSSD.h"
+
+Client* readConfig()
+{
+    std::string const source("config.txt");
+    std::ifstream fluxIn(source.c_str());
+
+    if (fluxIn)
+    {
+        //Ouverture fichier succés
+        std::string IP;
+        int port;
+
+        fluxIn >> IP;
+        fluxIn >> port;
+
+        return new Client(IP, port);
+    }
+    else
+    {
+        //Echec ouverture fichier
+        std::cout << "ERREUR: impossible de lire le fichier " << source << " ." << std::endl;
+        return 0;
+    }
+}

+ 10 - 0
TwoKobanClient/Flux/LecteurSSD.h

@@ -0,0 +1,10 @@
+#ifndef LECTEURSSD_H_INCLUDED
+#define LECTEURSSD_H_INCLUDED
+
+#include <iostream>
+#include <fstream>
+#include "Client.h"
+
+Client* readConfig();
+
+#endif // LECTEURSSD_H_INCLUDED

+ 67 - 0
TwoKobanClient/Flux/SpriteLoader.cpp

@@ -0,0 +1,67 @@
+#include "SpriteLoader.h"
+
+SpriteLoader::SpriteLoader() : m_folder("")
+{
+
+}
+
+SpriteLoader::SpriteLoader(std::string folder) : m_folder(folder)
+{
+
+}
+
+SpriteLoader::~SpriteLoader()
+{
+    for( m_it = m_paquet.begin(); m_it != m_paquet.end(); m_it++ )
+    {
+        SDL_FreeSurface(m_it->second);
+        m_it->second = 0x0;
+    }
+}
+
+SDL_Surface* SpriteLoader::takeSprite(std::string nom)
+{
+    // Cherche la surface dans le tableau
+    m_it = m_paquet.find(nom);
+
+    // Si la surface est déjà chargée, on la donne
+    if (m_it != m_paquet.end())
+        return m_it->second;
+
+    // Sinon on la charge
+    else
+    {
+        std::string source(m_folder + nom + ".bmp");
+        m_paquet[nom] = SDL_LoadBMP(source.c_str());
+        if (m_paquet[nom] == 0)
+        {
+            m_paquet[nom] = SDL_CreateRGBSurface(SDL_HWSURFACE, 40, 40, 32, 0, 0, 0, 0);
+            std::cout << "La texture " <<nom<< " n'a pas pu être chargée." << std::endl << std::endl;
+        }
+        else
+            std::cout << "La texture " <<nom<< " est maintenant chargée." << std::endl << std::endl;
+
+        return m_paquet[nom];
+    }
+}
+
+void SpriteLoader::addSprite(std::string nom, SDL_Surface* sprite)
+{
+    m_it = m_paquet.find(nom);
+    if (m_it == m_paquet.end())
+    {
+        m_paquet[nom] = sprite;
+        return;
+    }
+    else
+    {
+        std::cout << "Attention ! La texture " <<nom<< " a déjà une surface associée. Destruction de la nouvelle surface." << std::endl;
+        SDL_FreeSurface(sprite);
+    }
+}
+
+void SpriteLoader::assignFolder(std::string folder)
+{
+    m_folder = folder;
+}
+

+ 30 - 0
TwoKobanClient/Flux/SpriteLoader.h

@@ -0,0 +1,30 @@
+#ifndef SPRITELOADER_H_INCLUDED
+#define SPRITELOADER_H_INCLUDED
+
+#include <iostream>
+#include <string>
+#include <map>
+#include <SDL/SDL.h>
+#undef main
+
+class SpriteLoader
+{
+public:
+
+    SpriteLoader();
+    SpriteLoader(std::string folder);
+    ~SpriteLoader();
+
+    SDL_Surface* takeSprite(std::string nom);
+    void addSprite(std::string nom, SDL_Surface* sprite);
+    void assignFolder(std::string folder);
+
+private:
+
+    std::string m_folder;
+    std::map<std::string, SDL_Surface*>::iterator m_it;
+    std::map<std::string, SDL_Surface*> m_paquet;
+
+};
+
+#endif // SPRITELOADER_H_INCLUDED

+ 288 - 0
TwoKobanClient/Niveau.cpp

@@ -0,0 +1,288 @@
+#include "Niveau.h"
+
+Niveau::Niveau(SpriteLoader* spriteGet) : m_terrain(0), m_spriteGet(spriteGet)
+{
+    // Surface du terrain
+    m_terrain = SDL_CreateRGBSurface(SDL_HWSURFACE, 24*40, 18*40, 32, 0, 0, 0, 0);
+
+    // Remplissage tableau
+    for (Uint16 y(0); y < 18; y++)
+        for (Uint16 x(0); x < 24; x++)
+            m_tabl[y][x] = '#';
+
+    // Association noms aux chars
+    m_pass['#'] = "mur";
+    m_pass[' '] = "sol";
+    m_pass[36] = "end";//'$'
+
+    //Association couleurs lettres
+    Uint32 tab[26] = {0xffff0000, 0xff00ff00, 0x00ffff00, 0xff000000, 0x00ff0000, 0x0000ff00, 0xff770000, 0x00ff7700, 0x7700ff00, 0xff777700, 0x77ff7700, 0x7777ff00, 0x8c551500, 0xff00e000, 0x88880000, 0x88008800, 0x00888800, 0x2cb15800, 0x2cb15800, 0x008ebc00, 0x00bc5400, 0x6fbc0000, 0x6fbc0000, 0xff875200, 0xe56dff00, 0x00000000};
+    for(int i = 0;i<26;i++)
+        tabColor[i] = tab[i];
+
+    // Création des persos
+    m_perso[0].skin = m_spriteGet->takeSprite("bleu");
+    m_perso[1].skin = m_spriteGet->takeSprite("rouge");
+    m_perso[0].y = m_perso[1].y = 8;
+    m_perso[0].x = m_perso[1].x = 12;
+    SDL_SetColorKey(m_perso[0].skin, SDL_SRCCOLORKEY, 0xffffffff);
+    SDL_SetColorKey(m_perso[1].skin, SDL_SRCCOLORKEY, 0xffffffff);
+
+    //Création des
+    SDL_SetColorKey(m_spriteGet->takeSprite("boutonA"), SDL_SRCCOLORKEY, 0xff000000);
+    SDL_SetColorKey(m_spriteGet->takeSprite("boutonR"), SDL_SRCCOLORKEY, 0xff000000);
+    SDL_SetColorKey(m_spriteGet->takeSprite("porteO"), SDL_SRCCOLORKEY, 0xff000000);
+    SDL_SetColorKey(m_spriteGet->takeSprite("porteF"), SDL_SRCCOLORKEY, 0xff000000);
+}
+
+Niveau::~Niveau()
+{
+    SDL_FreeSurface(m_terrain);
+}
+
+void Niveau::majLevel(char newTerrain[18][24])
+{
+    // Nettoyage de la map
+    m_gates.clear();
+    for(unsigned int y = 0; y<18; y++) for(unsigned int x = 0; x<24; x++) m_caisses[y][x] = false;
+
+    // Balayage
+    for (Uint16 y(0); y < 18; y++)
+        for (Uint16 x(0); x < 24; x++)
+        {
+            // Valeur
+            m_tabl[y][x] = newTerrain[y][x];
+
+            // Pêche aux infos
+            if (m_tabl[y][x] == '0') {
+                m_perso[0].y = y;
+                m_perso[0].x = x;
+                m_tabl[y][x] = ' ';
+            }
+            if (m_tabl[y][x] == '1') {
+                m_perso[1].y = y;
+                m_perso[1].x = x;
+                m_tabl[y][x] = ' ';
+            }
+            if(m_tabl[y][x] == '*')
+            {
+                m_caisses[y][x] = true;
+                m_tabl[y][x] = ' ';
+            }
+
+            m_blitPos.x = x*40;
+            m_blitPos.y = y*40;
+            if(m_tabl[y][x] >= 97 && m_tabl[y][x] <= 122)//Minuscules
+            {
+                m_gates[m_tabl[y][x]].first = false;
+                m_gates[m_tabl[y][x]].second[0].push_back(x);
+                m_gates[m_tabl[y][x]].second[0].push_back(y);
+                SDL_BlitSurface(m_spriteGet->takeSprite(m_pass[' ']), 0, m_terrain, &m_blitPos);
+            }
+            else if(m_tabl[y][x] >= 65 && m_tabl[y][x] <= 90)//majuscules
+            {
+                m_gates[tolower(m_tabl[y][x])].second[1].push_back(x);
+                m_gates[tolower(m_tabl[y][x])].second[1].push_back(y);
+                SDL_BlitSurface(m_spriteGet->takeSprite(m_pass[' ']), 0, m_terrain, &m_blitPos);
+            }
+            else //blit si ce n'est ni porte ni bouton
+            {
+                SDL_BlitSurface(m_spriteGet->takeSprite(m_pass[m_tabl[y][x]]), 0, m_terrain, &m_blitPos);
+            }
+        }
+}
+
+void Niveau::afficher(SDL_Surface* screen)
+{
+    // Sol
+    SDL_BlitSurface(m_terrain, 0, screen, 0);
+
+    //affichage des potres/boutons ouvertes/fermées
+    SDL_Surface *tmpSurface;
+    for(std::map<char, std::pair<bool, std::vector<int>[2] > >::iterator tmp_gates = m_gates.begin(); tmp_gates!=m_gates.end(); tmp_gates++)
+    {
+        int index = (int)tmp_gates->first-97;
+        //boutons
+        tmpSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, 40, 40, 32, m_spriteGet->takeSprite("boutonA")->format->Rmask, m_spriteGet->takeSprite("boutonA")->format->Gmask, m_spriteGet->takeSprite("boutonA")->format->Bmask, m_spriteGet->takeSprite("boutonA")->format->Amask);
+        SDL_FillRect(tmpSurface, 0, tabColor[index]);
+        if(tmp_gates->second.first)
+            SDL_BlitSurface(m_spriteGet->takeSprite("boutonA"), 0, tmpSurface, 0);
+        else
+            SDL_BlitSurface(m_spriteGet->takeSprite("boutonR"), 0, tmpSurface, 0);
+        for(unsigned int i = 0;i<tmp_gates->second.second[0].size();i+=2)
+        {
+            m_blitPos.x = tmp_gates->second.second[0][i]*40;
+            m_blitPos.y = tmp_gates->second.second[0][i+1]*40;
+            SDL_SetColorKey(tmpSurface, SDL_SRCCOLORKEY, 0xffffff00);
+            SDL_BlitSurface(tmpSurface, 0, screen, &m_blitPos);
+        }
+        SDL_FreeSurface(tmpSurface);
+
+        //portes
+        tmpSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, 40, 40, 32, m_spriteGet->takeSprite("porteO")->format->Rmask, m_spriteGet->takeSprite("boutonA")->format->Gmask, m_spriteGet->takeSprite("boutonA")->format->Bmask, m_spriteGet->takeSprite("boutonA")->format->Amask);
+        SDL_FillRect(tmpSurface, 0, tabColor[index]);
+        if(tmp_gates->second.first)
+            SDL_BlitSurface(m_spriteGet->takeSprite("porteO"), 0, tmpSurface, 0);
+        else
+            SDL_BlitSurface(m_spriteGet->takeSprite("porteF"), 0, tmpSurface, 0);
+        for(unsigned int i = 0;i<tmp_gates->second.second[1].size();i+=2)
+        {
+            m_blitPos.x = tmp_gates->second.second[1][i]*40;
+            m_blitPos.y = tmp_gates->second.second[1][i+1]*40;
+            SDL_SetColorKey(tmpSurface, SDL_SRCCOLORKEY, 0xffffff00);
+            SDL_BlitSurface(tmpSurface, 0, screen, &m_blitPos);
+        }
+        SDL_FreeSurface(tmpSurface);
+    }
+
+    // Caisses
+    for (Uint16 y(0); y < 18; y++)
+        for (Uint16 x(0); x < 24; x++)
+            if (m_caisses[y][x])
+            {
+                m_blitPos.x = x*40;
+                m_blitPos.y = y*40;
+                SDL_BlitSurface(m_spriteGet->takeSprite("caisse"), 0, screen, &m_blitPos);
+            }
+
+    // Bonhommes
+    for (Uint16 i(0); i<=1; i++) {
+        m_blitPos.x = m_perso[i].x*40;
+        m_blitPos.y = m_perso[i].y*40;
+        SDL_BlitSurface(m_perso[i].skin, 0, screen, &m_blitPos);
+    }
+}
+
+bool Niveau::test(Uint16 y, Uint16 x, short dirX, short dirY)
+{
+
+    // Mur ?
+    if (m_tabl[y][x] == '#')
+        return false;
+
+    // Porte fermée ?
+    if(m_tabl[y][x] >= 65 && m_tabl[y][x] <= 90)
+        if (!m_gates[tolower(m_tabl[y][x])].first)
+            return false;
+
+    // Collisions caisse
+    if (m_caisses[y][x]) {
+        if(m_tabl[y+dirY][x+dirX] == '#')
+            return false;
+        if(m_tabl[y+dirY][x+dirX] >= 65 && m_tabl[y+dirY][x+dirX] <= 90)
+        {
+            if(m_gates[tolower(m_tabl[y+dirY][x+dirX])].first)
+            {
+                m_caisses[y][x] = false;
+                m_caisses[y + dirY][x + dirX] = true;
+                return true;
+            }
+            else
+                return false;
+        }
+        else
+        {
+            m_caisses[y][x] = false;
+            m_caisses[y + dirY][x + dirX] = true;
+            return true;
+        }
+    }
+
+    // Si rien n'empêche ...
+    return true;
+}
+
+char Niveau::getCase(Uint16 y, Uint16 x)
+{
+    if (y < 18 && x < 24)
+        return m_tabl[y][x];
+
+    return '#';
+}
+
+void Niveau::setCase(Uint16 y, Uint16 x, char bloc)
+{
+    if (y < 18 && x < 24)
+        m_tabl[y][x] = bloc;
+}
+
+bool Niveau::deplacer(char ID, char ordre)
+{
+    // Détermination du joueur qui bouge
+    Uint16 ind;
+    if (ID == '0') ind = 0;
+    else ind = 1;
+
+    // Détermination de la direction
+    short dirX(0), dirY(0);
+    switch (ordre)
+    {
+    case 24://'↑'
+        dirY--;
+        break;
+    case 25://'↓'
+        dirY++;
+        break;
+    case 26://'→'
+        dirX++;
+        break;
+    case 27://'←'
+        dirX--;
+        break;
+    default:
+        break;
+    }
+
+    // Collisions bonhomme
+    for(std::map<char, std::pair<bool, std::vector<int>[2] > >::iterator tmp_gates = m_gates.begin(); tmp_gates!=m_gates.end(); tmp_gates++)
+        for(unsigned int i = 0;i<tmp_gates->second.second[1].size();i+=2)
+            if(tmp_gates->second.second[1][i] == m_perso[ind].x && tmp_gates->second.second[1][i+1] == m_perso[ind].y)
+            {
+                if(tmp_gates->second.first)
+                    break;
+                else
+                    return false;
+            }
+    if (test(m_perso[ind].y+dirY, m_perso[ind].x+dirX, dirX, dirY)) {
+        m_perso[ind].y += dirY;
+        m_perso[ind].x += dirX;
+    }
+    return true;
+}
+
+void Niveau::updateBoutons()
+{
+    // Vérifie si un bouton est activé par une caisse A BOUGER
+    for(std::map<char, std::pair<bool, std::vector<int>[2] > >::iterator tmp_gates = m_gates.begin(); tmp_gates!=m_gates.end(); tmp_gates++)
+    {
+        tmp_gates->second.first = false;
+        for(unsigned int i = 0;i<tmp_gates->second.second[0].size();i+=2)
+            tmp_gates->second.first |= m_caisses[tmp_gates->second.second[0][i+1]][tmp_gates->second.second[0][i]];
+    }
+
+    // Vérifie perso on bouton
+    int x, y;
+    for (Uint16 i(0); i<=1; i++) {
+        x = m_perso[i].x;
+        y = m_perso[i].y;
+        if(m_tabl[y][x] >= 97 && m_tabl[y][x] <= 122)
+            m_gates[m_tabl[y][x]].first = true;
+    }
+
+    //destruction si caisse sur porte fermée
+    for(std::map<char, std::pair<bool, std::vector<int>[2] > >::iterator tmp_gates = m_gates.begin(); tmp_gates!=m_gates.end(); tmp_gates++)
+        for(unsigned int i = 0;i<tmp_gates->second.second[1].size();i+=2)
+            if(!tmp_gates->second.first && m_caisses[tmp_gates->second.second[1][i+1]][tmp_gates->second.second[1][i]])
+                m_caisses[tmp_gates->second.second[1][i+1]][tmp_gates->second.second[1][i]] = false;
+}
+
+bool Niveau::suisJeArrive(char ID)
+{
+     // Détermination du joueur qui bouge
+    Uint16 ind;
+    if (ID == '0') ind = 0;
+    else ind = 1;
+
+    // Retour
+    return (m_tabl[m_perso[ind].y][m_perso[ind].x] == 36);//'$'
+}

+ 48 - 0
TwoKobanClient/Niveau.h

@@ -0,0 +1,48 @@
+#ifndef NIVEAU_H
+#define NIVEAU_H
+
+#include <iostream>
+#include <SDL/SDL.h>
+#undef main
+#include <vector>
+#include "Flux/SpriteLoader.h"
+
+///Faire une fonction set pour modif tableau et image
+///Gérer les mvts de caisse
+///Améliorer les collisions : portes
+
+struct Perso
+{
+    Uint16 x;
+    Uint16 y;
+    SDL_Surface* skin;
+};
+
+class Niveau
+{
+    public:
+        Niveau(SpriteLoader* spriteGet);
+        ~Niveau();
+
+        void majLevel(char newTerrain[18][24]);
+        void afficher(SDL_Surface* screen);
+        bool test(Uint16 y, Uint16 x, short dirX, short dirY);
+        char getCase(Uint16 y, Uint16 x);
+        void setCase(Uint16 y, Uint16 x, char bloc);
+        bool deplacer(char ID, char ordre);
+        void updateBoutons();
+        bool suisJeArrive(char ID);
+
+    protected:
+        SDL_Surface* m_terrain;
+        SpriteLoader* m_spriteGet;
+        char m_tabl[18][24];//y;x
+        Perso m_perso[2];
+        std::map<char, std::string> m_pass;
+        SDL_Rect m_blitPos;
+        bool m_caisses[18][24];//y;x
+        std::map<char, std::pair<bool, std::vector<int>[2] > > m_gates;
+        Uint32 tabColor[26];
+};
+
+#endif // NIVEAU_H

BIN
TwoKobanClient/Textures/bleu.bmp


BIN
TwoKobanClient/Textures/boutonA.bmp


BIN
TwoKobanClient/Textures/boutonR.bmp


BIN
TwoKobanClient/Textures/caisse.bmp


BIN
TwoKobanClient/Textures/end.bmp


BIN
TwoKobanClient/Textures/mur.bmp


BIN
TwoKobanClient/Textures/patientez.bmp


BIN
TwoKobanClient/Textures/porteF.bmp


BIN
TwoKobanClient/Textures/porteO.bmp


BIN
TwoKobanClient/Textures/rouge.bmp


BIN
TwoKobanClient/Textures/sol.bmp


+ 98 - 0
TwoKobanClient/Thread.cpp

@@ -0,0 +1,98 @@
+#include "Thread.h"
+
+Thread::Thread(): m_isstop(true), m_autoDelete(false)
+{
+
+}
+Thread::~Thread()
+{
+    if(!m_isstop)
+    {
+        SDL_KillThread(m_t);
+        m_t = 0;
+    }
+    for(std::map<std::string, SDL_mutex*>::iterator mutex = m_mutexs.begin();mutex != m_mutexs.end();mutex++)
+        SDL_DestroyMutex(mutex->second);
+}
+bool Thread::start()
+{
+    if(m_isstop)
+    {
+        m_t = SDL_CreateThread(Thread::ThreadInit, this);
+        if(m_t != 0)
+        {
+            m_isstop = false;
+            return true;
+        }
+    }
+    return false;
+}
+void Thread::stop()
+{
+    if(!m_isstop)
+    {
+        SDL_KillThread(m_t);
+        m_t = 0;
+    }
+    m_isstop = true;
+}
+void Thread::join()
+{
+    SDL_WaitThread(m_t, 0);
+    m_isstop = true;
+}
+void Thread::setAutoDelete(bool autoDelete)
+{
+    m_autoDelete = autoDelete;
+}
+
+int Thread::ThreadInit(void* param)
+{
+    Thread *t(reinterpret_cast<Thread*>(param));
+    t->run();
+    if(t->m_autoDelete)
+        delete t;
+    return 0;
+}
+
+bool Thread::threadRunning()
+{
+    return m_isstop;
+}
+
+bool Thread::createLockMutex(std::string name)
+{
+    std::map<std::string, SDL_mutex*>::iterator mutex = m_mutexs.find(name);
+
+    if(m_mutexs.find(name) == m_mutexs.end())
+    {
+        m_mutexs[name] = SDL_CreateMutex();
+        mutex = m_mutexs.find(name);
+    }
+    if(SDL_mutexP(mutex->second)==-1)
+        return false;
+
+    return true;
+}
+bool Thread::lockMutex(std::string name)
+{
+    std::map<std::string, SDL_mutex*>::iterator mutex = m_mutexs.find(name);
+
+    if(m_mutexs.find(name) == m_mutexs.end())
+        return false;
+    if(SDL_mutexP(mutex->second)==-1)
+        return false;
+
+    return true;
+}
+bool Thread::unlockMutex(std::string name)
+{
+    std::map<std::string, SDL_mutex*>::iterator mutex = m_mutexs.find(name);
+
+    if(m_mutexs.find(name) == m_mutexs.end())
+        return false;
+    if(SDL_mutexV(mutex->second)==-1)
+        return false;
+
+    return true;
+}

+ 36 - 0
TwoKobanClient/Thread.h

@@ -0,0 +1,36 @@
+#ifndef THREAD_H
+#define THREAD_H
+
+#include <iostream>
+#include <map>
+#include <SDL/SDL_thread.h>
+
+class Thread
+{
+public:
+    Thread();
+    virtual ~Thread();// arrete automatiquement le thread meme si il est en cour
+    bool start();// demarre la fonction run() dans un thread
+    void stop();// arrete le thread
+    void join();// ratache la thread au processus principale qui est bloqué et attend que le run() se termine
+    void setAutoDelete(bool autoDelete);// permet de declarer dynamiquement une class qui herite de Thread sans garder le pointeur, il sera delete a la fin du thread si l'argument est true
+
+    bool threadRunning();
+
+    bool lockMutex(std::string name);
+    bool unlockMutex(std::string name);
+
+    virtual void run() = 0;// tout devra se passer ici
+
+protected:
+    bool createLockMutex(std::string name);
+
+private:
+    static int ThreadInit(void* param);
+    bool m_isstop;
+    SDL_Thread *m_t;
+    bool m_autoDelete;
+    std::map<std::string, SDL_mutex*> m_mutexs;
+};
+
+#endif // THREAD_H

+ 2 - 0
TwoKobanClient/config.txt

@@ -0,0 +1,2 @@
+127.0.0.1
+7856

+ 253 - 0
TwoKobanClient/main.cpp

@@ -0,0 +1,253 @@
+#include <iostream>
+#include <SDL/SDL.h>
+#undef main
+#include <cstdlib>
+#include <ctime>
+#include "Niveau.h"
+#include "Thread.h"
+#include "Flux/Client.h"
+#include "Flux/LecteurSSD.h"
+#include "Flux/SpriteLoader.h"
+
+class Patienter : public Thread
+{
+public:
+    Patienter(Client* lan, int* manage, char* IDMoi, char* IDLui): m_lan(lan), m_manage(manage), m_IDMoi(IDMoi), m_IDLui(IDLui)
+    {
+
+    }
+
+    void run()
+    {
+        if (m_lan != 0) {
+            if (!m_lan->rendreUtilisable()) {
+                std::cout << "Problème d'initialisation des connexions." << std::endl;
+                *m_manage = -1;
+                return;
+            }
+        }
+        else {
+            std::cout << "Problème de lecture de la configuration réseau." << std::endl;
+                *m_manage = -1;
+                return;
+        }
+
+        m_lan->recevoir(m_IDMoi, 1);
+        std::cout << "Votre identifiant est : " << *m_IDMoi << std::endl;
+        if (*m_IDMoi == '0') *m_IDLui = '1';
+        else *m_IDLui = '0';
+        *m_manage = 1;
+    }
+
+private:
+    Client* m_lan;
+    int *m_manage;
+    char *m_IDMoi, *m_IDLui;
+};
+
+int main ( int argc, char** argv )
+{
+    srand(time(0));
+    /// [1] Démarrage
+    // [1.1] Démarrages SDL
+    if ( SDL_Init( SDL_INIT_VIDEO ) < 0)
+    {
+        std::cout << "Impossible d'initialiser la SDL: " << SDL_GetError() << std::endl;
+        return 1;
+    }
+    putenv("SDL_VIDEO_CENTERED=1");
+
+    // [1.2] Préparation de fermeture
+    atexit(SDL_Quit);
+
+    // [1.3] Para-fenêtre
+    SDL_WM_SetCaption("Twokoban", 0);
+
+    /// [2] Préparation des composants
+    // [2.0] Variables
+    const char crash(197);//'┼'
+    const char loadLvl(9);//'○'
+    const char pasBouger(254);//'■'
+    const char fini(36);//'$'
+    const char reset(47);//'/'
+
+    char cmd(pasBouger), cmdLui(pasBouger);
+
+    // [2.1] Préparation du réseau
+    // [2.1.1] Fenetre d'attente
+    SDL_Surface* attente = SDL_SetVideoMode(400, 400, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
+    if ( !attente )
+    {
+        std::cout << "Inpossible de créer une fenêtre : " << SDL_GetError() << std::endl;
+        return 1;
+    }
+    SDL_Surface* imgattente = SDL_LoadBMP("Textures/patientez.bmp");
+    SDL_BlitSurface(imgattente, 0, attente, 0);
+    SDL_Flip(attente);
+    SDL_FreeSurface(imgattente);
+
+    // [2.1.2] initialisation du réseau
+    char octet;
+    int manage = 0;
+    Client* lan(0);
+    lan = readConfig();
+    char IDMoi, IDLui;
+
+    Patienter *p = new Patienter(lan, &manage, &IDMoi, &IDLui);
+    p->setAutoDelete(true);
+    p->start();
+
+    SDL_Event event;
+    while(!manage)
+    {
+        // [3.1] Gestion évènements
+        while (SDL_PollEvent(&event) && !manage)
+        {
+            switch (event.type)
+            {
+            case SDL_QUIT:
+                manage = -1;
+                break;
+            case SDL_KEYDOWN:
+                switch (event.key.keysym.sym)
+                {
+                case SDLK_ESCAPE:
+                    manage = -1;
+                default:
+                    break;
+                }
+                break;
+            } // end switch event type
+        } // end of message processing
+    }
+
+    // [2.1.3] disparition fenetre attente
+    SDL_FreeSurface(attente);
+
+    if(manage == -1)
+        return -1;
+
+    // [2.2] Préparation de la fenêtre
+    SDL_Surface* screen = SDL_SetVideoMode(40*24, 40*18, 32,
+                                           SDL_HWSURFACE|SDL_DOUBLEBUF);
+    if ( !screen )
+    {
+        std::cout << "Inpossible de créer une fenêtre : " << SDL_GetError() << std::endl;
+        return 1;
+    }
+
+    // [2.3] Préparation du gestionnaire de textures
+    SpriteLoader* spriteGet(0);
+    spriteGet = new SpriteLoader("Textures/");
+
+    // [2.4] Préparation du niveau
+    Niveau level(spriteGet);
+
+    /// [3] Boucle principale
+    bool done = false;
+    while (!done)
+    {
+        // [3.1] Gestion évènements
+        while (SDL_PollEvent(&event) && !done)
+        {
+            switch (event.type)
+            {
+            case SDL_QUIT:
+                done = true;
+                cmd = crash;
+                break;
+            case SDL_KEYDOWN:
+                switch (event.key.keysym.sym)
+                {
+                case SDLK_ESCAPE:
+                    done = true;
+                    cmd = crash;
+                    break;
+                case SDLK_UP:
+                    cmd = 24;
+                    break;
+                case SDLK_DOWN:
+                    cmd = 25;
+                    break;
+                case SDLK_RIGHT:
+                    cmd = 26;
+                    break;
+                case SDLK_LEFT:
+                    cmd = 27;
+                    break;
+                case SDLK_KP_DIVIDE:
+                    cmd = reset;
+                    break;
+                default:
+                    break;
+                }
+                break;
+            } // end switch event type
+        } // end of message processing
+
+        // [3.2] Réseau
+        lan->recevoir(&octet, 1);
+        switch (octet) // Exécution de la commande requise par le serveur
+        {
+        case loadLvl: // Recevoir le niveau
+            char lvlTmp[18][24];
+            for (Uint16 y(0); y < 18; y++)
+                for (Uint16 x(0); x < 24; x++) {
+                    lan->recevoir(&octet, 1);
+                    lvlTmp[y][x] = octet;
+                }
+            level.majLevel(lvlTmp);
+            std::cout << "Niveau reçu." << std::endl;
+            break;
+        case crash:
+            std::cout << "Le serveur a annoncé une erreur critique. Extinction préventive du programme." << std::endl;
+            done = true;
+            break;
+        default:
+            cmdLui = octet;
+            break;
+        }
+
+        if ( level.suisJeArrive(IDMoi) )
+        {
+            char fin = fini;
+            lan->envoyer(&fin, 1);
+        }
+        else
+        {
+            ///*****si crash, latence pour permetre un transfert fonctionnel***********
+            if(cmd==crash)
+                SDL_Delay(500);
+            ///************************************************************************
+            lan->envoyer(&cmd, 1);
+        }
+
+        // [3.3] Calculs
+        if(!level.deplacer(IDMoi, cmd))
+        {
+            lan->recevoir(&octet, 1);
+            cmd = reset;
+            lan->envoyer(&cmd, 1);
+        }
+        cmd = pasBouger;
+        level.deplacer(IDLui, cmdLui);
+        cmdLui = pasBouger;
+
+        level.updateBoutons();
+
+        // [3.4] Dessin des composants
+        level.afficher(screen);
+
+        SDL_Flip(screen);
+    } //fin bcl principale
+
+    ///[4] Destruction des composants
+    SDL_FreeSurface(screen);
+    delete lan;
+    delete spriteGet;
+
+    std::cout << "Aucune erreur détectée." << std::endl;
+    return 0;
+}
+
+

+ 26 - 0
TwoKobanClient/makefile

@@ -0,0 +1,26 @@
+CXX=g++
+CXXFLAGS=
+LDFLAGS=-lSDL -lSDL_image -lSDL_ttf
+INC=
+LIB=
+
+EXEC=twokobanclient
+SRC=$(shell find . -name '*.cpp') 
+OBJ=$(SRC:.cpp=.o)
+
+$(EXEC): $(OBJ)
+	@mkdir -p bin
+	$(CXX) -o bin/$@ $^ $(LDFLAGS) $(LIB)
+
+#TODO add .h in case of global variables
+%.o : %.cpp 
+	$(CXX) -o $@ -c $< $(CXXFLAGS) $(INC)
+	
+clean:
+	rm -rf $(OBJ)
+
+distclean: clean
+	rm -rf $(EXEC)
+
+exec: $(EXEC)
+	./bin/$(EXEC)

+ 40 - 0
TwokobanServeur/.gitignore

@@ -0,0 +1,40 @@
+# Created by https://www.toptal.com/developers/gitignore/api/c++
+# Edit at https://www.toptal.com/developers/gitignore?templates=c++
+
+### C++ ###
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+# End of https://www.toptal.com/developers/gitignore/api/c++
+
+bin/

+ 74 - 0
TwokobanServeur/Methodes.cpp

@@ -0,0 +1,74 @@
+#include "Methodes.h"
+
+std::string niveauSuivant(std::string index, std::string niveauPrecedant)
+{
+    std::ifstream flux(index.c_str());
+    std::string _niveauSuivant;
+    if(flux)
+    {
+        if(niveauPrecedant == "")
+        {
+            if(getline(flux, _niveauSuivant))
+                return _niveauSuivant.erase(0, 5);
+            else
+                return "";
+        }
+
+        bool trouver = false;
+        while(getline(flux, _niveauSuivant))
+        {
+            if(trouver)
+                return _niveauSuivant;
+            if(_niveauSuivant == niveauPrecedant)
+                trouver = true;
+        }
+        if(trouver)
+            save("Niveaux/0index.txt", niveauPrecedant);
+    }
+    return "";
+}
+bool chargerNiveau(char terrain[24*18], std::string chemin)
+{
+    std::ifstream flux(chemin.c_str());
+    if(flux)
+    {
+        for(int y = 0;y<18;y++)
+        {
+            std::string ligne = "";
+            if(!getline(flux, ligne))
+                std::cout << "ligne " << y+1 << ": raté" << std::endl;
+            for(unsigned int x = 0;x<24;x++)
+            {
+                if(x<ligne.size())
+                    terrain[x+y*24] = ligne[x];
+                else
+                    terrain[x+y*24] = '#';
+            }
+        }
+        return true;
+    }
+    return false;
+}
+void save(std::string index, std::string niveauActuel)
+{
+    std::ifstream iflux(index.c_str());
+    if(!iflux)
+        return;
+    std::string tmp, firstline, ligne;
+    //enlever ligne save:
+    getline(iflux, ligne);
+
+    //recuperer premiere ligne tout en la mettant dans tmp
+    getline(iflux, firstline);
+    tmp+=firstline+"\n";
+
+    while(getline(iflux, ligne))tmp+=ligne+"\n";
+    if(niveauActuel == ligne)
+        niveauActuel = firstline;
+    iflux.close();
+
+    std::ofstream oflux(index.c_str());
+    if(!oflux)
+        return;
+    oflux << "save:"+niveauActuel+"\n" << tmp;
+}

+ 11 - 0
TwokobanServeur/Methodes.h

@@ -0,0 +1,11 @@
+#ifndef METHODES_H_INCLUDED
+#define METHODES_H_INCLUDED
+
+#include <fstream>
+#include <iostream>
+
+std::string niveauSuivant(std::string index, std::string niveauPrecedant);
+bool chargerNiveau(char *terrain, std::string chemin);
+void save(std::string index, std::string niveauActuel);
+
+#endif // METHODES_H_INCLUDED

+ 5 - 0
TwokobanServeur/Niveaux/0index.txt

@@ -0,0 +1,5 @@
+save:laby.txt
+debug.txt
+test.txt
+portal.txt
+laby.txt

+ 2 - 0
TwokobanServeur/Niveaux/debug.txt

@@ -0,0 +1,2 @@
+###
+#$01

+ 18 - 0
TwokobanServeur/Niveaux/laby.txt

@@ -0,0 +1,18 @@
+########################
+#0* A   B e DC   f    G#
+###################### #
+#       p#    #i#  #g# #
+# # ######*#o    * IG* #
+# #* sSs*    #### ## # #
+#     ###    #j    #h  #
+######   ###K####  #####
+#J     #          #  Z #
+# ###############J# ## #
+# #kM  #m L   H #   z#$#
+# ###*  #*# #i# ########
+# #l nN     #I# g#     #
+# ########### # # *### #
+#P           O# F   E  #
+#################  #####
+#1  a   b   c         d#
+########################

+ 18 - 0
TwokobanServeur/Niveaux/portal.txt

@@ -0,0 +1,18 @@
+########################
+#c                    b#
+########D##########A####
+#            #         #
+#  ####      #         #
+#            #         #
+# a####    b #      ####
+#   *        #     #d  #
+#  #### ######      #B##
+#       #    AA        #
+#     1#      #####C####
+#######$#0   #         #
+#ABCD # ######   #######
+#######          # a   #
+#######      #   #     #
+#######  #   *   #     #
+#######e#        E     #
+########################

+ 18 - 0
TwokobanServeur/Niveaux/test.txt

@@ -0,0 +1,18 @@
+########################
+#$                     #
+#################C######
+#            #        c#
+#            #         #
+#      *     B         #
+#            #         #
+#            #         #
+#######A######    b    #
+#            #         #
+#            #         #
+#            #    a    #
+#            #         #
+#            #         #
+#0           #         #
+#            #         #
+#            # 1       #
+########################

+ 90 - 0
TwokobanServeur/Serveur.cpp

@@ -0,0 +1,90 @@
+#include "Serveur.h"
+
+Serveur::Serveur(int port, int nbrClient): m_port(port), m_nbrClient(nbrClient)
+{
+    #ifdef WIN32
+        m_erreur = WSAStartup(MAKEWORD(2,2), &m_WSAData);
+    #else
+        m_erreur = 0;
+    #endif // WIN32
+    m_sock.recsize = sizeof(m_sock.sin);
+
+    m_csock = new Sock[m_nbrClient];
+    for(int i = 0;i<m_nbrClient;i++)
+    {
+        m_csock[i].recsize = sizeof(m_csock[i].sin);
+    }
+
+}
+
+Serveur::~Serveur()
+{
+    #ifdef WIN32
+        WSACleanup();
+    #endif // WIN32
+    std::cout << "Fermeture des sockets clientes" << std::endl;
+    for(int i = 0;i<m_nbrClient;i++)
+        closesocket(m_csock[i].sock);
+    std::cout << "Fermeture de la socket serveur" << std::endl;
+    closesocket(m_sock.sock);
+    std::cout << "Fermeture du serveur termine" << std::endl;
+}
+
+
+bool Serveur::rendreUtilisable()
+{
+    if(!m_erreur)
+    {
+        m_sock.sock = socket(AF_INET, SOCK_STREAM, 0);// SOCK_STREAM pour TCP/IP, SOCK_DGRAM pour UDP/IP
+        if(m_sock.sock != INVALID_SOCKET)
+        {
+            std::cout << "La socket " << m_sock.sock << " est maintenant ouverte en mode TCP/IP" << std::endl;
+            m_sock.sin.sin_addr.s_addr = htonl(INADDR_ANY);
+            m_sock.sin.sin_family = AF_INET;
+            m_sock.sin.sin_port = htons(m_port);
+            if(bind(m_sock.sock, (SOCKADDR*)&m_sock.sin, m_sock.recsize) != SOCKET_ERROR)
+            {
+                std::cout << "Listage du port " << m_port << "..." << std::endl;
+                if(listen(m_sock.sock, 5) != SOCKET_ERROR)
+                {
+                    std::cout << "Patientez pendant que les " << m_nbrClient << " clients se connectent sur le port " << m_port << "..." << std::endl;
+                    for(int i = 0;i<m_nbrClient;i++)
+                    {
+                        m_csock[i].sock = accept(m_sock.sock, (SOCKADDR*)&m_csock[i].sin, &m_csock[i].recsize);// renvoi INVALID_SOCKET si il y a un probleme
+                        if(m_csock[i].sock != INVALID_SOCKET)
+                        {
+                            std::cout << "Un clien se connect avec la socket " << m_csock[i].sock << " de " << inet_ntoa(m_csock[i].sin.sin_addr) << " : " << htons(m_csock[i].sin.sin_port) << std::endl;
+                        }
+                        else
+                            return false;
+                    }
+                }
+                else
+                    return false;
+            }
+            else
+                return false;
+        }
+        else
+            return false;
+    }
+    else
+        return false;
+    return true;
+}
+
+void Serveur::envoyer(void* donnee, int indice, int tailleByte)
+{
+    if(tailleByte != 0)
+        send(m_csock[indice].sock, (char*)donnee, tailleByte, 0);
+    else
+        send(m_csock[indice].sock, (char*)donnee, sizeof(donnee), 0);
+}
+
+void Serveur::recevoir(void* donnee, int indice, int tailleByte)
+{
+    if(tailleByte != 0)
+        recv(m_csock[indice].sock, (char*)donnee, tailleByte, 0);
+    else
+        recv(m_csock[indice].sock, (char*)donnee, sizeof(donnee), 0);
+}

+ 55 - 0
TwokobanServeur/Serveur.h

@@ -0,0 +1,55 @@
+#ifndef SERVEUR_H_INCLUDED
+#define SERVEUR_H_INCLUDED
+#ifdef WIN32
+    #include <winsock2.h>
+    typedef int socklen_t;
+#elif defined (linux)
+    #include <sys/types.h>
+    #include <sys/socket.h>
+    #include <netinet/in.h>
+    #include <arpa/inet.h>
+    #include <unistd.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;
+
+#endif // WIN32
+#include <iostream>
+
+struct Sock
+{
+    SOCKADDR_IN sin;
+    SOCKET sock;
+    socklen_t recsize;
+};
+
+class Serveur
+{
+public:
+    Serveur(int port, int nbrClient);
+    ~Serveur();
+
+    bool rendreUtilisable();
+    void envoyer(void* donnee, int indice, int tailleByte);
+    void recevoir(void* donnee, int indice, int tailleByte);
+
+
+private:
+    #ifdef WIN32
+    WSADATA m_WSAData;
+    #endif
+
+    Sock m_sock;
+    Sock *m_csock;
+
+    int m_port;
+    int m_erreur;
+    const int m_nbrClient;
+};
+
+#endif // SERVEUR_H_INCLUDED

+ 93 - 0
TwokobanServeur/main.cpp

@@ -0,0 +1,93 @@
+#include <iostream>
+#include "Serveur.h"
+#include "Methodes.h"
+
+/**
+protocole de transfert:
+direction du perso: ↑→↓← (  alt24 à alt27 )
+si perso ne bouge pas: ■ ( alt254 )
+
+a faire: commande reset
+*/
+int main()
+{
+    ///creation du serveur
+    Serveur serveur(7856, 2);
+    if(!serveur.rendreUtilisable())
+    {
+        std::cout << "Erreur d'initialisation du serveur!" << std::endl;
+        return -1;
+    }
+
+    ///symboles envoyer = '○', fini = '$', arreter = '┼', bougePas = '■', reset = '/'
+    char envoyer = 9, fini = 36, arreter = 197, bougePas = 254, reset = 47;
+
+    ///attribution du numero du joueur
+    char id = '0';
+    serveur.envoyer(&id, 0, 1);
+    id = '1';
+    serveur.envoyer(&id, 1, 1);
+
+    /// attributs
+    bool continuer = true;
+    unsigned int taille = 1;
+    char joueur1 = bougePas, joueur2 = bougePas;
+    std::string cheminNiveau;
+    char niveau[18*24];
+    bool changerNiveau = true, isreset = false;
+
+    ///boucle evenementielle
+    while(continuer)
+    {
+        if(changerNiveau || isreset)
+        {
+            if(!isreset)
+                cheminNiveau = niveauSuivant("Niveaux/0index.txt", cheminNiveau);
+            else
+                isreset = false;
+            if(!chargerNiveau(niveau, "Niveaux/"+cheminNiveau))
+            {
+                std::cout << "Erreur de chargement du niveau : " << cheminNiveau << std::endl;
+                serveur.envoyer(&arreter, 0, taille);
+                serveur.envoyer(&arreter, 1, taille);
+                return -1;
+            }
+            else
+            {
+                serveur.envoyer(&envoyer, 0, taille);
+                serveur.envoyer(&envoyer, 1, taille);
+                for(int i = 0;i<18*24;i++)
+                {
+                    serveur.envoyer(&niveau[i], 0, taille);
+                    serveur.envoyer(&niveau[i], 1, taille);
+                }
+                changerNiveau = false;
+            }
+        }
+        else
+        {
+            serveur.envoyer(&joueur2, 0, taille);
+            serveur.envoyer(&joueur1, 1, taille);
+        }
+        serveur.recevoir(&joueur1, 0, taille);
+        serveur.recevoir(&joueur2, 1, taille);
+
+        if(joueur1 == arreter)
+        {
+            serveur.envoyer(&arreter, 1, taille);
+            save("Niveaux/0index.txt", cheminNiveau);
+            return 0;
+        }
+        else if(joueur2 == arreter)
+        {
+            serveur.envoyer(&arreter, 0, taille);
+            save("Niveaux/0index.txt", cheminNiveau);
+            return 0;
+        }
+        else if(joueur1 == fini && joueur2 == fini)
+            changerNiveau = true;
+        else if(joueur1 == reset || joueur2 == reset)
+            isreset  = true;
+    }
+    return 0;
+}

+ 26 - 0
TwokobanServeur/makefile

@@ -0,0 +1,26 @@
+CXX=g++
+CXXFLAGS=
+LDFLAGS=-lSDL -lSDL_image -lSDL_ttf
+INC=
+LIB=
+
+EXEC=twokobanserver
+SRC=$(shell find . -name '*.cpp') 
+OBJ=$(SRC:.cpp=.o)
+
+$(EXEC): $(OBJ)
+	@mkdir -p bin
+	$(CXX) -o bin/$@ $^ $(LDFLAGS) $(LIB)
+
+#TODO add .h in case of global variables
+%.o : %.cpp 
+	$(CXX) -o $@ -c $< $(CXXFLAGS) $(INC)
+	
+clean:
+	rm -rf $(OBJ)
+
+distclean: clean
+	rm -rf $(EXEC)
+
+exec: $(EXEC)
+	./bin/$(EXEC)

BIN
TwokobanServeur/skins/Sans titre.xcf


BIN
TwokobanServeur/skins/bleu.bmp


BIN
TwokobanServeur/skins/caisse.bmp


BIN
TwokobanServeur/skins/caisse.xcf


BIN
TwokobanServeur/skins/rouge.bmp