Skip to content

Latest commit

 

History

History
258 lines (210 loc) · 10 KB

DESIGN.md

File metadata and controls

258 lines (210 loc) · 10 KB

CS50 Nuggets

Design Spec

In this document we reference the REQUIREMENTS.md and focus on the implementation-independent design decisions. Here we focus on the core subset:

  • User interface
  • Inputs and outputs
  • Functional decomposition into modules
  • Pseudo code (plain English-like language) for logic/algorithmic flow
  • Major data structures
  • Testing plan

User interface

As described in the Requirements Spec, the nugget’s interface with the user is initially through the command line when the user creates the server or connects to the server. Once the game starts, the user interacts with the program with their keyboard.

$ ./server map.txt seed
$ ./client hostname port [playername]

The user also interacts with the game through the client side through stdin. Allowing the player to move about and quit the game. The server has no more user interaction after being called.

Check the Requirements Spec to see the specific keystrokes available to the client

Inputs and outputs

Input: when creating the server, the user must provide the server the map text file. Once the game has started, the user provides input to the program exclusively through keystrokes from the keyboard to stdin.

Output: the output is the map display updated to player movements and game events updated by the server and pushed out to all of the clients.

Functional decomposition into modules

We anticipate the following modules or functions:

SERVER MODULE

server runs the server and parses and receives Messages from Clients, sends relevant visible maps for all players. Handles all the GameLogic and initializes the map.

  1. main, parses args, Seeds randomness initializes Game, start networkServer(MessageLoop)
  2. initializeGame, placeGold, make Map

SERVERCMDS MODULE

  1. movePlayer, gets a direction and a player and does a move for that player and collects gold, true on all gold collected
  2. joinUser, adds a player, calls ensureDimensions on player, and places them on the map also can add a user as a spectator if name is NULL
  3. leaveUser, gets a player and removes them from the game
  4. sendDisplays, (Static) send visible map (get it via getVisibleMap) and the relevant information that's displayed at the top of the screen. To all players.
  5. endGame, (Static) disconnect everyone, give them Scoreboards

CLIENT MODULE

client sends keystrokes and join msg; Displays the visible map for players and the end game screen

  1. Main Parses args, connects to the server, Start N Curses, start NetworkPlayer(MessageLoop)

CLIENTCMDS

  1. Display Display what the server sends to the client
  2. DisplayHeader Displays the string on the top of the screen, which provides relevant game information to the client.
  3. DisplayAction Writes an action message on the viewer given a char*
  4. EnsureDimensions Called by join server and loops on player until they have the right dimensions
  5. QuitClient Called if server finishes or player quits, called from server, returns true. Upon receiving a QUIT message the client shall exit curses, print the explanation followed by a newline, and exit.

And some helper modules that provide data structures:

  1. gameInfo Struct holding number of gold piles left, amount of gold left, and a PlayerInfo array also holds the map struct
  2. grid Struct to hold a map of characters that can be interacted with 2d coordinates to get and set. Has toString and parseFromString
  3. map Struct to hold BaseGrid and GameState Grid, functions to send display to players, setPlayerPos, Place Gold, and a function to return a visible map from a sight grid
  4. playerInfo Struct to hold player-specific info such as location (x and y coordinates), gold collected, playerID, and address.
  5. pos2D Struct wrapper for x and y coordinates, has getX and getY also has Set function
  6. Visibility Module that provides a function to check if one point is visible from another given a map.
  7. Network Runs message.h and handles messages and timeouts, parses them and translates them to functions which must be called on the player

Pseudo code for logic/algorithmic flow

The server will run as follows:

parse the command line, validate parameters, initialize other modules
create gameInfo struct
initalizes the game
start network server
    get messages - parse them
    call appropriate functions on server

InitializeGame

read the map file
create two grid for that map
create the map struct
place gold in map

ServerCmds will run as follows

MovePlayer

getplayerpos and cmd/direction
if not a sprint
    use one shortMove
if sprint,
    loop through shortMove until shortMove false
    send new game state
if no more gold
    endgame
    return true

Helper ShortMove:

take move dir
find adjacent pos
if wall
    return false
