# CS50 Nuggets Project Design Spec
## Team: imac
#### Group Members:
- (i) Ikeoluwa Abioye
- (m) Mubarak Idoko
- (a) Alexander Huang-Menders
- \(c\) Charlie Childress
## Design Spec
In this document we reference the Requirements Specification and focus on the implementation-independent design decisions. The knowledge unit noted that a design spec may include many topics; not all are relevant to the Nugget Lab. Here we focus on the core subset:
- Assumptions
- User interface (including command-line parameters and stdin/stdout/graphical interface);
- Inputs and outputs
- Functional decomposition into modules
- Pseudo code (plain English-like language) for logic/algorithmic flow
- Major data structures
- Testing plan, including unit tests, integration tests, system tests.
For the following major programs/modules
- Server
- Client
- Map
## Assumptions
- The text file is a valid mapfile (according to the Requirement specs)
## Server
### User interface
The server's initial interface with the user is on the command line. It may have 1 or 2 arguments:
```
./server mapfile.txt [seed]
```
Where the seed is optional. For example,
```
./server maps/big.txt
```
Any other user interactions is handled through client messages.
### Inputs and outputs
Inputs:
- The server reads a .txt file from the command-line, which it parses into a 2D array.
- The server receives these message types from the client, per network protocol: `PLAY`, `SPECTATE`, and `KEY`.
Ouput:
- The server sends a string representation of the mapfile as well as the other network protocol messages to client.
### Functional decomposition into modules
We anticipate the following functions or modules:
- server_init(), which calls a function to create the map and sets up server connection
- generate_piles(), which randomly divides `goldTotal` into a random number of piles such that the number of piles is between `goldMinPiles` and `goldMaxPiles` inclusive
- server_updateGold(), which sends a network protocol `GOLD` message to update all players on the status of gold
- server_sendMapfile(), which sends network protocol messages to a player that show the player's map
- server_receiveKey(), which handles a client's `KEY` message
- game_end() which ends the game
And some helper modules:
- *map* contains all the data needed to render a given map
- **counter** of map gold locations
### Pseudo code (plain English-like language) for logic/algorithmic flow
```
Parse the command line arguments,
if they are invalid,
send an error message and exit
initialize the map, exiting on error
place the gold and players, exiting on error
continuously listen for a connection, exiting with error on timeout
when a connection is established with client,
validate the display size
validate the player(s)
validate the spectator, booting out the current one
if any of these fail, send an error message to client
for each player, place them on the map and send a message
continously listen for message from client
if a player/spectator sends 'Q',
close their port and handle their exit
if the key is a movement key,
validate the movement and move their ID location
if the numGold is 0,
perform gameEnd operations
```
execute from a command line per the requirement spec
parse the command line, validate parameters
call initializeGame() to set up data structures
initialize the 'message' module
print the port number on which we wait
call message_loop(), to await clients
call gameOver() to inform all clients the game has ended
clean up
### Major data structures
The `Map` helper module which is described in the implementation specs.
The server will also implement the following,
A **player struct**, with the following properties:
```c
typedef struct player {
char* portID;
char playerID; // uppercase character: A, B, C,...
char* playerName; // name of player passed in
int* playerLocation; // size: 2; x,y coordinate of player
int numGold; // number of gold found by this player
int** playerVision; // size: grid width * grid height
int visibleCoordCount; // number of coordinates player can see
bool visionFull; // flag for whether or not a player has seen all the spots on the map
} player_t*;
```
We store all the players in an array with their playerID as the index. We initialize the array to be maxPlayers. we calculate the index by, index = playerID - 'A'
```
int allplayers[26] = {playerA, playerB, ...}
```
A **counter** of map gold locations to the remaining gold in the location
A **game struct** with the following properties:
```c
typedef struct game {
player_t** allplayers;
int numRows;
int numCols;
char** map; // the map as an array for easy information retrieval
counters_t* goldPiles;
} game_t*;
```
### Testing plan
**Unit Testing**
The **Server Module** can be tested by passing client commands using the client module provided in `~/cs50-dev/shared/nuggets/linux` directory. Some tests we can run are:
- Various forms of invalid arguments to server
- Player on our server using the provided client and player
- Player on our server using the provided client and player as a bot
- Write a script to play as 26 background bots, botbg, to see how well out server handles
- Run the server overloaded, i.e. with 26 players or bots, and with valgrind to test for memory leaks and errors
- Have all the players leave mid game
**Methodology**
The server can also print out input received from the client and vice versa. This would confirm that the server receives and responds to client properly. When the map module functions properly, the server could also make calls to map functions and print out map grids to further demonstrate functionality.
## Client
### User interface
The interface is the command line with inputs:
```
./client hostname port [playername]
```
The user also enters commands to interact with the game. These commands are:
- `Q` quit the game.
- `h` move left, if possible
- `l` move right, if possible
- `j` move down, if possible
- `k` move up , if possible
- `y` move diagonally up and left, if possible
- `u` move diagonally up and right, if possible
- `b` move diagonally down and left, if possible
- `n` move diagonally down and right, if possible
- where possible means the adjacent gridpoint in the given direction is an empty spot, a pile of gold, or another player.
- for each move key, the corresponding Capitalized character will move automatically and repeatedly in that direction, until it is no longer possible.
### Inputs and outputs
Input:
- The client reads the hostname and port from the command-line which allows it to connect to the server.
- The client reads keystrokes from the user to control player movement.
- The client receives the map from the server in the form of one string.
- The client receives these message types from the server, per network protocol: `OK`, `GRID`, `GOLD`, `DISPLAY`, `QUIT`, and `ERROR`.
Output:
- The client outputs commands received from the user to the server, as described above.
### Functional decomposition into modules
We anticipate the following modules or functions:
- client_init(), which instantiates the display and connects to server
- client_send(), which sends a keystroke in the form of a `KEY` message to the server
- client_receive(), which handles network protocol input from the server
- client_display(), which prints the player's visible map to the display
We will also make extensive use of the ncurses library
### Pseudo code for logic/algorithmic flow
```
Parse and verify the command line arguments
if invalid
print error message and exit
Connect to server with hostname and port
If playername provided
join server as a player
Else
join server as a spectator
Initialize the display
When GRID message received
verify display size large enough
print status line and game grid to display
While stdin can still be read
send user keystrokes to server
update display with server updates
Print game over message
```
### Major Data Structures
We do not anticipate the use of major data structures for the client
### Testing Plan
*Unit Testing*:
The **Client Module** can be tested by:
- Running the client and logging when it sends messages to be sure we are sending the correct thing
- Playing the game using the server module provided in the `~/cs50-dev/shared/nuggets/linux` directory to ensure that our client can progressively play the game with no trouble on the server
- Run the client with valgrind to test for memory leaks and errors
## System and Integration Testing:
The entire system can be tested together by creating a server and joining it from multiple client devices. The game can then be played and tested to make sure that all game mechanics work properly. Mechanics that should be tested include:
- Player movement
- Walls
- Passages
- "capital letter" movement/sprinting
- Player visibility
- Player - Player interactions
- Player quit
- Game end
- Gold count
- Playing with the maximum number of players, 26
- Spectator View