diff --git a/src/controleur/ControleurPartie.java b/src/controleur/ControleurPartie.java index 80598f2..42b8aa2 100644 --- a/src/controleur/ControleurPartie.java +++ b/src/controleur/ControleurPartie.java @@ -14,11 +14,16 @@ public class ControleurPartie { private ControleurReseau controleurReseau; private ModeDeJeu modeDeJeu; - public ControleurPartie(Partie partie, Vue vue, ControleurReseau controleurReseau, ModeDeJeu modeDeJeu) { + public ControleurPartie(Partie partie, Vue vue, ControleurReseau CR, ModeDeJeu modeDeJeu) { this.partie = partie; this.vue = vue; - this.controleurReseau = controleurReseau; + this.controleurReseau = CR; this.modeDeJeu = modeDeJeu; + + // On lie ce ControleurPartie au ControleurReseau + if (controleurReseau != null) { + controleurReseau.setControleurPartie(this); + } } public void lancerPartie(){ @@ -27,14 +32,14 @@ public class ControleurPartie { System.out.println("===============================\n"); - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"Mode de jeu : " + modeDeJeu); - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"Joueurs : " + partie.getJoueurBlanc().getNom() + " (Blancs) vs " + partie.getJoueurNoir().getNom() + " (Noirs)"); - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"Les pions Noirs sont en bas. Les pions Blancs sont en haut. \n"); + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"Mode de jeu : " + modeDeJeu); + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"Joueurs : " + partie.getJoueurBlanc().getNom() + " (Blancs) vs " + partie.getJoueurNoir().getNom() + " (Noirs)"); + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"Les pions Noirs sont en bas. Les pions Blancs sont en haut. \n"); - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"------- La Partie commence ! -------"); + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"------- La Partie commence ! -------"); vue.afficherPlateau(partie.getPlateau()); //System.out.print("\n"); - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"C'est au tour de " + partie.getJoueurActif().getNom() + " de jouer."); + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"C'est au tour de " + partie.getJoueurActif().getNom() + " de jouer."); boucleDeJeu(); vue.setTour(partie.getJoueurActif().getNom()); vue.setScore(partie.getScore()); @@ -51,21 +56,57 @@ public class ControleurPartie { vue.afficherPlateau(partie.getPlateau()); if(dernierCoup != null) { - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"Dernier coup : " + joueurPrecedent.getNom() + " a joué " + dernierCoup); + vue.afficherMessage(TypeMessage.SYSTEME_WARN,"Dernier coup : " + joueurPrecedent.getNom() + " a joué " + dernierCoup); + + // Envoi du coup au serveur si le controleurReseau est initialisé + if (controleurReseau != null) { + controleurReseau.envoyerCoup(dernierCoup, joueurPrecedent.getNom()); + } } - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"\nC'est au tour de " + partie.getJoueurActif().getNom() + " de jouer."); + + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"\nC'est au tour de " + partie.getJoueurActif().getNom() + " de jouer."); vue.setTour(partie.getJoueurActif().getNom()); vue.setScore(partie.getScore()); } catch (IllegalArgumentException e) { - vue.afficherMessage(TypeMessage.SYSTEMEROUGE,"> Erreur : " + e.getMessage()); + vue.afficherMessage(TypeMessage.SYSTEME_ERR,"> Erreur : " + e.getMessage()); } } - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"La partie est terminée !"); - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"Si vous souhaitez rejouer, relancez le programme."); - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"Si vous souhaitez voir l'historique des coups taper 1. Si vous souhaitez voir les captures taper 2."); - vue.afficherMessage(TypeMessage.SYSTEMEBLEU,"Merci d'avoir joué !"); + //Fin de la partie + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"La partie est terminée !"); + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"Si vous souhaitez rejouer, relancez le programme."); + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"Si vous souhaitez voir l'historique des coups taper 1. Si vous souhaitez voir les captures taper 2."); + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"Merci d'avoir joué !"); + } + + // Coup reçu depuis le reseau + public void joueCoupReseau(Coup coup){ + try { + partie.jouerCoup(coup); // Applique le coup + vue.setDernierCoup(coup); // Met à jour le dernier coup + vue.afficherPlateau(partie.getPlateau()); // Affiche le plateau + + vue.afficherMessage(TypeMessage.SYSTEME_WARN, + "Dernier coup : " + partie.getJoueurActif().getNom() + " a joué " + coup); // Affiche le dernier coup + + vue.setTour(partie.getJoueurActif().getNom()); // Met à jour le tour + vue.setScore(partie.getScore()); // Met à jour le score + } catch (IllegalArgumentException e) { + vue.afficherMessage(TypeMessage.SYSTEME_ERR,"> Erreur en appliquant un coup reseau : " + e.getMessage()); + } + } + // Fin de la partie + public void finPartieReseau(String message){ + vue.afficherMessage(TypeMessage.SYSTEME_INFO,"Fin de la partie en reseau : " + message); + } + + public void afficherChat(String auteur, String message){ + vue.afficherMessage(TypeMessage.CHAT, auteur + ": " + message); + } + + public void afficherMessageSysteme(String message){ + vue.afficherMessage(TypeMessage.SYSTEME_INFO, message); } } diff --git a/src/controleur/ControleurReseau.java b/src/controleur/ControleurReseau.java index ce145d4..6cd9cd6 100644 --- a/src/controleur/ControleurReseau.java +++ b/src/controleur/ControleurReseau.java @@ -1,5 +1,112 @@ package controleur; +import modele.Coup; +import reseau.*; + public class ControleurReseau { - -} + private final boolean isServer; // Vrai si on joue en tant que serveur + private Client client; // si joueur rejoint une partie + private Serveur serveur; // si joueur héberge une partie + private ControleurPartie controleurPartie; // Logique du jeu (plateau, règles, etc.) + + public ControleurReseau(boolean isServer){ + this.isServer = isServer; + } + + public void setControleurPartie(ControleurPartie controleurPartie){ + this.controleurPartie = controleurPartie; + } + + // Initialisation du serveur + public void demarrerServeur(int port) throws Exception{ + serveur = new Serveur(port); + serveur.setControleur(this); // Branchement du controleur réseau au serveur + serveur.demarrer(); + } + + // Initialisation du client + public void demarrerClient(String host, int port) throws Exception{ + client = new Client(host, port); + client.setControleur(this); // Branchement du controleur réseau au client + client.connecter(); + } + + public void arreter() throws Exception{ + if (isServer) { + serveur.arreter(); + } else { + client.deconnecter(); + } + } + + // Emission + public void envoyerDemandePartie(String joueur) { + envoyer(new MessageJeu(TypeMessage.DEMANDE_DE_PARTIE, joueur, "Demande de partie", null)); + } + + public void envoyerCoup(Coup coup, String joueur) { + envoyer(new MessageJeu(TypeMessage.MOUVEMENT, joueur, null, coup)); + } + + public void envoyerChat(String joueur, String texte) { + envoyer(new MessageJeu(TypeMessage.CHAT, joueur, texte, null)); + } + + public void envoyerSysteme(String texte, TypeMessage type) { + envoyer(new MessageJeu(type, "SYSTEME", texte, null)); + } + public void envoyerFin(String texte, TypeMessage type) { + envoyer(new MessageJeu(type, "SYSTEME", texte, null)); + } + + private void envoyer(MessageJeu msg) { + try { + if (isServer && serveur != null) { + serveur.envoyerMessageAuClient(msg); + } else if (!isServer && client != null) { + client.envoyerMessage(msg); + } + } catch (Exception e) { + onSysteme("Erreur d’envoi : " + e.getMessage()); + } + } + + + + // --- Réception (appelé par Serveur/Client) --- + public void onDemandePartie(String auteur) { + onSysteme("Demande de partie de " + auteur); + // Ici, le serveur peut accepter ou refuser + if (isServer && controleurPartie != null) { + controleurPartie.lancerPartie(); + } + } + + public void onMouvement(Coup coup) { + onSysteme("Coup reçu : " + coup); + if (controleurPartie != null) { + controleurPartie.joueCoupReseau(coup); + } + } + + public void onChat(String auteur, String texte) { + System.out.println("Chat [" + auteur + "]: " + texte); + if (controleurPartie != null) { + controleurPartie.afficherChat(auteur, texte); + } + } + + public void onSysteme(String texte) { + System.out.println("[SYSTEME] " + texte); + if (controleurPartie != null) { + controleurPartie.afficherMessageSysteme(texte); + } + } + + public void onFinPartie(String texte) { + System.out.println("[FIN] " + texte); + if (controleurPartie != null) { + controleurPartie.finPartieReseau(texte); + } + } +} \ No newline at end of file diff --git a/src/modele/Partie.java b/src/modele/Partie.java index e4baaf1..18822eb 100644 --- a/src/modele/Partie.java +++ b/src/modele/Partie.java @@ -34,14 +34,14 @@ public class Partie{ public void jouerTour() { // Logique pour jouer un tour Coup coup = joueurActif.jouerCoup(plateau); + jouerCoup(coup); + + } + + public void jouerCoup(Coup coup) { + // Logique pour jouer un coup Piece piece = plateau.getCase((int)coup.getOrigine().getX(), (int)coup.getOrigine().getY()).getPiece(); - // System.out.println(""); - // System.out.println("Origine du coup : " + coup.getOrigine()); - // System.out.println("Destination du coup : " + coup.getDestination()); - // System.out.println("Contenu de la case d'origine : " + plateau.getCase(coup.getOrigine()).getPiece().getSymbole()); - - if(piece == null) { throw new IllegalArgumentException("Aucune pièce à la position d'origine."); } @@ -78,7 +78,6 @@ public class Partie{ ajouterCoup(coup); // Changer de joueur changerJoueur(); - } public boolean estFini() { diff --git a/src/out/controleur/ControleurPartie.class b/src/out/controleur/ControleurPartie.class index 7f1d115..2e05636 100644 Binary files a/src/out/controleur/ControleurPartie.class and b/src/out/controleur/ControleurPartie.class differ diff --git a/src/out/controleur/ControleurReseau.class b/src/out/controleur/ControleurReseau.class index 721ee56..0a6b980 100644 Binary files a/src/out/controleur/ControleurReseau.class and b/src/out/controleur/ControleurReseau.class differ diff --git a/src/out/modele/Coup.class b/src/out/modele/Coup.class index 0a82ef7..cc9adb6 100644 Binary files a/src/out/modele/Coup.class and b/src/out/modele/Coup.class differ diff --git a/src/out/modele/Partie.class b/src/out/modele/Partie.class index 75b17d5..f8fd330 100644 Binary files a/src/out/modele/Partie.class and b/src/out/modele/Partie.class differ diff --git a/src/out/reseau/Client$1.class b/src/out/reseau/Client$1.class new file mode 100644 index 0000000..5dd82d0 Binary files /dev/null and b/src/out/reseau/Client$1.class differ diff --git a/src/out/reseau/Client.class b/src/out/reseau/Client.class index 0fff62b..999bfec 100644 Binary files a/src/out/reseau/Client.class and b/src/out/reseau/Client.class differ diff --git a/src/out/reseau/MessageJeu.class b/src/out/reseau/MessageJeu.class index cd8fdee..8c7de53 100644 Binary files a/src/out/reseau/MessageJeu.class and b/src/out/reseau/MessageJeu.class differ diff --git a/src/out/reseau/Serveur$1.class b/src/out/reseau/Serveur$1.class new file mode 100644 index 0000000..f19b423 Binary files /dev/null and b/src/out/reseau/Serveur$1.class differ diff --git a/src/out/reseau/Serveur.class b/src/out/reseau/Serveur.class index d0b5b16..25319f4 100644 Binary files a/src/out/reseau/Serveur.class and b/src/out/reseau/Serveur.class differ diff --git a/src/out/reseau/TypeMessage.class b/src/out/reseau/TypeMessage.class index 61d5edb..00687eb 100644 Binary files a/src/out/reseau/TypeMessage.class and b/src/out/reseau/TypeMessage.class differ diff --git a/src/out/vue/VueGraphiqueSwing$1.class b/src/out/vue/VueGraphiqueSwing$1.class index 00e0feb..44f243c 100644 Binary files a/src/out/vue/VueGraphiqueSwing$1.class and b/src/out/vue/VueGraphiqueSwing$1.class differ diff --git a/src/out/vue/VueGraphiqueSwing.class b/src/out/vue/VueGraphiqueSwing.class index c99eaa6..5a9cac3 100644 Binary files a/src/out/vue/VueGraphiqueSwing.class and b/src/out/vue/VueGraphiqueSwing.class differ diff --git a/src/reseau/Client.java b/src/reseau/Client.java index 429cccf..394f725 100644 --- a/src/reseau/Client.java +++ b/src/reseau/Client.java @@ -1,5 +1,97 @@ package reseau; +import java.io.*; +import java.net.*; + +import controleur.ControleurReseau; + public class Client { - + private final String host; // Adresse IP du serveur + private final int port; // Port du serveur + private ObjectInputStream input; // flux d'entrée (messages du serveur) + private ObjectOutputStream output; // flux de sortie (messages envoyés au serveur) + private ControleurReseau controleurR; + + public Client(String host, int port) { + this.host = host; + this.port = port; + } + + // Associer le controleur réseau au client + public void setControleur(ControleurReseau controleur) { + this.controleurR = controleur; + } + + // Connexion au serveur + public void connecter() throws IOException { + Socket clientSocket = new Socket(host, port); + System.out.println("Connecté au serveur " + host + ":" + port); + + output = new ObjectOutputStream(clientSocket.getOutputStream()); + input = new ObjectInputStream(clientSocket.getInputStream()); + + // Thread d'écoute des messages du serveur + new Thread(() -> { + try { + while (true) { + // Lire un message reçu du serveur + MessageJeu message = (MessageJeu) input.readObject(); + traiterMessage(message); + } + } catch (Exception e) { + if (controleurR != null) { + controleurR.onSysteme("Serveur déconnecté."); + } + } + }, "Client-Listener").start(); + } + + // Envoyer un message au serveur + public synchronized void envoyerMessage(MessageJeu message) throws IOException { + output.writeObject(message); + output.flush(); + } + + // Dispatch : traiter les messages du serveur + private void traiterMessage(MessageJeu message) { + if (controleurR != null) { + switch (message.getType()) { + case DEMANDE_DE_PARTIE: + controleurR.onDemandePartie(message.getAuteur()); + break; + + case MOUVEMENT: + controleurR.onMouvement(message.getCoup()); + break; + + case CHAT: + controleurR.onChat(message.getAuteur(), message.getContenu()); + break; + + case SYSTEME_INFO: + case SYSTEME_WARN: + case SYSTEME_ERR: + controleurR.onSysteme(message.getContenu()); + break; + + case DEFAITE: + case VICTOIRE: + case EGALITE: + controleurR.onFinPartie(message.getContenu()); + break; + + default: + controleurR.onSysteme("Message inconnu: " + message.getContenu()); + break; + } + } else { + System.err.println("Message reçu mais aucun controleur réseau n’est attaché !"); + } + } + + // Fermer proprement + public void deconnecter() throws IOException { + if (input != null) input.close(); + if (output != null) output.close(); + } } diff --git a/src/reseau/Serveur.java b/src/reseau/Serveur.java index c32ddbe..38af592 100644 --- a/src/reseau/Serveur.java +++ b/src/reseau/Serveur.java @@ -3,49 +3,102 @@ package reseau; import java.io.*; import java.net.*; -import controleur.ControleurReseau; - +import controleur.ControleurReseau; public class Serveur { private final int port; - private ObjectInputStream input; // flux d'entrée qui vient du client - private ObjectOutputStream output; // flux de sortie qui va vers le client - private ControleurReseau controleur; + private ObjectInputStream input; // flux d'entrée : messages reçus depuis le client + private ObjectOutputStream output; // flux de sortie : messages envoyés vers le client + private ControleurReseau controleurR; // référence au contrôleur réseau (qui gère la logique côté app) - public Serveur(int port){ + public Serveur(int port) { this.port = port; } + // Permet de brancher le controleur réseau à ce serveur public void setControleur(ControleurReseau controleur) { - this.controleur = controleur; + this.controleurR = controleur; } - public void demarrer() throws IOException{ + // Lancer le serveur + public void demarrer() throws IOException { + // Crée un serveur qui écoute sur le port choisi ServerSocket serveurSocket = new ServerSocket(port); System.out.println("Serveur démarré sur le port " + port); - // Accepter une connexion seule client + // Bloque jusqu'à ce qu'un client se connecte Socket clientSocket = serveurSocket.accept(); System.out.println("Client connecté : " + clientSocket.getInetAddress()); // Initialiser les flux de communication - output = new ObjectOutputStream(clientSocket.getOutputStream()); - input = new ObjectInputStream(clientSocket.getInputStream()); + output = new ObjectOutputStream(clientSocket.getOutputStream()); // envoi d’objets au client + input = new ObjectInputStream(clientSocket.getInputStream()); // réception d’objets du client - // Démarrer un thread pour écouter les messages entrants - new Thread(()-> { + // Lancer un thread séparé pour écouter les messages entrants en continu + new Thread(() -> { try { - while(true) { + while (true) { + // Lire un message envoyé par le client MessageJeu message = (MessageJeu) input.readObject(); + + // Dispatch du message vers le controleur réseau traiterMessage(message); } } catch (Exception e) { - if(controleur != null) { - controleur.onSyteme("Client déconnecté."); + if (controleurR != null) { + // Si le client se déconnecte ou erreur réseau + controleurR.onSysteme("Client déconnecté."); } } - }) + }, "Serveur-Listener").start(); + } + // Envoyer un message au client + public synchronized void envoyerMessageAuClient(MessageJeu message) throws IOException { + output.writeObject(message); // sérialise l’objet et l’envoie + output.flush(); // vide le buffer pour s'assurer que c'est transmis + } + + // Dispatch : traduit un MessageJeu reçu en action pour le controleur réseau + private void traiterMessage(MessageJeu message) { + if (controleurR != null) { + switch (message.getType()) { + case DEMANDE_DE_PARTIE: + controleurR.onDemandePartie(message.getAuteur()); + break; + + case MOUVEMENT: + controleurR.onMouvement(message.getCoup()); + break; + + case CHAT: + controleurR.onChat(message.getAuteur(), message.getContenu()); + break; + + case SYSTEME_INFO: + case SYSTEME_WARN: + case SYSTEME_ERR: + controleurR.onSysteme(message.getContenu()); + break; + + case DEFAITE: + case VICTOIRE: + case EGALITE: + controleurR.onFinPartie(message.getContenu()); + break; + + default: + controleurR.onSysteme("Message inconnu: " + message.getContenu()); + break; + } + } else { + System.err.println("Message reçu mais aucun controleur réseau n’est attaché !"); + } + } + + // Arrêt du serveur : fermeture des flux + public void arreter() throws IOException { + if (input != null) input.close(); + if (output != null) output.close(); } - } diff --git a/src/reseau/TypeMessage.java b/src/reseau/TypeMessage.java index 3eaf8a8..3cd3744 100644 --- a/src/reseau/TypeMessage.java +++ b/src/reseau/TypeMessage.java @@ -1,12 +1,26 @@ package reseau; public enum TypeMessage { - DEMANDE_DE_PARTIE, // Un joueur veut lancer une partie - MOUVEMENT, // Transmission d'un coup - FIN_DE_PARTIE, // Signal de fin + // Partie / connexion + DEMANDE_DE_PARTIE, + ACCEPTATION_PARTIE, + REFUS_PARTIE, + INIT_PLATEAU, - SYSTEMEBLEU, // Message système ( info serveur, etc.) - SYSTEMEROUGE, // Message système ( info serveur, etc.) en rouge - CHAT // Message chat entre joueurs + // Jeu + MOUVEMENT, + ABANDON, + ANNULATION, + TEMPS_DEPASSER, + + // Fin + DEFAITE, + VICTOIRE, + EGALITE, + + // Communication + CHAT, + SYSTEME_INFO, + SYSTEME_WARN, + SYSTEME_ERR } - \ No newline at end of file diff --git a/src/vue/VueGraphiqueSwing.java b/src/vue/VueGraphiqueSwing.java index b2e69c1..4b8f3cb 100644 --- a/src/vue/VueGraphiqueSwing.java +++ b/src/vue/VueGraphiqueSwing.java @@ -130,6 +130,11 @@ public class VueGraphiqueSwing implements Vue { fg = Color.RED.darker(); border = Color.RED; } + case "serveurorange" -> { + bg = new Color(255, 220, 220); // orange clair + fg = Color.ORANGE.darker(); + border = Color.ORANGE; + } default -> { // adversaire bg = new Color(255, 220, 220); // rouge clair fg = Color.RED.darker(); @@ -194,8 +199,9 @@ public class VueGraphiqueSwing implements Vue { public void afficherMessage(TypeMessage type, String message) { switch (type) { case CHAT : ajouterMessageChat("", message); break; - case SYSTEMEBLEU : ajouterMessageSysteme("serveurBleu", message); break; - case SYSTEMEROUGE : ajouterMessageSysteme("serveurRouge", message); break; + case SYSTEME_INFO : ajouterMessageSysteme("serveurBleu", message); break; + case SYSTEME_WARN : ajouterMessageSysteme("serveurOrange", message); break; + case SYSTEME_ERR : ajouterMessageSysteme("serveurRouge", message); break; default : System.out.println("[INFO] " + message); } } @@ -204,7 +210,7 @@ public class VueGraphiqueSwing implements Vue { public Coup demanderCoup(Plateau plateau) { while(this.c == null) { try { - Thread.sleep(20); + Thread.sleep(15); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); return null;