Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Bots have been in the news for doing negative things such as spreading fake news. Your task in this assignment is to write a bot

Bots have been in the news for doing negative things such as spreading fake news.

Your task in this assignment is to write a bot that makes the world a better place.

Your bot will pilot a drone which ferries fruit to UNSW students so they stop eating junk food, have a healthy diet.

Your bot must successfully buy, transport and sell fruit in a simulated world.

You will write a C program to implement this bot.

STARTING CODE

// fruit_bot.c // Assignment 3, COMP1511 18s1: Fruit Bot // // This program by YOUR-NAME-HERE (z5555555) on INSERT-DATE-HERE // // Version 1.0.0: Assignment released. // Version 1.0.1: minor bug in main fixed #include  #include  #include "fruit_bot.h" void print_player_name(void); void print_move(struct bot *b); void run_unit_tests(void); // ADD PROTOTYPES FOR YOUR FUNCTIONS HERE // YOU SHOULD NOT NEED TO CHANGE THIS MAIN FUNCTION int main(int argc, char *argv[]) { if (argc > 1) { // supply any command-line argument to run unit tests run_unit_tests(); return 0; } struct bot *me = fruit_bot_input(stdin); if (me == NULL) { print_player_name(); } else { print_move(me); } return 0; } void print_player_name(void) { // CHANGE THIS PRINTF TO YOUR DESIRED PLAYER NAME printf("Botty McBotbot"); } // print_move - should print a single line indicating // the move your bot wishes to make // // This line should contain only the word Move, Sell or Buy // followed by a single integer void print_move(struct bot *b) { // THE LINES BELOW IMPLEMENT A SIMPLE (USELESS) STRATEGY // REPLACE THEN WITH YOUR CODE int silly_choice = b->turns_left % 3; if (silly_choice == 0) { printf("Move 1 "); } else if (silly_choice == 1) { printf("Sell 1 "); } else { printf("Buy 1 "); } } // ADD A COMMENT HERE EXPLAINING YOUR OVERALL TESTING STRATEGY void run_unit_tests(void) { // PUT YOUR UNIT TESTS HERE // This is a difficult assignment to write unit tests for, // but make sure you describe your testing strategy above. } // ADD YOUR FUNCTIONS HERE

FRUIT_BOT.h

// DO NOT CHANGE THIS FILE // DO NOT ADD LINES TO THIS FILE // DO NOT DELETE LINES FROM THIS FILE // DO NOT CHANGE THIS FILE // Fruit Bot - https://cgi.unsw.edu.au/~cs1511/assignments/ass3/ // header guard: https://en.wikipedia.org/wiki/Include_guard // This avoids errors if this file is included multiple times // in a complex source file setup #ifndef FRUIT_BOT_H #define FRUIT_BOT_H // These constants are upper bounds on various features of the Fruit Bot world // You may not need to use any of these constants in your program. #define MAX_TURNS 999 #define MAX_LOCATIONS 2048 #define MAX_BOTS 2048 #define MAX_FRUIT_TYPES 128 #define MAX_NAME_CHARS 64 #define MAX_SUPPLIED_BOT_NAME_CHARS 32 // Description of the state of a single bot // // name - unique string of between 1 and MAX_NAME_CHARS (does not change during simulation) // // location - pointer to struct representing bot's current location, never NULL // // cash - how much cash the bot has // // battery_level - how many kJ in the bot's battery - reduces by 1 kJ for every location bot moves // // fruit - name of the fruit bot is carrying (between 1 and MAX_NAME_CHARS) // note bots may only carry one type of fruit at a time // NULL if the bot is not carrying fruit // // fruit_kg - how many kg of fruit the bot is carrying // // turns_left - turns left in simulation, always > 0 (reduces by 1 every turn) // // battery_capacity - maximum kJ bot's battery can hold // // maximum_move - maximum number of location bot can move // // maximum_fruit_kg - maximum kg of fruit bot can carry // // battery_capacity, maximum_fruit_kg, maximum_move are the same for all bots // and do not change during the simulation. // // name is different for every bot and does not change during the simulation struct bot { char *name; struct location *location; int cash; int battery_level; char *fruit; int fruit_kg; int turns_left; int battery_capacity; int maximum_move; int maximum_fruit_kg; }; // Description of a location in the fruit bot world // // name - unique string of between 1 and MAX_NAME_CHARS (never NULL) // // fruit - name of the fruit this location buys/sells // string of between 1 and MAX_NAME_CHARS (never NULL) // if fruit == "Anything" location buys any fruit // fruit == "Electricity" is a special case, bots can recharge by buying electricity // note some locations have fruit == "Nothing" and price == 0 & quantity == 0 // // price - price at which this location sells/buys a kg of fruit or, kJ of electricity // a positive price indicates this location only buys fruit // a negative price indicates this location only sells fruit or electricity // a price of zero indicates location does not buy or sell anything // price does not change during the simulation // // quantity - a non-negative number indicating how many units of fruit/electricity // this location currently has available to buy or sell // quantity never increases during the simulation // it reduces by n kg/kJ when a bot buy/sells n kg/kJ at this location // // bots - pointer to a linked list of bots currently at this location (NULL if no bots at this location) // // // east - pointer to struct representing next location east, never NULL // The east fields of locations link them in a circular list // // west - pointer to struct representing next location west, never NULL // The west fields of locations link them in a circular list // but in the reverse direction to east fields. // struct location { char *name; char *fruit; int price; int quantity; struct location *east; struct location *west; struct bot_list *bots; }; // linked list of bots // // bot - pointer to a struct representing a bot // // next - points to remainder of list // next is NULL if there are no more bots in list struct bot_list { struct bot *bot; struct bot_list *next; }; struct bot *fruit_bot_input(FILE *stream); #endif

