Manual

Introduction

The Klotski application allows you to play the eponymous game: a sliding block puzzle where the goal is to move a special block to a predefined position. The challenge lies in cleverly maneuvering the other pieces within the game board to make way for the special one, and to succeed in getting it to the final position in the fewest possible moves.

Technologies Used

Name Version Description
Java 20 Environment and programming language used to develop the application.
JavaFX 20.0.1 Platform for client application development, based on Java.
JFoenix 9.0.1 Open-source Java library that implements Google Material Design using Java components.
Jackson 2.12.3 Java library for serializing Java objects to JSON and vice versa.
JUnit 5.9.1 Framework for automated testing of Java classes.
SceneBuilder 19.0.0 Software for building a JavaFX GUI using "drag and drop."

In the end, it is recommended to consult the attached Javadoc for a better understanding of library integration.

Project Description and Implementation

In the early stages of project development, specifications were discussed and explored with the idea of tackling the design and development phases as linearly as possible.

After completing the specification and design phases (whose "deliverables" are attached in the following sections), the actual development of the application was initiated.

The main idea underlying the implementation of the software's features was to use the concept of "configuration," representing the set of pieces that make up the puzzle and their positions at a given moment (or move).

Graphical Interface and Block Movement

To create the GUI, the JavaFX graphics library and SceneBuilder software were used for easier arrangement of graphical elements and the subsequent generation of the .fxml file, which encodes the interface using JavaFX markup language.

The blocks were implemented by extending the Rectangle component of JavaFX, allowing for the management of block movement logic - preventing overlap, ensuring they stay within the game board's boundaries, and extracting information from attributes provided directly by the library.

To complete the interface, buttons were added, selected from JFoenix components. Each button was associated with a functionality, each of which was implemented through logic triggered by user actions on the GUI.

Possibility to Save the Current State and Restore It

This feature is closely related to the others. To save the current state and allow its restoration once the application is closed and reopened, we decided to keep track of various configurations generated every time a single block is moved. This history is stored in a JSON file, which is updated with each move. The Jackson library was used to handle file writing and reading.

Choosing from Different Initial Configurations

The functionality of changing configuration was associated with some buttons. The selectable initial configurations are stored within the code.
Please note that changing the configuration results in a reset of the history.

Resetting the Game

Through the dedicated button, you can reset the game by returning to the initial configuration from which you started playing.

Undoing a Move

Using the appropriate button, you can undo one move; this operation is implemented by removing the last configuration from the history and displaying the penultimate one.

Next Best Move

With the dedicated button, you can make the game execute the best possible move starting from the current state of the game when NBM is requested. The logic enabling this functionality is implemented by an external system (link to the script). The connection between the latter and the software was created using two JavaFX classes: WebView, to "map" the content of a web page, and WebEngine, to modify a web page through WebView. With this infrastructure, it was possible to query the external system and process its response. The resulting configuration is stored in the history as a move.

Move Counter

A "counter" is provided to count the moves in a game, which corresponds to the size of the history without considering the initial configuration (this logic applies to all other features).

At the end of the development, code refactoring was performed to enable efficient and rigorous testing, including the use of JUnit (the testing deliverables are available in the following sections).

Download and Install the Software

Jar

To download the program in .jar format, click on the Windows or macOS button:

Once the .zip file download is complete, extract its contents to a location of your choice on your device. There will be a directory containing a folder and a file:

  • /klotski_files, which contains the files necessary for game saving and NBM request. It was chosen to allocate them externally because it was not possible to render and use them within the .jar file.

  • klotski.jar, the application.

To start the application, double click on the klotski.jar file. Running the program in this mode is possible after installing the JRE.

To run the klotski.jar file, it must be in the same directory as the klotski_files folder. Due to a lack of alternative support, functionality is guaranteed on Windows 10 and macOS Monterey 12.6

Note: macOS

If, when attempting to run the .jar file, the alert 'Unable to open “klotski.jar” because it is from an unidentified developer' appears, you can still run it through: Right-click > Open > Open

IDE

