Zhoucai
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # CS50 nuggets ## Implementation Spec ## Detailed pseudo code for each of the objects/components/functions, ### server.c #### main: ```c parseArgs() if (port != 0) { message_loop(NULL, 0, NULL, handleInput, handleMessage); } exit(0) ``` #### parseArgs: ```c check correct arguements exit if wrong open map file exit if file can not be opened close file if seed is provided set seed variable if seed is invalid or positibe, exit else set seed to -1(will be set later) ``` #### Initialize game: Intializes game struct and variables inside. Then intializes map and places gold in the map. ```c game_t game = mem_malloc(sizeof(game_t)) call intializeMap(map textName) inside intializeMap(): calculate a random amount of gold piles between Max and Min create grid_t* map and load map in from txtfile using grid_loadgrid(maptext); set game->NR = grid_getNR(map) set game->NC = grid_getNR(map) set game->game = map set game->spectator = NULL allocate memory for game->playersArray if memory allocation fails return false call game_placegold(int number of game piles) inside game_placegold(): set int disperse to random number between 1 and 7 which will be how far apart we disperse for(int i = disperse; i + disperse < indices && piles > 0; i += disperse) if(map[i])=='.' map[i] = '*'; // set it equal to a gold piece subtract from number of piles ``` #### handleMessages: handles incoming messages from clients, changes the game accordingly, and broadcasts the changes to all connected clients ```c if(single char input){ call handleSingleChar(): if(char=='h') move left if possible else if(char=='H') sprint left if possible else if(char=='l') move left if possible else if(char=='L') sprint right if possible else if(char=='j') move down if possible else if(char=='J') sprint down if possible else if(char=='k') move up if possible else if(char=='K') sprint up if possible else if(char=='y') move diagonal up left if possible else if(char=='Y') sprint diagonal up left if possible else if(char=='u') move diagonal up right if possible else if(char=='U') sprint diagonal up right if possible else if(char=='b') move diagonal down left if possible else if(char=='B') sprint diagonal down left if possible else if(char=='n') move diagonal down right if possible else if(char=='N') sprint diagonal down right if possible else if(char=="Q") if client is spectator remove spectator from game struct else remove player from grid send quit message to client else send message to client message is unreadabele if any movement occured check if any gold was collected if gold was collected update game struct if gold collected is game ending move handle endGame() return false; }else{ Split first word from rest of String call handleFirstWord(): if first word is "PLAY" if player number exceeds limit send client message game is full else create player assign symbol to player put player into game struct send grid, gold, and display messages to client else if first word is "SPECTATE" If game has a current spectator Send message to current spectator to quit Forgot current spectator Create a new Spectator Struct for the new spectator. else send message to client it is unreadable error message broadcast to all clients updated display. return true } ``` #### is_visible: Calculates what will be visible for a player ```c bool is_visible(const double pc, const doube pr, const double c, const double r); find the difference in y and x calculate the slope and constant if line is either vertical or horizontal set the equation of the line appropriately loop over the columns from pc to c (non-inclusive) if is grid point if not room spot return false else check the floor and ceil if neither point is room spot return false loop over pr to c (non-inclusive) if is grid point if not room spot return false else check the floor and ceil if neither point is room spot return false return true ``` #### endGame: handles end of game sequence. ```c broadcast to all clients quit message with gameover summary print GameOver summary. free all allocated memory return false ``` ### Player.c #### main: ```c parseArgs() if set_address(hostname, port, &serverAddress) succeeds if playername exists send "PLAY playername" message to server else send "Spectate" message to srver else set_address failed print error message message_loop(NULL, 0, NULL, handleInput, handleMessage); free allocated memory. ``` #### parseArgs: ```c if incorrect number of arguements print error message copy host name, playername, and port from input ``` #### handleStdin: ```c while(line=file_readline(stdin)!=NULL) send stdin string as message to server ``` #### handleMessages: handles incoming messages from server, changing info and display accordingly. ```c initialize player or spectator struct from arg create array of tokenized message words store client's window/display coordinates if GRID message if not valid message print error malformed message while window not large enough inform client update coordinates if QUIT message if not a valid message print error malformed message exit curses print quit explanation free allocated memory exit if GOLD message if not valid message print error malformed message initialize nugsGrabbed initialize purseTotal initialize nugsRemaining if client is a spectator Print spectator display message if client is a player Print player display message if nugsGrabbed > 0 Print gold update if DISPLAY message print the display message to display refresh display free all words in messageArray free messageArray ``` ### Grid.c #### grid_loadgrid(char* mapTextName): loads the map file into a a char* map inside the grid_t struct. ```c Allocate memory to grid_t* grid if grid or MapTextName are null return null Open file mapTextName if failed to open return null set number of rows to file_numLines(fptr) set number of Cols to find_NC(textfile) open file using mapTextName allocate memory to string char* map set int idx =0 to be used to traverse through map string while(can read lines from file) for(int i = 0; i<number of Cols; i++) if i>= the length of the line set map[idx]=' ' else set map[idx]=[i] idx++ set grid->NC to number of columns set gird->NR to number of rows set grid->map to map string return grid ``` #### grid_findNC: finds the number of columns in a map given the map file. ```c declare int maxlen, currlen, linenum while(can readline from file) if at first line currlen = strlen(line) maxlen=currlen change linenum tracker so you are no longer at first line else currlen=strlen(line) if currlen>maxlen maxlen=currlen; close the file return maxlen ``` ## Definition of detailed APIs, interfaces, function prototypes and their parameters ### Function Prototypes server.c: ```c static bool game_initializemap(char* maptext,int seedin); static bool game_placegold(int numpiles,int seedin); static bool game_calculategoldvalues(int seedin); static void parseArgs(const int argc, char* argv[], char** map, int* seed); bool handleTimeout(void* arg); bool handleInput(void* arg); bool handleMessage(void* arg, const addr_t from, const char* message); void broadcast(char* message); player_t* getPlayer(player_t** playerArray, char playerSymbol); bool move(player_t* player, int newX, int newY); bool handlePlayerMovement(char key, player_t* player); ``` player.c: ```c static void parseArgs(const int argc, char* argv[], char** hostname, char** port, char** playername); bool handleTimeout(void* arg); bool handleInput(void* arg); bool handleMessage(void* arg, const addr_t from, const char* message); ``` ## Data structures (e.g., struct names and members) ### Game Struct - Server This game structure holds a `grid_t` pointer, an array of player pointers, and the variables hold the number of gold total, the minimum number of gold piles, the maximum number of gold piles, and the other variables defined in the requirement specs. We also hold a pointer to a spectator object. This game struct is in the server file and allows us to pass around these variables as one global variable of a game struct. ### Array of Player Pointers - Server In our server file, we use an array of pointers to player objects to keep track of the players in our game. This array of player pointers is held inside of the game struct object that is the global variable in our server.c ### Player Struct - Server We created a player structure that will hold the player’s name as a string, their address held in an `addr_t` object, their symbol character(A-Z), and the number of gold that they currently have. This player object also holds their own grid object that has that player’s version of the map based on their current visibility. This structure will only be present in the server file. ### Spectator Struct - Server We created a spectator structure that holds an integer `r` which represents the amount of gold left in the game, a grid pointer that holds the most updated version of the game’s ‘all seeing map’, and `addr_t` object that holds this spectator’s address for the game to use to send messages, and two integers, one to hold number of columns and the other to hold the number of rows. This structure is only present in the server file. ### Grid Struct - Server & Client This data structure that we created deals with modifying the characters of the map, which is a string representation of the Map textfile passed as an argument to `server.c`. The server file is going to have the map that has all the characters at their correct locations and the current gold piles left, this grid will be held in the game structure object. Each player is going to have their own grid object too in the client file that the server can access and modify. Each spectator is going to have their own grid object holding the same map as the server in its own respective client file. Each grid object is also going to hold two integers, one for the number of columns in the map and one for the number of rows in the map. So the grid structure will appear both in the client and server files. ## Other Modules Detailed descriptions of each function's interface is provided as a paragraph comment prior to each function's declaration in player.h, spectator.h, and grid.h and is not repeated here. ### Player Module ```c // getters grid_t* player_getGrid(player_t* player); char* player_getHostName(player_t* player); char* player_getPort(player_t* player); char* player_getName(player_t* player); int player_getX(player_t* player); int player_getY(player_t* player); char player_getPlayerSymbol(player_t* player); char player_getJustStepped(player_t* player); addr_t player_getAddress(player_t* player); // setter grid_t* player_setGrid(player_t* player, grid_t* grid); char* player_setHostName(player_t* player, char* hostName); char* player_setPort(player_t* player, char* name); char* player_setName(player_t* player, char* name); int player_setX(player_t* player, const int x); int player_setY(player_t* player, const int y); char player_setPlayerSymbol(player_t* player, char playerSymbol); char player_setJustStepped(player_t* player, char justStepped); ``` ### Spectator Module ```c spectator_t* spectator_new(addr_t addressIn, int NC, int NR); void spectator_delete(spectator_t* spectator); Void spectator_setr(spectator_t* spectator, int rin); int spectator_getr(spectator_t* spectator); void spectator_displaygrid(spectator_t* spectator, char* mainmap); ``` ### Grid Module ```c grid_t* grid_loadgrid(char* txtfile); int grid_getNC(grid_t* grid); int grid_getNR(grid_t* grid); char grid_getchar(grid_t* grid, int x, int y); bool grid_setchar(grid_t* grid, char c, int x, int y); void grid_display(grid_t* grid); void grid_delete(grid_t* grid); ``` ## Error Handling and Recovery All the command-line parameters are rigorously checked before any data structures are allocated or work begins; problems result in a message printed to stderr and a non-zero exit status. Out-of-memory errors are handled by variants of the `mem_assert` functions, which result in a message printed to stderr and a non-zero exit status. The code utilizes defensive programming practices to ensure functions are not being given bad variables. Many functions return booleans, which allow the program to ensure a function was successful (returned true) before moving on with the game. This approach to defensive programming allows the game to continue safely and not use any bad variables, but does not trigger a fatal error that would end the game. Additionally, most variables and data structures are null checked before continuing, to ensure data was initialized correctly. ## Testing plan Our group first created our grid module and created a c program that tested to make sure that the grid loaded properly from the map textfile. This c program also made sure that our grid module calculated the number of collumns and number of rows correctly for each of the map textfiles provided in the maps directory. This test also made sure that our grid functions getchar and putchar could either put a character or get a characters at a certain x and y coordinate on the map. We then created a testing script to run though each of these map textfiles to test the functions in the grid module and print their output to testing.out file. Our next test was testing our static functions in the server.c file that place random gold piles on room spots in the game's map. We created a c program to test this and a corresponding testing script to run through the different map textfiles and make sure that the correct amount of gold piles are being placed in the valid room spots on each map. To test our message handling, we made sure that the messages were being sent correctly between the client in server by printing out the parsed message after we handled it. We also make sure that when we pressed a key, that our program was responded correctly by moving the player to the right spot on the map. To test our spectator, we made sure that the spectator would receive its gold message correctly and that it would display the same version of the map as the map held in the server. We did this by running a basic server.c program and a player.c program that only created a spectator and had it display its map after the server.c sent its DISPLAY message. ## To-Do list / Division of Work 1. Visability function - `Zhoucai Ni` 2. ParseArgs (client & server) - `Devon Parker` 3. Message/input Handlers (client) - `Devon Parker & Victoria Shaw` 4. Message/input Handlers (server)- `Victoria Shaw` 5. Handle Player Movement - `Devon Parker` 6. Game Struct - `Tanner Rosa` 7. Player Struct - `Zhoucai Ni` 8. Spectator Struct - `Tanner Rosa` 9. Grid struct - `Tanner Rosa` 10. Debugging - `Everyone` 11. Mem leaks - `Victoria Shaw & Zhoucai Ni` 12. Testing/Test files - `Victoria Shaw & Zhoucai Ni`

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully