Starting from:

$25

COMP90041 - Assignment 3 - Solved

1           Mandatory Assignment
1.1         Introduction
The aim of this project is to add some more advanced features to the system developed in Project B. The features to be added are:

•    Sort the players with more specific rules

•    Handling of invalid input via Exceptions

•    Write (read) the game statistics into (from) a file, i.e., one which is stored on the hard disk between executions of Nimsys

•    A new type of player - an AI (Artificial Intelligence) player, whose moves are automatically determined by the computer rather than a game user

The system should still operate as specified in Project B, but with additional functionality, due to the addition of the aforementioned features. Thus, it is advised that you use your Project B solution as a starting point for implementing Project C.

Knowledge Coverage

•    Exceptions

•    File I/O operations

•    Polymorphism, you may use either inheritance or interface to design the AI player in addition to the human player

1.2         Requirements
In the following description, all command line displays are put in a box. This is only for easier understanding the format. The box should NOT be printed out by your program, only the contents in the box should be printed. The command prompt is illustrated below:

1.2.1          Sort the players with more specific rules

In Project B, when two players had the same winning ratio, you were required to sort the players by username in either ascending alphabetical order or descending alphabetical order.

In this project, the ranking should still be based on the winning ratio first (i.e., the percentage of games won). If there is a tie (two or more players with the same winning ratio), sort all players by their username in ONLY ascending alphabetical order.

Example Execution:

Suppose we have three players in (username, First Name, Last Name) format as follow: (LS, Luke, Skywalker), (HS, Han, Solo), (DV, Darth, Vader). They all have the same wining ratio.

1.    rank all users (default, i.e., descending order)

$rankings

0% | 00 games | Darth Vader

0% | 00 games | Han Solo

0% | 00 games | Luke Skywalker

$
2.    rank all users in descending order

$rankings desc

0% | 00 games | Darth Vader

0% | 00 games | Han Solo

0% | 00 games | Luke Skywalker

$
3.    rank all users in ascending order

$rankings asc

0% | 00 games | Darth Vader

0% | 00 games | Han Solo

0% | 00 games | Luke Skywalker

$
1.2.2          Invalid input handling via Exceptions

The system should check inputs for validity. For this task, you will not be required to implement exception handling for all possible invalid inputs - just a subset of them. The range of potential invalid inputs you are required to address by Exceptions (not via if-then statements) are listed below, along with the required behaviour of your program. Note that some of this input checking was also a requirement in Project B. Where this is the case, you need to modify your code so that the invalid input is handled via

Exceptions. The rest of the invalid input handling cases described in Project B do not need modification.

•    Invalid command - The user enters a command which is not a valid Nimsys command. Here, invalid command suggests the input command is not among the specified commands, i.e., addplayer, editplayer, removeplayer, displayplayerresetstats, rankings, startgame, and exit. Example:

$createplayer lskywalker,Skywalker,Luke ‘createplayer’ is not a valid command.

$
•    Invalid number of arguments - The user enters a valid Nimsys command, but does not provide the correct number of arguments. Note: You only need to check for insufficient number of arguments, and simply ignore any extra arguments, i.e., an insufficient argument count will generate an Exception while an excessive count will not. Different commands may have different number of arguments; your program should be able to check invalid number of arguments for all commands. Example:

$addplayer lskywalker Incorrect number of arguments supplied to command.

$
•    Invalid move (during a game) - The player tries to remove an invalid number of stones from the game. For the move to be valid, it must be an integer between 1 and N inclusive, where N is the minimum of the upper bound and the number of stones remaining. Any other inputs (e.g. fractions, decimals, non-numeric entries) should be detected as invalid. Example (Upper bound is 3 stones here):

7 stones left: * * * * * * * Han’s turn - remove how many?

4 Invalid move. You must remove between 1 and 3 stones.

7 stones left: * * * * * * * Han’s turn - remove how many?
After implementing the invalid input checking, the scenarios detailed above should not cause your program to crash - rather, your program should display the appropriate error message, and continue execution, as illustrated in the examples. You may assume that, aside from the cases explicitly mentioned above, the input to your program will be valid.

1.2.3        The player statistics file

In Project B, no program data are stored to disk, so all player data are lost when exiting the program. Here, the task is to store these data upon exiting the program, and to restore them on subsequent executions. Thus, if one was to exit your program (using the ‘exit’ command), and then start it again (by running ‘java Nimsys’ at the shell prompt), your program should be restored to the state it was in immediately before exiting. That is, it should be as if the program never exited at all.

