Featured image of post Puissance 4 en Réseau : Implémentation MVC avec JavaFX

Puissance 4 en Réseau : Implémentation MVC avec JavaFX

Développement d'un jeu Puissance 4 multijoueur en réseau utilisant l'architecture MVC avec JavaFX et une bibliothèque réseau personnalisée.

Projet Puissance 4 en Réseau — Architecture MVC avec JavaFX


Présentation du projet

Puissance 4 en Réseau est une implémentation du célèbre jeu de société permettant à deux joueurs de s’affronter à distance via une connexion réseau.
Le projet met l’accent sur l’application rigoureuse de l’architecture Modèle-Vue-Contrôleur (MVC) et démontre comment structurer une application JavaFX pour le jeu multijoueur en temps réel.

Le jeu utilise une bibliothèque réseau personnalisée (JFX-Network) qui gère automatiquement la synchronisation des états entre les clients et le serveur, permettant une expérience de jeu fluide et cohérente.


Objectifs du projet

  • Maîtriser l’architecture MVC dans une application JavaFX complexe
  • Comprendre la séparation des responsabilités entre les couches logicielles
  • Implémenter une communication réseau robuste pour le multijoueur
  • Gérer la synchronisation d’états entre plusieurs clients
  • Concevoir des interfaces découplées pour faciliter la maintenance

Architecture du projet

1. Structure des packages

1
2
3
4
5
fr.univartois.butinfo.ihm.fourinaline/
├── controller/          # Contrôleurs et logique d'interaction
├── model/              # Modèle métier et règles du jeu
├── view/               # Vues FXML et ressources graphiques
└── network/            # Classes serveur et client réseau

2. Conception MVC appliquée

Modèle (Model)

Le modèle encapsule toute la logique métier du Puissance 4 :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class Game {
    private Grid grid;
    private Player currentPlayer;
    private GameState state;
    
    public boolean playMove(int column) {
        // Logique de placement du jeton
        // Vérification des conditions de victoire
        // Changement de joueur
    }
    
    public boolean checkWin(Player player) {
        // Algorithme de détection de victoire
        // (4 jetons alignés horizontalement, verticalement, diagonalement)
    }
}

Vue (View)

Interface utilisateur définie en FXML avec composants interactifs :

1
2
3
4
5
6
7
8
<GridPane fx:id="gameGrid" styleClass="game-board">
    <!-- Grille 7x6 pour le Puissance 4 -->
    <ImageView fx:id="cell_0_0" onMouseClicked="#onColumnClick"/>
    <!-- ... autres cellules ... -->
</GridPane>

<Label fx:id="currentPlayerLabel" text="Joueur Jaune"/>
<Button fx:id="restartButton" text="Nouvelle Partie"/>

Contrôleur (Controller)

Fait le lien entre la vue et le modèle, gère les événements utilisateur :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
@FXML
private void onColumnClick(MouseEvent event) {
    ImageView clickedCell = (ImageView) event.getSource();
    int column = getColumnFromImageView(clickedCell);
    
    // Transmission de l'action vers le modèle via la façade
    gameFacade.playMove(column);
}

@Override
public void updateGrid(Grid grid) {
    // Mise à jour de l'affichage suite aux changements du modèle
    Platform.runLater(() -> {
        for (int row = 0; row < 6; row++) {
            for (int col = 0; col < 7; col++) {
                updateCell(row, col, grid.getCell(row, col));
            }
        }
    });
}

3. Interfaces de découplage

Deux interfaces principales assurent le découplage entre les couches :

Interface Façade (IGame)

1
2
3
4
5
6
public interface IGame {
    void startGame();
    void playMove(int column);
    void restartGame();
    void setController(IController controller);
}

Interface Contrôleur (IController)

1
2
3
4
5
6
public interface IController {
    void updateGrid(Grid grid);
    void updateCurrentPlayer(Player player);
    void gameEnded(Player winner);
    void setGame(IGame game);
}

🌐 Architecture réseau

Serveur de jeu

