Menu

(Solved) : Monster Database Lab Re Visit Monsters Stats Weapons Time Writing C Program Furthermore Da Q37177108 . . .

Monster Database

In this lab we re-visit our monsters, stats, and weapons butthis time we are writing a C program. Furthermore, the data for thelair of monsters will be read from, and written to, binaryfiles.

Program Structure

The general structure of the program is to start by displaying alist of (single letter) commands that the user can invoke. Fromthere, a while loop will continually prompt the user for a command,execute it, and loop back for the next. We’ll use a switch block tocreate the logic for invoking the appropriate function(s) tocomplete each command.

Starter Code

The started code contains:

  • the required #include statements
  • a couple of #defines for char array sizes
  • a predefined array of pointers to strings (C-style)
    • to be displayed as user information
  • the struct definitions for Weapon, Stats,Monster, and MonsterList
  • function prototypes for the required functions
  • a partial implementation of the main() function
  • TODO (N): comments indicating where coding is needed

The main() function

Required local variables are already defined and the basicstructure of the while loop is already written. You will need todefine casestatements within the switch block, to execute theappropriate actions for the commands entered by the user.

? – print this list of commands

Reprint the command list information.

r – read monster database (binary file)

Prompt for and read in a file name, (“DB file name (to read):”), then pass (by reference) both the monster list and theuser-entered file name to the function to read the monsterdatabase.

w – write monster database (binary file)

If there are no monsters currently loaded, print themessage:

(no monsters loaded)

Otherwise, prompt for and read in a file name, (“DB file name(to write): “), then pass (by reference) both the monster list andthe user-entered file name to the function to write the monsterdatabase.

d – display monsters

If there are no monsters currently loaded, print themessage:

(no monsters loaded)

Otherwise, display the list of monsters.

n – sort monsters by name (ascending)

If there are no monsters currently loaded, print themessage:

(no monsters loaded)

Otherwise, sort the monsters by name (inascending order), then immediately displaythem.

h – sort monsters by hitpoints (descending)

If there are no monsters currently loaded, print themessage:

(no monsters loaded)

Otherwise, sort the monsters by hitpoint values (indescending order), then immediately displaythem.

q – quit

Set the done flag, so that the while loop exits.

Function Prototypes

Utility Functions

Functions to display information to the user…

void printInfo();

  • start by printing a newline
  • iterate over the strings in the info array, and print eachone

void displayMonster(Monster *m);

  • print a single, formatted line displaying information about thegiven monster.
  • use the following format string: “%10s [a:%d, t:%d, hp:%2d]<%-15s mod:%2d>n”
    • The numbers in front of the placeholders will specifiy fieldwith. The negative in %-15s will make it left justified instead ofthe default right justified in %10s.
  • example output:

Skeleton [a:3, t:6, hp: 8] <long spear mod: 1>

void displayMonsters(MonsterList *monsters);

Iterate over the monsters in the list, to print them, one perline.

Sorting Functions

The Insertion Sort algorithm should be used toimplement in-place sorting of monsters in the monster array. Theonly difference between the two required sorts is in determiningwhether, given two monsters A andB, they need to be swapped or not. The next twofunctions serve to encapsulate just that determination:

int swapNeededName(Monster *a, Monster *b);

This utility function should compare the names of the givenmonsters, and return true (1) if they should be swapped (a’s name”comes after” b’s name), or false (0) otherwise.

int swapNeededHitPoints(Monster *a, Monster *b);

This utility function should compare the hitpoints of the givenmonsters, and return true (1) if they should be swapped (a’shitpoints are “fewer” than b’s hitpoints), or false (0)otherwise.

void sortMonsters(MonsterList *monsters, char sortType);

Implement the insertion sort on the array of monsters in thegiven MonsterList structure. The second parameter(sortType) will be the character ‘n’ if sorting by name isrequired, or ‘h’ if sorting by hitpoints is required.

Reading and Writing Binary Files

void readDb(MonsterList *monsters, char *fileName);

  • attempt to open the given file for reading binary (mode:”rb”)
  • if failed to open, print a message and return. For example:
    • Failed to open ‘no-such-file.bin’ for read
  • read a single integer from the file stream; this is how manymonster structs are stored in the binary file.
  • attempt to allocate a block of memory big enough to hold therequired number of monster structs.
    • if the allocation fails, print a message and return.
  • read the required number of monsters from the file stream, intothe allocated space.
  • close the file.

Be sure to use the size and list fields of the givenMonsterList struct as the destination for the reads.

Some samples showing possible messages displayed:

  • failed read:

DB file name (to read): no-such-file.binFailed to open ‘no-such-file.bin’ for read

  • successful read:

DB file name (to read): rabble1.bin1 items read from ‘rabble1.bin’ (size header)Allocating heap for 3 Monsters…memory allocated3 items read from ‘rabble1.bin’ (monster array)

  • failed memory allocation:

DB file name (to read): rabble1.bin1 items read from ‘rabble1.bin’ (size header)Allocating heap for 3 Monsters…failed to allocate memory!

Notice the trick of using a printf string without a terminatingnewline, (in the above examples the string “Allocating heap for 3Monsters…”), so that the outcome of the operation can be writtenat the end of that same line, with the next printf statement.