If there are issues with the previous installation method, it is recommended to clone the repository at the link in the upper right corner, open the downloaded project with an IDE (such as IntelliJ), and run the Main.java file located at the following path: src/main/java/com/klotski/app/Main.java

Execution requires the installation of the jdk (preferably version 20).

How to Play

Klotski

To move a block, simply click on it and move it using the arrow keys or WASD.

To change configuration, simply click one of the numbered buttons to the right of the puzzle.

To request the functions, simply click the corresponding buttons to the left of the puzzle.

Note: NBM may take some time, especially on the first run.

Design Patterns

GRASP

Creator

The Piece class was designed following the "Creator" pattern. Configuration indeed instantiates and aggregates objects of the Piece class. Also, Configuration is contained and instantiated in Game.

Controller

The Controller class is simply what it says it is: a "controller," an object responsible for communication between the graphical interface and the system. This class is responsible for receiving the user inputs provided through the GUI, subsequently invoking functions implemented in other classes that handle the request's logic, and then receiving the results and updating the interface accordingly.

Low Coupling

All classes in this software were designed to limit coupling as much as possible, i.e., the impact that a change to one class could have on the entire project.

High Cohesion

All classes in this software were designed to represent atomic and separate concepts as much as possible.

Pure Fabrication

During the design phase, it was noticed that a class to handle all the logic behind a game of Klotski would be convenient. With this purpose, the Game class was "fabricated."

GoF

Facade

The Controller class also serves as an interface for the NBM_Script. In practice, it is the only facade that connects the system with other external actors, which reflects the "Facade" design pattern.

Low Coupling

All classes in this software were designed to limit coupling as much as possible, i.e., the impact that a change to one class could have on the entire project.

High Cohesion

All classes in this software were designed to represent atomic and separate concepts as much as possible.

Pure Fabrication

During the design phase, it was noticed that a class to handle all the logic behind a game of Klotski would be convenient. With this purpose, the `Game` class was "fabricated."

GoF

Facade

The `Controller` class also serves as an interface for the NBM_Script. In practice, it is the only facade that connects the system with other external actors, which reflects the "Facade" design pattern.


Specifications

Use Cases
  1. View current configuration
  2. Choose initial configuration
  3. Move pieces to allowed positions
  4. View move counter
  5. Use reset function
  6. Use undo function
  7. View "next best move"
  8. Save the game
  9. Restore saved game
  10. Provide "next best move"
  11. Win