Le serveur centralise la logique du jeu et synchronise les clients :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class GameServer {
    public static void main(String[] args) throws IOException {
        IGame game = new FourInALineGame();
        
        try (JFXNetworkServer<IController> server = 
                 new JFXNetworkServer<>(PORT, game, IController.class)) {
            
            IController controller = server.getController();
            game.setController(controller);
            
            // Attendre 2 joueurs puis démarrer
            server.start(2, game::startGame);
        }
    }
}

Client de jeu

Chaque client se connecte au serveur et reçoit les mises à jour :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class GameClient extends Application {
    private JFXNetworkClient client;
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        // Chargement de l'interface FXML
        FXMLLoader loader = new FXMLLoader(getClass().getResource("game-view.fxml"));
        Parent root = loader.load();
        
        // Récupération du contrôleur
        GameController controller = loader.getController();
        
        // Connexion réseau
        client = new JFXNetworkClient(HOST, PORT, controller);
        client.start();
        
        // Association du modèle distant
        IGame game = client.getModel(IGame.class);
        controller.setGame(game);
        
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}

🎮 Fonctionnalités implémentées

Jeu local et en réseau

  • Mode local : Deux joueurs sur la même machine
  • Mode réseau : Deux joueurs sur des machines différentes
  • Synchronisation automatique des actions entre les clients

Interface utilisateur intuitive

  • Grille visuelle avec jetons colorés (rouge/jaune)
  • Indication du joueur courant
  • Détection automatique des fins de partie
  • Bouton de redémarrage pour une nouvelle partie

Gestion robuste des états

  • Validation des coups (colonne pleine, partie terminée)
  • Détection de victoire dans toutes les directions
  • Gestion des parties nulles (grille complète)
  • Verrouillage de l’interface en fin de partie

🛠️ Technologies utilisées

  • Java 11+ : Langage de programmation principal
  • JavaFX : Framework pour l’interface graphique moderne
  • FXML : Séparation claire entre vue et logique métier
  • JFX-Network : Bibliothèque réseau personnalisée pour JavaFX
  • Gradle : Gestionnaire de dépendances et build
  • SceneBuilder : Outil de conception d’interfaces FXML

🎯 Points techniques remarquables

Architecture MVC stricte

La séparation des responsabilités est respectée rigoureusement :

  • Modèle : Aucune dépendance vers la vue ou le contrôleur
  • Vue : Définie uniquement en FXML, sans logique métier
  • Contrôleur : Interface entre vue et modèle, sans logique métier

Pattern Façade pour le découplage

La façade simplifie l’interface du modèle complexe et centralise les appels :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class GameFacade implements IGame {
    private Game game;
    private IController controller;
    
    @Override
    public void playMove(int column) {
        if (game.isValidMove(column)) {
            game.playMove(column);
            controller.updateGrid(game.getGrid());
            
            if (game.isFinished()) {
                controller.gameEnded(game.getWinner());
            } else {
                controller.updateCurrentPlayer(game.getCurrentPlayer());
            }
        }
    }
}

Communication réseau transparente

La bibliothèque JFX-Network permet une communication transparente :

  • Sérialisation automatique des appels de méthodes
  • Gestion des proxies pour les interfaces distantes
  • Thread safety pour les mises à jour de l’interface

Code extensible et maintenable

  • Interfaces bien définies facilitant les tests unitaires
  • Responsabilités clairement séparées
  • Configuration centralisée (ports, adresses)

📈 Résultats et apprentissages

Ce projet m’a permis de maîtriser :

  • L’architecture MVC dans un contexte applicatif réel
  • La programmation réseau en Java avec gestion des erreurs
  • Le développement d’interfaces JavaFX avancées avec FXML
  • La gestion de la concurrence dans les applications graphiques
  • Les bonnes pratiques de structuration de projet Java

Le résultat est une application robuste, extensible et démonstrative des bonnes pratiques de développement logiciel en Java, particulièrement adaptée pour comprendre les enjeux du développement d’applications distribuées.

Interface de jeu en cours

Connexion réseau entre deux clients

Généré avec Hugo