Your implementation will need to use the following librarycalls:

  • fopen()
  • fread()
  • malloc()
  • free()
  • fclose()

void writeDb(MonsterList *monsters, char *fileName);

  • attempt to open the given file for writing binary (mode:”wb”)
  • if failed to open, print a message and return. For example:
    • Failed to open ‘bad-file.bin’ for write
  • write a single integer to the file stream; this should be thevalue of the size field in the MonsterList struct.
  • write the monster array (the list field in theMonsterList struct) to the file stream.
  • close the file.

Sample output:

DB file name (to write): my-monsters.bin1 items written to ‘my-monsters.bin’ (size header)3 items written to ‘my-monsters.bin’ (monster array)

Your implementation will need to use the following librarycalls:

  • fopen()
  • fwrite()
  • fclose()

Hints

1) In your calls to fread and fwrite, be sure to capture thereturn value which tells you how many items were read, orwritten.

2) Don’t forget to cast the pointer returned from the malloccall to the type (Monster *), when you assign it to the list fieldof theMonsterList struct.

3) Make sure you free previously allocated memory beforeoverwriting the pointer with a new memory allocation.

4) It is possible to combine the cases of the commands d, n,and h with some carefully constructed logic. (This will reduce codeduplication).

A Sample Run

Enter a command: ? – print this list of commands r – read monster database (binary file) w – write monster database (binary file) d – display monsters n – sort monsters by name (ascending) h – sort monsters by hitpoints (descending) q – quit> d(no monsters loaded)> rDB file name (to read): rabble1.bin1 items read from ‘rabble1.bin’ (size header)Allocating heap for 3 Monsters…memory allocated3 items read from ‘rabble1.bin’ (monster array)> d Lizard [a:3, t:4, hp: 4] <spiked tail mod: 2> Dragon [a:4, t:6, hp: 9] <fire breath mod: 3> Archer [a:5, t:2, hp: 2] <long bow mod: 1>> aUnknown command `a`> n Archer [a:5, t:2, hp: 2] <long bow mod: 1> Dragon [a:4, t:6, hp: 9] <fire breath mod: 3> Lizard [a:3, t:4, hp: 4] <spiked tail mod: 2>> h Dragon [a:4, t:6, hp: 9] <fire breath mod: 3> Lizard [a:3, t:4, hp: 4] <spiked tail mod: 2> Archer [a:5, t:2, hp: 2] <long bow mod: 1>> wDB file name (to write): mydb.bin1 items written to ‘mydb.bin’ (size header)3 items written to ‘mydb.bin’ (monster array)> qthis is the starter code:

#include
#include

//———————————————————————–
// Some defines
#define NAME_MAX 64
#define BUFFER_MAX 256

// User instructions
const char *info[] = {
“Enter a command:”,
“”,
” ? – print this list of commands”,
” r – read monster database (binary file)”,
” w – write monster database (binary file)”,
” d – display monsters”,
” n – sort monsters by name (ascending)”,
” h – sort monsters by hitpoints (descending)”,
” q – quit”,
};
const int N_INFO = 9;

//———————————————————————–
// Structs

typedef struct Weapon_struct {
char name[NAME_MAX];
int damageModifier;
} Weapon;

typedef struct Stats_struct {
int agility;
int toughness;
int hitpoints;
} Stats;

typedef struct Monster_struct {
char name[NAME_MAX];
Stats stats;
Weapon weapon;
} Monster;

typedef struct MonsterList_struct {
int size;
Monster *list;
} MonsterList;

//———————————————————————–
// Function prototypes

void printInfo();
void displayMonster(Monster *m);
void displayMonsters(MonsterList *monsters);
int swapNeededName(Monster *a, Monster *b);
int swapNeededHitPoints(Monster *a, Monster *b);
void sortMonsters(MonsterList *monsters, char sortType);
void readDb(MonsterList *monsters, char *fileName);
void writeDb(MonsterList *monsters, char *fileName);

//———————————————————————–
// Main Program

int main() {
MonsterList monsters = {0, NULL};
char fileName[BUFFER_MAX];
char userIn[BUFFER_MAX];
char cmd;

printInfo();

int done = 0;
while (!done) {
printf(“n> “);
scanf(“%s”, userIn);
cmd = userIn[0];

switch (cmd) {
// TODO (1): ‘?’ command
// TODO (2): ‘r’ command
// TODO (3): ‘w’ command
// TODO (4): ‘d’ command
// TODO (5): ‘n’ command
// TODO (6): ‘h’ command
// TODO (7): ‘q’ command

default:
printf(“Unknown command `%c`”, cmd);
break;
}
}
return 0;
}

//———————————————————————–
// Function implementations

// TODO (8): void printInfo();
// TODO (9): void displayMonster(Monster *m);
// TODO (10): void displayMonsters(MonsterList *monsters);
// TODO (11): int swapNeededName(Monster *a, Monster *b);
// TODO (12): int swapNeededHitPoints(Monster *a, Monster*b);
// TODO (13): void sortMonsters(MonsterList *monsters, charsortType);
// TODO (14): void readDb(MonsterList *monsters, char*fileName);
// TODO (15): void writeDb(MonsterList *monsters, char*fileName);

//———————————————————————–

Expert Answer


Answer to Monster Database In this lab we re-visit our monsters, stats, and weapons but this time we are writing a C program. Furt…

OR