This can be achieved by storing your player data in a file. At the beginning of the execution of your program, if the file exists, it is opened and its contents loaded into the system. When your program exits, this file will be updated with new/modified players, and then closed. If the file does not already exist, it will need to be created. It is up to you to decide the most appropriate format, e.g., text or binary, of this file. The name of the file should be players.dat, and it should be stored in the same directory as your program.

All player information should be stored, i.e., usernames, given / family names, and number of games played / won. Note that you do not need to store information about games in progress, since a game should never be in progress when the program exits properly, i.e., via the ‘exit’ command.

1.2.4           The AI (Artificial Intelligence) player

Here, a new type of player is to be added - an AI player. This player type should be controlled by the program, not by a human player. Aside from this, an AI player should be the same as a human player. That is, they should have all the same information associated with them (i.e., username, given/family names, and number of games played/won), and they should be stored in the system and appear in player lists/rankings, just as human players are. They should also be manipulated via all the same commands (with the exception of ‘addplayer’, since we now need to indicate whether we are adding a human player or an AI player to the system - see below).

The only difference between a human player and an AI player is in the way that they make a move. Instead of prompting for a move to be entered via standard input, the AI player should choose their own move, based on the state of the game. Thus, the only difference between a human player and an AI player should be in the method used to make a move. This suggests that the object-oriented principle of polymorphism should be applied here. Java offers polymorphism via two main avenues - inheritance, and interfaces. In this case, inheritance is the more appropriate choice. Conceptually speaking, we can think of human players and AI players as specialized players, i.e., a human player is a player, and an AI player is a player. They are identical in almost every way, and so most of their attributes and methods can be inherited - the only exception to this is the method used to make a move, which will need to be rewritten to act autonomously. You can add an abstract NimPlayer class, which will be used to represent the behaviour/attributes common to both Human and AI players. You can modify your original NimPlayer class used in Project B to be the new abstract NimPlayer class, and the human player class (NimHumanPlayer) and AI player class (NimAIPlayer) can extend the abstract player class.

Part of your mark for this project will be based on how well you apply polymorphism in your implementation of the human and the AI player, so it is important that you do use the principle of polymorphism in your design.

To allow for AI players to be added to the system, you should create a new command - ‘addaiplayer’. This command should operate in exactly the same way as ‘addplayer’ (refer to Project B for details). The only difference is that the resulting player is an AI player. Note that all other commands, e.g., ‘removeplayer’ and ‘editplayer’ should work for both human players and AI players. Provided below is an example of the use of the ‘addaiplayer’ command:

$addaiplayer artoo,D2,R2

$
In this task you need to modify the provided NimAIPlayer.java to implement the AI player functionality. Note that this file and Testable.java are provided to you for auto-testing the task of Section 2.6. You do NOT need to modify the advancedMove() method until you work on the task of Section 2.6.

After implementing the AI player, the ‘startgame’ command should allow games to be started with one or both players being AI players. The game should proceed exactly as per the Project B spec, except that when it comes to an AI player’s turn, there should be no reading of input from standard input - instead, the move should be immediately made by the AI. Provided below is an example execution. Here, Luke is a human player, and R2 D2 is an AI player:

$startgame 10,3,lskywalker,artoo

Initial stone count: 10
Maximum stone removal: 3

Player 1: Luke Skywalker Player 2: R2 D2

10 stones left: * * * * * * * * * *

Luke’s turn - remove how many?

3

7 stones left: * * * * * * * R2’s turn - remove how many?

5 stones left: * * * * *

Luke’s turn - remove how many?

3

2 stones left: * *

R2’s turn - remove how many?

1 stones left: *

Luke’s turn - remove how many?

1

Game Over

R2 D2 wins!

$
The move an AI player makes given a specific situation shall follow certain strategy such that the victory is guaranteed for the AI player if it holds the ability to win when the game commences. For details, please see the following section.

2           Checklist For Solution
•    Blank line and whitespace related issues  Make sure in terms of format, your output matches with the expected output on the submission system.

•    File I/O mechanism related issues

 Make sure your program runs fine no matter whether the players.dat file exists.

 Make sure every exit command triggers data to be written to the players.dat file.

•    Polymorphism related issues

 Make sure the AI player is implemented using inheritance mechanism.  Make sure you are leveraging the polymorphism to invoke the methods, i.e., using object declared in parent class to invoke methods overridden in the child class.

 If attempting for bonus marks, make sure the advanced game is implemented using either inheritance or interface mechanism




4           Your Task
Implement the new version of Nimsys in Java according to the above specification. Specifically, it includes following subtasks:

1.    try / catch syntax to detect the listed invalid inputs in Section 1.2.2;

2.    file based mechanism for player data as described in Section 1.2.3;3. the AI player implemented using polymorphism mechanism in Section 1.2.4;
.


More products