Use Case 1
Use Case Name View current configuration
Actors Player
Description The player must be able to view the current configuration on the screen.
Preconditions -
Main Scenario The last configuration stored in the history is displayed to the player.
Alternative Scenario -
Post-Conditions -
Notes -
Use Case 2
Nome dello Use Case Choose Initial Configuration
Attori Player
Descrizione The player can select one of four initial configurations to start playing.
Precondizioni -
Scenario Principale The program sets up the initial arrangement of pieces based on the configuration chosen by the player.
Scenario Alternativo The game can start or continue with the current configuration.
Post-Condizioni Reset the move counter and the game.
Note The choice of the initial configuration can always be made, but the ongoing game will be deleted.
Use Case 3
Use Case Name Move Pieces to Allowed Positions
Actors Player
Description The player can move a piece one position per turn to an empty space that can accommodate it.
Preconditions There must be an allowed position, i.e., an empty space.
Main Scenario The selected piece is moved one position in the direction chosen by the player.
Alternative Scenario The selected piece does not move.
Post-Conditions Increase the move counter, save the game.
Notes -
Use Case 4
Use Case Name Display Moves Counter
Actors Player
Description The player must be able to view the number of moves made so far.
Preconditions A counter must be present in the graphical interface displaying the number of moves made up to that point.
Main Scenario Whenever the player takes an action, the counter is updated and displayed to the player.
Alternative Scenario -
Post-Conditions -
Notes -
Use Case 5
Use Case Name Use Reset Function
Actors Player
Description The player can reset the game using a dedicated button.
Preconditions -
Main Scenario At any time, the player can choose to reset the game by pressing the "reset" button. Pieces must be arranged in the initial configuration related to the game they were playing.
Alternative Scenario If the player has not made a move yet, the reset does nothing.
Post-Conditions Reset the move counter and the game.
Notes -
Use Case 6
Use Case Name Use Undo Function
Actors Player
Description The player can choose to undo a move using a dedicated button.
Preconditions At least one move must have been made before invoking the functionality.
Main Scenario The arrangement of the pieces reverts to the previous configuration relative to the current one.
Alternative Scenario No modifications are applied to the game state, and the player is notified that there are no moves to undo.
Post-Conditions Decrease the move counter, save the game.
Notes The player can undo as many moves as they wish, going back through the game's history to the initial configuration.
Use Case 7
Use Case Name Display "Next Best Move"
Actors Player
Description The player sees a configuration representing the best move compared to the previous configuration.
Preconditions The player must be connected to the internet.
Main Scenario Whenever "Next Best Move" is requested, one piece at a time will be moved to achieve victory in the fewest possible moves.
Alternative Scenario The message "NBM not available, connect to the Internet" is displayed if the player is not connected.
Alternative Scenario The message "Error loading NBM" is displayed if something goes wrong.
Alternative Scenario The message "Loading NBM..." is displayed if the player requests the NBM again before receiving it.
Post-Conditions Increase the move counter, save the game.
Notes -
Use Case 8
Use Case Name Save the Game
Actors Player
Description The player must be able to save the game.
Preconditions The player has taken some action.
Main Scenario Whenever the player performs an action that affects the arrangement of the pieces (move, undo, reset, or choose the initial configuration), the game must be saved so that if the program is closed, the game can be resumed upon the next launch.
Alternative Scenario -
Post-Conditions -
Notes The game is represented by all configurations generated up to that point (plus the initial configuration) and, consequently, by the move counter.
Use Case 9
Use Case Name Restore Saved Game
Actors Player
Description When the player reopens the application, the game loads the last saved configuration.
Preconditions
  • A game save must be present.
  • The loaded game must not have already concluded.
  • The player must want to view the last configuration by starting the game.
Main Scenario The player opens the application and views the last saved configuration from when the game was last closed.
Alternative Scenario -
Post-Conditions -
Notes -
Use Case 10
Use Case Name Provide "next best move"
Actors NBM_Script
Description The external system NBM_Script calculates the NBM (Next Best Move).
Preconditions The player must be connected to the internet.
Main Scenario The external system calculates the NBM and provides it.
Alternative Scenario The external system fails to calculate the NBM for some reason.
Alternative Scenario The external system does not receive the request or cannot send a response due to a connection interruption.
Post-Conditions The NBM must be processed and displayed.
Notes -
Use Case 11
Use Case Name Win
Actors Player
Description The player must be able to win.
Preconditions The player must have moved the special piece to the winning position (bottom center).
Main Scenario The player is notified that they have won.
Alternative Scenario The player, with the current move, has not reached the winning position with the special piece.
Post-Conditions The move counter is reset, and the game is reset.
Notes -

Design

Domain Model

Domain model

Design Class Model

Design Class Model

Sequence Diagrams

System Sequence Diagram

System Sequence Diagram

Internal Sequence Diagrams

move(piece, keyCode)

The numbered sequence within the alt constructs should not be taken as strict, as they are executed alternatively but indicative.

muovi(pezzo, keyCode)

change_configuration(alternative_configuration)

The numbered sequence within the alt constructs should not be taken as strict, as they are executed alternatively but indicative.

cambia_configurazione(configurazione_alternativa)

undo()

The numbered sequence within the alt constructs should not be taken as strict, as they are executed alternatively but indicative.

undo()

reset()

reset()

request_NBM()

The numbered sequence within the alt constructs should not be taken as strict, as they are executed alternatively but indicative.

richiedi_NBM()

Test

Unit Tests Results

Unit Tests Results

Click to view the results of the Unit Tests



System Tests

System Tests

Click to view the System Tests


JavaDoc

Java Doc

Click to view the JavaDoc