FRUIT_BOT_INPUT.c

// DO NOT CHANGE THIS FILE // DO NOT ADD LINES TO THIS FILE // DO NOT DELETE LINES FROM THIS FILE // DO NOT CHANGE THIS FILE //v0.2 fix bug where some locations have l->fruit == NULL // Fruit Bot - https://cgi.unsw.edu.au/~cs1511/assignments/ass3/ #include  #include  #include  #include  #include  #include "fruit_bot.h" #define FRUIT_MARKER " kg of " #define ALTERNATE_FRUIT_MARKER " kJ of " #define FRUIT_END_MARKER " for " #define BATTERY_MARKER "battery level: " #define TURN_MARKER "*** Turn " #define TURN_NEXT_MARKER " of " #define YOU_ARE_MARKER "*** You are" #define MAX_LINE_CHARS 65536 static int parse_starting_parameter(char line[], struct bot *prototype_bot); static int parse_turn(char line[], struct bot *prototype_bot, int n_bots, struct bot *bots[MAX_BOTS]); static struct bot *parse_you_are(char line[], int n_bots, struct bot *bots[MAX_BOTS]); static struct location *parse_location(char line[], int n_locations, struct location *locations[MAX_LOCATIONS]); static struct bot *parse_bot(char line[], struct bot *prototype_bot, int n_locations, struct location *locations[MAX_LOCATIONS]); static char *sstrdup(char *s); static void *salloc(size_t n_bytes); // read a decsription of fruit bot from stdin // return NULL if no description can be read struct bot *fruit_bot_input(FILE *stream) { int debug = 0; char line[MAX_LINE_CHARS]; struct bot prototype_bot = { .cash=100, .battery_level=100, .maximum_move=7, .maximum_fruit_kg=15, .battery_capacity=100, .turns_left=100 }; int n_locations = 0; struct location *locations[MAX_LOCATIONS]; int n_bots = 0; struct bot *bots[MAX_BOTS]; struct bot *me = NULL; while (fgets(line, sizeof line, stream) != NULL) { // trim trailing white space char *p = line + strlen(line) - 1; while (p >= line && isspace(*p)) { *p = '\0'; p = p - 1; } char original_line[MAX_LINE_CHARS]; strncpy(original_line, line, MAX_LINE_CHARS); original_line[MAX_LINE_CHARS - 1] = '\0'; if (debug) { fprintf(stderr, "line='%s' ", line); } int parse_result = 1; if (line[0] != '"' && line[0] != '*' && !isalpha(line[0])) { // skip line } else if (strncmp(line, TURN_MARKER, strlen(TURN_MARKER)) == 0) { parse_result = parse_turn(line, &prototype_bot, n_bots, bots); } else if (strncmp(line, YOU_ARE_MARKER, strlen(YOU_ARE_MARKER)) == 0) { me = parse_you_are(line, n_bots, bots); parse_result = !!me; } else if (line[0] == '"') { assert(n_bots < MAX_BOTS); bots[n_bots] = parse_bot(line, &prototype_bot, n_locations, locations); parse_result = !!bots[n_bots]; n_bots++; } else if (strchr(line, ':')) { assert(n_locations < MAX_LOCATIONS); locations[n_locations] = parse_location(line, n_locations, locations); parse_result = !!locations[n_locations]; n_locations++; } else if (!n_locations && strchr(line, '=')) { parse_result = parse_starting_parameter(line, &prototype_bot); } if (!parse_result) { fprintf(stderr, "Error: bad line in world description: '%s' ", original_line); exit(1); } if (debug) { fprintf(stderr, "parse_result=%d n_bots=%d n_locations=%d me=%p ", parse_result, n_bots, n_locations, me); } } for (int i = 0; i < n_locations; i++) { locations[i]->east = locations[(i + 1) % n_locations]; locations[i]->west = locations[(n_locations + i - 1) % n_locations]; } if (me) { return me; } if (n_bots) { return bots[0]; } return NULL; } // parse a line saying what simulation turn this and update all bots appropriately // return 1, if successful, 0 otherwise static int parse_turn(char line[], struct bot *prototype_bot, int n_bots, struct bot *bots[MAX_BOTS]) { char *p = strstr(line, TURN_MARKER); if (!p) { fprintf(stderr, "Error: missing turn marker "); return 0; } p += strlen(TURN_MARKER); int turn = atoi(p); if (!turn) { fprintf(stderr, "Error: turn "); return 0; } p = strstr(p, TURN_NEXT_MARKER); if (!p) { fprintf(stderr, "Error: missing turn next marker "); return 0; } p += strlen(TURN_NEXT_MARKER); int n_turns = atoi(p); if (!n_turns) { fprintf(stderr, "Error: missing n_turn "); return 0; } int turns_left = n_turns - turn + 1; prototype_bot->turns_left = turns_left; for (int i = 0; i < n_bots; i++) { bots[i]->turns_left = turns_left; } return 1; } static struct bot *parse_you_are(char line[], int n_bots, struct bot *bots[MAX_BOTS]) { char *p = strchr(line, '"'); if (!p) { fprintf(stderr, "Error: you are line missing opening quote "); return NULL; } p++; char *q = strchr(p, '"'); if (!q) { fprintf(stderr, "Error: you are line missing closing quote "); return NULL; } *q = '\0'; for (int i = 0; i < n_bots; i++) { if (strcmp(bots[i]->name, p) == 0) { return bots[i]; } } fprintf(stderr, "Error: you are line bot '%s' not found ", p); return NULL; } // parse a line specifying a simulation parameter and update prototype bot appropriately // return 1, if successful, 0 otherwise static int parse_starting_parameter(char line[], struct bot *prototype_bot) { char *p = strchr(line, '='); if (!p || p == line) { return 0; } while (isspace(*p) && p > line) { p--; } *p = '\0'; int value = atoi(p + 1); if (value == 0) { return 0; } if (strcmp(line, "cash") == 0) { prototype_bot->cash = value; } else if (strcmp(line, "battery_capacity") == 0) { prototype_bot->battery_capacity = value; prototype_bot->battery_level = value; } else if (strcmp(line, "cash") == 0) { prototype_bot->cash = value; } else if (strcmp(line, "maximum_move") == 0) { prototype_bot->maximum_move = value; } else if (strcmp(line, "maximum_fruit_kg") == 0) { prototype_bot->maximum_fruit_kg = value; } return 1; } static struct location *parse_location(char line[], int n_locations, struct location *locations[MAX_LOCATIONS]) { struct location *l = salloc(sizeof *l); char *p = strchr(line, ':'); if (!p) { fprintf(stderr, "error: can not find name in location description "); return NULL; } *p = '\0'; l->name = sstrdup(line); for (int i = 0; i < n_locations; i++) { if (strcmp(locations[i]->name, l->name) == 0) { fprintf(stderr, "warning: ignoring duplicate location description '%s' ", l->name); free(l->name); free(l); return locations[i]; } } assert(n_locations < MAX_LOCATIONS); locations[n_locations++] = l; p = p + 1; char *q = strchr(p, '$'); if (q) { l->price = atoi(q + 1); if (!l->price) { fprintf(stderr, "error: can not find price in location description "); return NULL; } } q = NULL; q = strstr(p, "sell"); if (q) { l->price = -l->price; } else { q = strstr(p, "buy"); } if (!q) { l->fruit = sstrdup("Nothing"); return l; } p = q + strlen("buy") + 1; l->quantity = atoi(p); q = strstr(p, FRUIT_MARKER); if (q) { p = q; } else { p = strstr(p, ALTERNATE_FRUIT_MARKER); } if (!p) { l->fruit = sstrdup("Nothing"); return l; } p += strlen(FRUIT_MARKER); q = strstr(p, FRUIT_END_MARKER); if (q) { *q = '\0'; } l->fruit = sstrdup(p); return l; } static struct bot *parse_bot(char line[], struct bot *prototype_bot, int n_locations, struct location *locations[MAX_LOCATIONS]) { struct bot *b = salloc(sizeof *b); *b = *prototype_bot; char *p = strchr(line + 1, '"'); if (!p) { fprintf(stderr, "error: can not find closing quote for bot name "); return NULL; } *p = '\0'; b->name = sstrdup(line + 1); p = strchr(p + 1, '"'); if (!p) { fprintf(stderr, "error: can not find location for bot "); return NULL; } p++; char *q = strchr(p, '"'); if (!q) { fprintf(stderr, "error: can not find closing quote for bot location "); return NULL; } *q = 0; int i = 0; while (i < n_locations) { //fprintf(stderr, "locations[i]->name='%s' p='%s' ", locations[i]->name, p); if (strcmp(locations[i]->name, p) == 0) { break; } i++; } if (i == n_locations) { fprintf(stderr, "error: unknown location '%s' ", p); return NULL; } b->location = locations[i]; struct bot_list *bl = salloc(sizeof *bl); bl->bot = b; bl->next = b->location->bots; b->location->bots = bl; p = strchr(q + 1, '$'); if (!p) { fprintf(stderr, "error: can not find bot cash "); return NULL; } b->cash = atoi(p + 1); p = strstr(p, BATTERY_MARKER); if (!p) { fprintf(stderr, "error: can not find bot battery level "); return NULL; } p += strlen(BATTERY_MARKER); b->battery_level = atoi(p); p = strchr(p, ','); if (!p) { return b; } p++; b->fruit_kg = atoi(p); if (!b->fruit_kg) { fprintf(stderr, "Can not find bot fruit kg "); return NULL; } p = strstr(p, FRUIT_MARKER); if (!p) { fprintf(stderr, "error: can not find bot frtui "); return NULL; } p += strlen(FRUIT_MARKER); q = strchr(p, ':'); if (q) { *q = '\0'; } b->fruit = sstrdup(p); return b; } static char *sstrdup(char *s) { char *p = strdup(s); assert(p); return p; } static void *salloc(size_t n_bytes) { void *p = malloc(n_bytes); assert(p); memset(p, 0, n_bytes); return p; }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Intelligent Information And Database Systems 12th Asian Conference ACIIDS 2020 Phuket Thailand March 23 26 2020 Proceedings

Authors: Pawel Sitek ,Marcin Pietranik ,Marek Krotkiewicz ,Chutimet Srinilta

1st Edition

9811533792, 978-9811533792

More Books

Students also viewed these Databases questions

Question

3. Define the attributions we use to explain behavior

Answered: 1 week ago