Introduction

bos10

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:

      • Actively update issues and provide constructive comments and feedback to the team. (Pull requests #147, #365, #375)

      • Managed the progress of the Developer Guide by delegating the required tasks and ensuring it is completed on time. (Issue #360)

    • 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:

      • Reviewed team member’s pull requests with suggestions for improvements (Pull requests : #365, #375) (Issues #376 (Suggested renaming key components), #377(Organization of DG))

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

  • The pop-up window will contain a bar chart visualisation of your game play data

  • To reload the statistics data, you must close the current pop-up window and call the stats command again to display the updated values.


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 :

inputStatsCommandSS

Pop-up window for stats :

StatsWindowSS
Figure 1. Screenshot of empty statistics pop-up window.

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.

StatsWindowUpdatedSS
Figure 2. Screenshot of populated statistics pop-up window.

Besides the pop-up window, the data is also captured in the command-line result box.

StatsCommandBox

The following sequence diagram summarizes what happens when a User invokes the stats command.

StatsSequenceDiagram
Figure 3. Sequence diagram of stats command.

Save and Compare

Given below is an example usage scenario of the automatic save and compare feature.

  1. Upon winning a game, a user will be presented with the following screen.

StatsWinScreen

Notice the displayed 'Statistics Analysis' section that displays a comparison of the player’s accuracy in the current game and the previous game.

  1. By inputting init 6 and press enter. The game will be restarted with a new map.

  2. 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.

SaveSequenceDiag
Figure 4. Sequence diagram of how the statistics data is saved.

The following sequence diagram summarizes what happens at the end of the game where an automatic reading of previous statistics data is performed.

ReadSequenceDiagram
Figure 5. Sequence diagram of how the previous statistics data is read from storage.

Activity Diagram

The following Activity Diagram shows when the stats command can be used.

StatisticsActivityDiagram
Figure 6. Activity Diagram of the statistics feature.

Use Case Diagram

The following use-case diagram captures the behaviour of the statistics feature.

StatsUseCaseDiag
Figure 7. Use case diagram on 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

StorageClassDiagram
Figure 8. Structure of the 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

  1. User requests to display current gameplay statistics

  2. 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

  1. User wins a game.

  2. 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.

  1. Initialize a 8x8 map using init 8.

  2. Run the stats command and observe the results

    1. Test case : stats (before)
      Expected: All fields are 0.

  3. Now input attack c1 to simulate an attack on the enemy map.

    1. 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.

  1. Initialize a 8x8 map using init 8.

  2. Input save into the command box and press enter.

    1. 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.

  3. Now play the game until you win.

  4. At the end of the game, the save command will be automatically called.

    1. 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.