if gold
	add Score to player
    use TakeOutGold to remove it
if another player
	save playerID
setPlayerPos to the pos (map SetPlayerPos)
if replaced another player
	setPlayerPos of other player to old pos (map SetPlayerPos)
return true

JoinPlayer

if player terminal size is not big enough,
    call JoinFail on client with size needed
    return early
if there is space for another player,
    Create a new playerInfo struct to insert into the array of players (stored in gameInfo struct)
    Assign the new player a location on the map and place them there
    Send all players the updated map
else,
    Send the player a rejection message

JoinSpectator

if there is a current spectator,
    Kick them off the server
let the new spectator connect
send the player a join message
messageLoop
    receives display input from the server
    if spectator presses “q”,
        send a quit message to the server and disconnect spectator.

LeavePlayer

take Player off the map  (GameInfo removePlayer)
delete corresponding playerInfo
send new Game State (Map SendNewGameState)
if no more players,
    endGame
    return true

EndGame

construct a scoreboard (GameInfo)
send a scoreboard of all the gold collected and other relevant information to the players 
send a quit message to all of the players
close down the server

The client will run as follows:

parse the command line args, validate parameters
connect to the server and send it an initialization message
start nCurses
starts NetworkPlayer (MessageLoop)
    display what the server sends the client
    send keystrokes to the server through the handleInput function in MessageLoop
try to call JoinPlayer on server
quit when the user presses “q” or when a quit message is received from the server

ClientCmds will run as Follows

Display

Clear out the old N curses display
take a string
print it with nCurses use addch(c) and move cursor
through the entire display to print each given character

DisplayHeader

Construct a header message
Spectator: for a spectator
Player A has p nuggets otherwise
Call display action if we received gold
print out the decided on header to the top in ncurses

DisplayAction

Check args
get the string
move to top right 
and print the string backwards

ensureDimensions

Get the dimensions
loop until the screen is large enough for it
print message asking to fix screen

quitClient

exit curses with endwin()
print the explanation passed in the quit message
exit main with zero;

Major data structures

Helper modules provide all the data structures we need:

  • gameInfo holds all the major data structures needed to run the game
  • array playerIDs are the indices, the array stores playerInfo structs
  • map holds the base grid and gamestate grid along with various methods
  • grid base grid: holds the original base map.txt
  • grid gamestate grid: hold the current state of the game
  • grid sight grids: holds what a particular player can see
  • playerInfo struct to hold the information of a single player

Testing plan

For testing, we plan to run the server from a local host as well as remotely, connecting multiple clients to test connection, as well as running the program.

A sampling of tests that should be run:

  • Using the provided “bot mode” to test multiple players at once while running the server
  • Test erroneous cases - such as using bot mode to connect a number of players over the player count and joining as a spectator once a spectator is already connected.
  • Test player collisions during gameplay to ensure proper switching
  • Test tunnels to make sure players can only see one space in front of them
  • Test connecting from multiple clients remotely to make sure network connections are running as needed
  • Check error logs to make sure all tests are run correctly → print stderr and stdout to testing.out while running the program
  • Test multiple map sizes to make sure the program reads in map text files and assembles grid layouts correctly

Division of work

In the interest of efficiency, it makes sense to have each person work on modules of the project that are co-dependent. This allows each individual team member to build knowlege on one section of the project, without needing to know the nitty gritty detailed of every module. It also streamlines the workflow, as each team member is responsible for writing the code that their future code is dependent on, ensuring that we spend little to no time waiting on others to finish modules.

When writing the modules, if functionality from one module is requisite for functionality in another, team members are to assume that the functions being borrowed from other modules do exactly as described without fail. This allows for individuals to complete their code in the absence of worrying about functionality on the part of the others, thus enhancing efficiency.

General Responsibilities James: Visibility Module & Testing, Server Main, Move, displayHeader, leaveUser, & Server Testing Will: Grid Module & Testing, Map Module & Testing, Various Functions in Player.c, Player EnsureDimensions Spencer: GameInfo Module & Testing, Pos2D module, server endGame, Player Testing Alan: Network Module & Testing, Server join User, server leave User, server endGame, display, display action