This project implements a Java-based Minesweeper game using the MVC pattern in the frontend and a layered architecture in the backend. The application supports multi-language user interfaces and persistent user preferences.
- frontend: Handles the graphical interface and user interactions.
- backend: Manages core game logic, persistence, and application preferences.
Note: Since the project is divided into two separate modules (frontend and backend), you need to import them manually when using IntelliJ IDEA. To do this: 1. Go to File → Project Structure…. 2. Under the Modules section, click the ”+” button and choose Import Module. 3. Select the frontend or backend directory and confirm. 4. Repeat the process for the other module. 5. Make sure both modules are properly configured and recognized by the main project.
-
presentation
- Service Layer: Bridges frontend and backend logic.
- Important classes:
GameServiceImpl: central class for game actions likemove,flag, and saving/loading games.PreferencesServiceImpl: manages reading and writing user preferences.TranslationsBusinessInterface: defines translation operations.GameObserver: To overcome the module separation, it has been introduced a new interface implemented by all views:GameObserver. This interface is supposed to be used like the oldViewinterface for the backend. In this way the GameModel has an elegant and safe way to tell views to update themselves, without having to rely on concrete implementations.
-
business
- Application Logic Layer: Models and interfaces for preferences and translation logic.
PreferencesModel: manages user preferences, including language and mine count.TranslationsModel: loads and manages translations based on selected locale.
-
dataaccess
- Persistence Access Layer: Reads/writes configuration data from property files.
PreferencesPropertiesDataAccess: saves preferences in the user’s home directory (preferences.properties).TranslationsPropertiesDataAccess: loads translations fromresources/i18n.
-
dataPersistence
- Game Save/Load Logic:
GamePersistence: serializes and deserializesGameModelto/from JSON using Jackson.
- Game Save/Load Logic:
-
model
- Domain Entities:
GameModel: represents the core game state, handles game rules, mine placement, and game progression.CellModel: represents each cell in the grid.
- Domain Entities:
-
event
- Defines event structures like
GameAction, which captures moves and game state transitions.
- Defines event structures like
The frontend uses JavaFX for UI and follows MVC principles.
MainFx: application entry point, initializes the UI and wires controllers and views.- controller: event-driven logic (e.g.,
GameController,ExitController). - view:
GameBoardViewFxml,MenuBarViewFxml,PreferencesViewFxml: handle game board, menu, and preferences dialog respectively.UserFeedbackViewFxml: shows translated feedback messages.implements GameObserver: simple mechanism to allow the backend to have a way to update every view when required.
- File:
preferences.properties - Managed by:
PreferencesPropertiesDataAccess - Location:
- macOS:
~/Library/Application Support/minesweeper/preferences.properties - Windows:
%APPDATA%\minesweeper\preferences.properties - Linux:
~/.config/minesweeper/preferences.properties
- macOS:
- Preferences file property:
language-tag - Supported values (see
supported-languages.properties):"en-US","it-CH", etc.
- Change dynamically through
PreferencesViewFxmlor directly editingpreferences.properties
Located in: src/main/resources/i18n/
- labels_en.properties
- labels_it.properties
- supported-languages.properties
- property key:
mines - Cold-loaded during backend model setup
- Accessed via:
PreferencesReader.getInitialNumberOfMines() - Used by:
GameModel.getInstance() during singleton initialization
PreferencesControllerreads the saved language tag.TranslationsModelloads the correspondingResourceBundle.- UI elements call
TranslationsController.translate(key)to retrieve the translated string.
- App starts via
MainFx, callingGameService.getGameModel() GameModel.getInstance()initializes state, including reading mine count fromPreferencesReaderGameServiceImplexposes operations like:newGame(),move(row, col),flag(row, col)
- Views observe the model (
GameObserver) and refresh on updates - Game state is saved/loaded using
GamePersistence
- The system uses singleton patterns in most service/model classes.
- Preferences are saved immediately when changed in the preferences UI.
- Game state is stored in JSON (
game_save.json) using Jackson, placed in the same directory as the.jarfile.