Introduction
Hello! My name is Boston, a Year 2 Computer Science student at the National University of Singapore (NUS). This portfolio documents the CS2103T Software Engineering project I have been actively involved in over the past semester. The experience has exposed me to new technologies and helped me to develop relevant skills en route to being a Software Engineer.
Project Overview : Battleship
'Battleship' is a desktop game application based on the classic Battleship guessing game. Borrowing the same game rules, the game aims to recreate the adrenaline-filled experience by pitting the player against an intelligent computerized enemy. However, instead of using a pencil and paper, players will be introduced with the command-line interface which they will use to play the game.
My role was to design and implement a method to track and monitor the progress of the game. I managed to achieve this by introducing the 'Statistics' feature of Battleships. By allowing the player to view their gameplay data, performance and score at any time during the game players are able to plan their moves strategically.
The following sections will illustrate the feature and its implementation in more detail.
Summary of contributions
-
Major enhancement: added the ability to view the game statistics.
-
What it does: By entering the
stats
command, the player will be given a pop-up display that contains information on the number of successful hits, number of misses, number of enemy ships destroyed and even the player’s current shooting accuracy. -
Justification: This feature is crucial to user experience in the game as it allows players to track and keep up with the progress of the game. It is also fundamental as a basis for deploying strategies in the gameplay.
-
Highlight: This feature can be invoked at any point of the game.
-
-
Major enhancement: added the ability to compare the game statistics between two games.
-
What it does: Upon winning a game, the game will automatically save the current game statistics into the storage folder of the application. At the same time, the game will perform a comparison with the previous game statistics data (if any) and will reflect if there are improvements from the previous game.
-
Justification: This feature enhances the user experience by giving constructive feedback through an analysis the player’s past game. This encourages player to employ different strategies to be better at the game. It also demonstrates the application’s ability to store game data which is fundamental to a future highscore feature in the game.
-
-
Minor enhancement: added the elapsed time panel to update the duration of the game in real-time.
-
Code contributed: View my Project Dashboard and my Github commits.
-
Other contributions:
-
Project management:
-
Enhancements to existing features:
-
Overhaul of HistoryCommand into StatsCommand to be used by rest of the team (Pull request #43)
-
Restructured Storage component to accommodate saving of statistics data (Pull request #289)
-
Introduced an elapsed time functionality in the Graphical User Interface (GUI). (Pull request #108, #123 )
-
Wrote tests for the statistics feature and storage component and increased coverage by 5.6%. (Pull Requests #253, #379, #397)
-
-
Documentation:
-
Added detailed implementation documentation for the statistics feature in the Developer Guide and User Guide, including screenshots and diagrams.
-
Added detailed implementation documentation for the storage feature in the Developer Guide and User Guide, including diagrams.
-
Added the command summary table into the Developer Guide.
-
-
Community:
-
Contributions to the User Guide
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
Statistics Feature
Retrieving game statistics: stats
Retrieves the gameplay statistics data displays them on a pop-up window.
Format: stats
Command Summary
As the diagram is too large, please refer to 'Command Summary' in the User Guide. (link)
Display high score across games
Display the high score across more than two games.
Format: stats highscore t/ATTRIBUTE
Examples:
-
stats highscore t/time
Display game data from the game that won in the shortest amount of time -
stats highscore t/accuracy
Display game data from the game with the highest accuracy.
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
Statistics feature
Current implementation
The statistics feature allows users to view their current gameplay information. This information will be displayed in a pop-up window that includes: Number of Attacks Made, Number of Successful Hits, Number of Misses and Number of Enemy Ships Destroyed. The statistics command can be called at any juncture of the game.
Upon a successful win game, the statistics feature also implements a save command that automatically saves the statistical data into the game’s storage. At the same time, the command will retrieve the statistical data from the previous game and perform a comparison of game data.
The following operations are invoked upon the calling of the stats
command.
-
getAttacksMade()
- Returns the number of attacks made by the User. -
getMovesLeft()
- Returns the remaining number of moves left for the User. -
getHitCount()
- Returns the number of successful hit on enemy ships. -
getMissCount()
Returns the number of misses made. -
getEnemyShipsDestroyed()
Returns the number of Enemy Ships Destroyed by the player. -
getAccuracy()
Returns the current Hit-Miss Ratio of the User based on the game so far. -
generateData()
Formats the current statistical data into a json serializable format.
Display statistics
Given below is an example usage scenario and how the stats
command behaves at each step.
Step 1. The User initializes the game with the init 8
which will create a 8x8 map.
The Map can be initialized to any valid size (This is just a sample scenario)
Step 2. Put the ships onto the grid via the put
ship command.
Step 3. Input stats
into the command-line and press enter to obtain the current statistical data.
Inputting stats
:
Pop-up window for stats
:
There should not be any valid data at the moment as the game as not started.
Step 4. Now proceed with the game and perform an attack. Input attack a1
.
Step 5. Invoke the stats
command again to view the updated statistics of the attack result.
Besides the pop-up window, the data is also captured in the command-line result box.
The following sequence diagram summarizes what happens when a User invokes the stats
command.
stats
command.Save and Compare
Given below is an example usage scenario of the automatic save and compare feature.
-
Upon winning a game, a user will be presented with the following screen.
Notice the displayed 'Statistics Analysis' section that displays a comparison of the player’s accuracy in the current game and the previous game.
-
By inputting
init 6
and press enter. The game will be restarted with a new map. -
Next, input the command
stats
to observe how the previous statistics data has also been cleared in preparation for the new game.
The following sequence diagram summarizes what happens at the end of a game and an automatic save is performed.
The following sequence diagram summarizes what happens at the end of the game where an automatic reading of previous statistics data is performed.
Activity Diagram
The following Activity Diagram shows when the stats
command can be used.
Use Case Diagram
The following use-case diagram captures the behaviour of the statistics feature.
Design considerations
Design of data-tracking methods
-
Alternative 1: The methods that are responsible for incrementing the relevant game data are placed in each of the commands to be tracked. This meant that there would be a method call to the statistics class from within every method itself, which also meant that every method had to contain a parameter for the PlayerStatistics Object.
-
Pros: The methods are clearly visible within each command to be tracked and as a developer I can understand when each command is being tracked.
-
Cons: This implementation violates the DRY principle (Don’t Repeat Yourself) Principle.
-
-
Alternative 2 (Current Choice) : The method responsible for incrementing the statistical data is placed only at the AttackCommand class.
-
Pros: The implementation does not violate the DRY principle and contains less dependencies on the other components.
-
Cons: It is more difficult to code as it has to account for different CommandResult objects.
-
Type of Storage File
-
Alternative 1 (Current Choice) : Use JSON file to store statistics data
-
Pros: Easy to implement as there are libraries pre-installed.
-
Cons: Formatting errors are not validated
-
-
Alternative 2 : Use XML file to store statistics data
-
Pros: Can put metadata into the tags in the form of attributes.
-
Cons: Difficult to code as it is less readable and external libraries must be imported.
-
Storage component
API : Storage.java
The Storage
component,
-
can save
PlayerStatistics
objects in json format and read it back.
Documentation of Use Cases
See game statistics
MSS
-
User requests to display current gameplay statistics
-
User is presented with all of the user’s gameplay data in a pop-up window.
Use case ends.
Extensions
-
2a. There is no statistics data to display
-
2a1. A single statement indicating no statistical data yet is displayed in the command box.
-
Compare scores with previous games
MSS
-
User wins a game.
-
User is presented with a comparison between the current game and previous game score.
Use case ends.
Extensions
-
2a. There is no previous game data.
-
2a1. A single statement indicating no statistical data yet is displayed in the command box.
-
Instructions for Manual Testing
Viewing the statistics
To test the stats
feature. We will perform a before and after check to see if the statistical data of a simple behaviour is captured. In this case, we will perform an attack with a miss result.
-
Initialize a 8x8 map using
init 8
. -
Run the
stats
command and observe the results-
Test case :
stats
(before)
Expected: All fields are 0.
-
-
Now input
attack c1
to simulate an attack on the enemy map.-
Test case :
stats
(after)
Expected: Number of attacks : 1, Number of Misses : 1
-
Saving statistics data
To test the statistics save and compare feature. We will use a debug command save
.
-
Initialize a 8x8 map using
init 8
. -
Input
save
into the command box and press enter.-
Test case :
save
(start of game)
Expected: Accuracy is same as before at 0%. This is because the application automatically compares to a default state of 0 if there is no previous game.
-
-
Now play the game until you win.
-
At the end of the game, the
save
command will be automatically called.-
Test case : Win the game
Expected: A comparison is made between your current game accuracy and the previous game accuracy which is 0. Your accuracy has improved.
-