working till stage 3

 avatar
user_7863373
plain_text
2 months ago
37 kB
10
Indexable
// Assignment 2 26T1 COMP1511: CS Karting
// cs_karting.c
//
// Written by Akshay Govil, YOUR-ZID z5555555
// on <TODAYS-DATE>
//
// DESCRIPTION OF YOUR PROGRAM HERE

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#include "cs_karting.h"

// Stage 1.1
// Function to create the Racing Series
// Params:
//      name - the name of the series
// Returns: a pointer to the series

void insert_track_piece(struct series *series);
void insert_driver(struct series *series);
void copy_race(struct series *series);
void validate_race(struct series *series);
void start_race(struct series *series);

void insert_track_at_position(struct race *race, struct track_piece *new_track,
                              int position);
void insert_driver_at_position(struct race *race, struct driver *new_driver,
                               int position);
struct track_piece *last_track_piece(struct race *race);

struct race *find_race(struct series *series, char race_name[MAX_SIZE]);
int driver_count(struct race *race);
int driver_exists(struct race *race, char driver_name[MAX_SIZE]);

struct race *find_race(struct series *series, char race_name[MAX_SIZE]);
int driver_count(struct race *race);
int driver_exists(struct race *race, char driver_name[MAX_SIZE]);
void insert_track_piece(struct series *series);
void insert_driver(struct series *series);
void copy_race(struct series *series);
void validate_race(struct series *series);
void start_race(struct series *series);

void remove_driver_from_series(struct series *series);
void move_driver(struct series *series);
void play_turn(struct series *series);
void end_race(struct series *series);

void free_series(struct series *series);
void free_races(struct race *race);
void free_track(struct track_piece *track);
void free_drivers(struct driver *driver);

int remove_driver_from_list(struct driver **head, char driver_name[MAX_SIZE]);
struct driver *detach_driver_from_list(struct driver **head,
                                       char driver_name[MAX_SIZE]);
void append_driver_to_list(struct driver **head, struct driver *new_driver);

int track_count(struct track_piece *track);
int driver_position(struct track_piece *track, struct driver *target);
void play_one_turn(struct race *race);
int race_finished(struct race *race);
void finish_race(struct race *race);
void print_final_positions(struct race *race);

void insert_track_at_position(struct race *race, struct track_piece *new_track,
                              int position);
void insert_driver_at_position(struct race *race, struct driver *new_driver,
                               int position);
struct track_piece *last_track_piece(struct race *race);

struct series *create_series(char name[MAX_SIZE]) {
    struct series *new_series = malloc(sizeof(struct series));

    strcpy(new_series->name, name);
    new_series->races = NULL;

    return new_series;
}

// Stage 1.1
// Function to create a race
// Params:
//      name - the name of the race
//      location - the location of the race
// Returns: a pointer to the race
struct race *create_race(char name[MAX_SIZE], enum location location) {
    struct race *new_race = malloc(sizeof(struct race));

    strcpy(new_race->name, name);
    new_race->location = location;
    new_race->status = NOT_STARTED;
    new_race->track = NULL;
    new_race->drivers = NULL;
    new_race->next = NULL;

    return new_race;
}

// Stage 1.1
// Function to create a track piece
// Params:
//      type - the type of track piece
// Returns: a pointer to the track piece
struct track_piece *create_track(enum piece_type type) {
    struct track_piece *new_track = malloc(sizeof(struct track_piece));

    new_track->type = type;
    new_track->drivers = NULL;
    new_track->next = NULL;

    return new_track;
}

// Stage 1.1
// Function to create a driver
// Params:
//      name - the name of the driver
//      speed - the speed of the driver
// Returns: a pointer to the driver
struct driver *create_driver(char name[MAX_SIZE], int speed) {
    struct driver *new_driver = malloc(sizeof(struct driver));

    strcpy(new_driver->name, name);
    new_driver->speed = speed;
    new_driver->next = NULL;

    return new_driver;
}

// Stage 1.2
// Function to run the main command loop for the program
// Params:
//      series - a pointer to the racing series
// Returns: None
void command_loop(struct series *series) {
    char command;

    while (1) {
        printf("Enter command: ");

        if (scanf(" %c", &command) != 1) {
            free_series(series);
            return;
        }

        if (command == '?') {
            print_usage();
        } else if (command == 'a') {
            char add_type;
            scanf(" %c", &add_type);

            if (add_type == 'r') {
                add_race(series);
            } else if (add_type == 't') {
                add_track_piece(series);
            } else if (add_type == 'd') {
                add_driver(series);
            } else {
                printf("ERROR: Invalid command.\n");
            }
        } else if (command == 'i') {
            char insert_type;
            scanf(" %c", &insert_type);

            if (insert_type == 't') {
                insert_track_piece(series);
            } else if (insert_type == 'd') {
                insert_driver(series);
            } else {
                printf("ERROR: Invalid command.\n");
            }
        } else if (command == 'c') {
            copy_race(series);
        } else if (command == 'v') {
            validate_race(series);
        } else if (command == 's') {
            start_race(series);
        } else if (command == 'r') {
            remove_driver_from_series(series);
        } else if (command == 'm') {
            move_driver(series);
        } else if (command == 't') {
            play_turn(series);
        } else if (command == 'e') {
            end_race(series);
        } else if (command == 'q') {
            free_series(series);
            return;
        } else if (command == '*') {
            print_series(series);
        } else {
            printf("ERROR: Invalid command.\n");
        }
    }
}

// Stage 1.3
// Function to add a race
// Params:
//      series - a pointer to the racing series
// Returns: None
void add_race(struct series *series) {
    char name[MAX_SIZE];
    scan_name(name);
    enum location location = scan_location();

    if (find_race(series, name) != NULL) {
        printf("ERROR: Race %s already exists.\n", name);
        return;
    }

    struct race *new_race = create_race(name, location);

    if (series->races == NULL) {
        series->races = new_race;
    } else {
        struct race *current = series->races;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = new_race;
    }

    printf("Race: '%s' added!\n", name);
}

// Stage 1.3
// Function to add a track piece
// Params:
//      series - a pointer to the racing series
// Returns: None
void add_track_piece(struct series *series) {
    char race_name[MAX_SIZE];
    scan_name(race_name);
    enum piece_type type = scan_piece_type();

    if (type == INVALID) {
        printf("ERROR: Invalid track piece type.\n");
        return;
    }

    struct race *race = find_race(series, race_name);
    if (race == NULL) {
        printf("ERROR: No race with name %s.\n", race_name);
        return;
    }

    if (race->status != NOT_STARTED) {
        printf("ERROR: Race %s has already started.\n", race_name);
        return;
    }

    struct track_piece *new_track = create_track(type);

    if (race->track == NULL) {
        race->track = new_track;
    } else {
        struct track_piece *current = race->track;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = new_track;
    }

    printf("Track Piece: '%s' added!\n", type_to_string(type));
}

// Stage 1.3
// Function to add a driver
// Params:
//      series - a pointer to the racing series
// Returns: None
void add_driver(struct series *series) {
    char race_name[MAX_SIZE];
    char driver_name[MAX_SIZE];
    int speed;

    scan_name(race_name);
    scan_name(driver_name);
    scanf("%d", &speed);

    struct race *race = find_race(series, race_name);
    if (race == NULL) {
        printf("ERROR: No race with name %s.\n", race_name);
        return;
    }

    if (race->status != NOT_STARTED) {
        printf("ERROR: Race %s has already started.\n", race_name);
        return;
    }

    if (driver_exists(race, driver_name)) {
        printf("ERROR: Driver with name %s already exists in race.\n",
               driver_name);
        return;
    }

    if (speed < 1 || speed > 3) {
        printf("ERROR: Driver speed must be within 1 and 3.\n");
        return;
    }

    if (driver_count(race) >= 8) {
        printf("ERROR: Maximum of 8 drivers per race.\n");
        return;
    }

    struct driver *new_driver = create_driver(driver_name, speed);

    if (race->drivers == NULL) {
        race->drivers = new_driver;
    } else {
        struct driver *current = race->drivers;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = new_driver;
    }

    printf("Driver: '%s' added!\n", driver_name);
}

// Stage 1.4
// Function to print out the racing series
// Params:
//      series - a pointer to the racing series
// Retruns: None
void print_series(struct series *series) {
    printf("===================[ %s ]===================\n", series->name);

    if (series->races == NULL) {
        printf("The racing series is empty!\n");
        return;
    }

    printf("Races: \n");

    struct race *current = series->races;
    while (current != NULL) {
        printf("    %s [%s]\n", current->name, status_to_string(current->status));
        printf("    (%s)\n", location_to_string(current->location));
        print_track(current->track);
        print_drivers(current);
        current = current->next;
    }

    printf("\n");
}

// Add your function definitions below this line
struct race *find_race(struct series *series, char race_name[MAX_SIZE]) {
    struct race *current = series->races;
    while (current != NULL) {
        if (strcmp(current->name, race_name) == 0) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

int driver_count(struct race *race) {
    int count = 0;
    struct driver *current = race->drivers;
    while (current != NULL) {
        count++;
        current = current->next;
    }
    return count;
}

int driver_exists(struct race *race, char driver_name[MAX_SIZE]) {
    struct driver *current = race->drivers;
    while (current != NULL) {
        if (strcmp(current->name, driver_name) == 0) {
            return 1;
        }
        current = current->next;
    }
    return 0;
}

struct track_piece *last_track_piece(struct race *race) {
    struct track_piece *current = race->track;

    while (current->next != NULL) {
        current = current->next;
    }

    return current;
}

void insert_track_at_position(struct race *race, struct track_piece *new_track,
                              int position) {
    if (race->track == NULL || position <= 1) {
        new_track->next = race->track;
        race->track = new_track;
        return;
    }

    struct track_piece *current = race->track;
    int index = 1;

    while (current->next != NULL && index < position - 1) {
        current = current->next;
        index++;
    }

    new_track->next = current->next;
    current->next = new_track;
}

void insert_driver_at_position(struct race *race, struct driver *new_driver,
                               int position) {
    if (race->drivers == NULL || position <= 1) {
        new_driver->next = race->drivers;
        race->drivers = new_driver;
        return;
    }

    struct driver *current = race->drivers;
    int index = 1;

    while (current->next != NULL && index < position - 1) {
        current = current->next;
        index++;
    }

    new_driver->next = current->next;
    current->next = new_driver;
}

void insert_track_piece(struct series *series) {
    int position;
    char race_name[MAX_SIZE];

    scanf("%d", &position);
    scan_name(race_name);
    enum piece_type type = scan_piece_type();

    if (position < 1) {
        printf("ERROR: Position must be at least 1.\n");
        return;
    }

    if (type == INVALID) {
        printf("ERROR: Invalid track piece type.\n");
        return;
    }

    struct race *race = find_race(series, race_name);
    if (race == NULL) {
        printf("ERROR: No race with name %s.\n", race_name);
        return;
    }

    if (race->status != NOT_STARTED) {
        printf("ERROR: Race %s has already started.\n", race_name);
        return;
    }

    struct track_piece *new_track = create_track(type);
    insert_track_at_position(race, new_track, position);

    printf("Track Piece: '%s' inserted!\n", type_to_string(type));
}

void insert_driver(struct series *series) {
    int position;
    int speed;
    char race_name[MAX_SIZE];
    char driver_name[MAX_SIZE];

    scanf("%d", &position);
    scan_name(race_name);
    scan_name(driver_name);
    scanf("%d", &speed);

    if (position < 1) {
        printf("ERROR: Position must be at least 1.\n");
        return;
    }

    struct race *race = find_race(series, race_name);
    if (race == NULL) {
        printf("ERROR: No race with name %s.\n", race_name);
        return;
    }

    if (race->status != NOT_STARTED) {
        printf("ERROR: Race %s has already started.\n", race_name);
        return;
    }

    if (driver_exists(race, driver_name)) {
        printf("ERROR: Driver with name %s already exists in race.\n",
               driver_name);
        return;
    }

    if (speed < 1 || speed > 3) {
        printf("ERROR: Driver speed must be within 1 and 3.\n");
        return;
    }

    if (driver_count(race) >= 8) {
        printf("ERROR: Maximum of 8 drivers per race.\n");
        return;
    }

    struct driver *new_driver = create_driver(driver_name, speed);
    insert_driver_at_position(race, new_driver, position);

    printf("Driver: '%s' inserted!\n", driver_name);
}

void copy_race(struct series *series) {
    char existing_name[MAX_SIZE];
    char new_name[MAX_SIZE];

    scan_name(existing_name);
    scan_name(new_name);

    struct race *old_race = find_race(series, existing_name);
    if (old_race == NULL) {
        printf("ERROR: No race with name %s.\n", existing_name);
        return;
    }

    if (find_race(series, new_name) != NULL) {
        printf("ERROR: Race %s already exists.\n", new_name);
        return;
    }

    if (old_race->track == NULL) {
        printf("ERROR: No track pieces in race to be copied.\n");
        return;
    }

    struct race *new_race = create_race(new_name, old_race->location);

    struct track_piece *current_old = old_race->track;
    while (current_old != NULL) {
        struct track_piece *new_track = create_track(current_old->type);

        if (new_race->track == NULL) {
            new_race->track = new_track;
        } else {
            struct track_piece *current_new = new_race->track;
            while (current_new->next != NULL) {
                current_new = current_new->next;
            }
            current_new->next = new_track;
        }

        current_old = current_old->next;
    }

    if (series->races == NULL) {
        series->races = new_race;
    } else {
        struct race *current = series->races;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = new_race;
    }
}

void validate_race(struct series *series) {
    char race_name[MAX_SIZE];
    scan_name(race_name);

    struct race *race = find_race(series, race_name);
    if (race == NULL) {
        printf("ERROR: No race with name %s.\n", race_name);
        return;
    }

    if (race->status != NOT_STARTED) {
        printf("ERROR: Race %s has already started.\n", race_name);
        return;
    }

    struct track_piece *current = race->track;

    while (current != NULL && current->next != NULL) {
        int needs_straight = 0;

        if (current->type == LEFT_TURN && current->next->type == LEFT_TURN) {
            needs_straight = 1;
        }
        if (current->type == RIGHT_TURN && current->next->type == RIGHT_TURN) {
            needs_straight = 1;
        }
        if (current->type == JUMP && current->next->type != STRAIGHT) {
            needs_straight = 1;
        }

        if (needs_straight) {
            struct track_piece *new_track = create_track(STRAIGHT);
            new_track->next = current->next;
            current->next = new_track;
            current = new_track->next;
        } else {
            current = current->next;
        }
    }

    printf("Race %s validated!\n", race_name);
}

void start_race(struct series *series) {
    char race_name[MAX_SIZE];
    scan_name(race_name);

    struct race *race = find_race(series, race_name);
    if (race == NULL) {
        printf("ERROR: No race with name %s.\n", race_name);
        return;
    }

    if (race->status != NOT_STARTED) {
        printf("ERROR: Race %s has already started.\n", race_name);
        return;
    }

    if (race->track == NULL) {
        printf("ERROR: No track pieces in race %s.\n", race_name);
        return;
    }

    if (race->drivers == NULL) {
        printf("ERROR: No drivers in race %s.\n", race_name);
        return;
    }

    struct track_piece *start_line = create_track(START_LINE);
    struct track_piece *finish_line = create_track(FINISH_LINE);

    start_line->next = race->track;
    race->track = start_line;

    struct track_piece *last = last_track_piece(race);
    last->next = finish_line;

    start_line->drivers = race->drivers;
    race->drivers = NULL;

    race->status = ACTIVE;

    printf("Race %s started!\n", race_name);
}
void free_drivers(struct driver *driver) {
    while (driver != NULL) {
        struct driver *next = driver->next;
        free(driver);
        driver = next;
    }
}

void free_track(struct track_piece *track) {
    while (track != NULL) {
        struct track_piece *next = track->next;
        free_drivers(track->drivers);
        free(track);
        track = next;
    }
}

void free_races(struct race *race) {
    while (race != NULL) {
        struct race *next = race->next;
        free_track(race->track);
        free_drivers(race->drivers);
        free(race);
        race = next;
    }
}

void free_series(struct series *series) {
    free_races(series->races);
    free(series);
}

int remove_driver_from_list(struct driver **head, char driver_name[MAX_SIZE]) {
    int removed = 0;

    while (*head != NULL && strcmp((*head)->name, driver_name) == 0) {
        struct driver *temp = *head;
        *head = (*head)->next;
        free(temp);
        removed = 1;
    }

    struct driver *current = *head;
    while (current != NULL && current->next != NULL) {
        if (strcmp(current->next->name, driver_name) == 0) {
            struct driver *temp = current->next;
            current->next = temp->next;
            free(temp);
            removed = 1;
        } else {
            current = current->next;
        }
    }

    return removed;
}

struct driver *detach_driver_from_list(struct driver **head,
                                       char driver_name[MAX_SIZE]) {
    if (*head == NULL) {
        return NULL;
    }

    if (strcmp((*head)->name, driver_name) == 0) {
        struct driver *removed = *head;
        *head = (*head)->next;
        removed->next = NULL;
        return removed;
    }

    struct driver *current = *head;
    while (current->next != NULL) {
        if (strcmp(current->next->name, driver_name) == 0) {
            struct driver *removed = current->next;
            current->next = removed->next;
            removed->next = NULL;
            return removed;
        }
        current = current->next;
    }

    return NULL;
}

void append_driver_to_list(struct driver **head, struct driver *new_driver) {
    new_driver->next = NULL;

    if (*head == NULL) {
        *head = new_driver;
        return;
    }

    struct driver *current = *head;
    while (current->next != NULL) {
        current = current->next;
    }
    current->next = new_driver;
}

void remove_driver_from_series(struct series *series) {
    char driver_name[MAX_SIZE];
    scan_name(driver_name);

    int removed = 0;
    struct race *current_race = series->races;

    while (current_race != NULL) {
        removed += remove_driver_from_list(&current_race->drivers, driver_name);

        struct track_piece *current_track = current_race->track;
        while (current_track != NULL) {
            removed += remove_driver_from_list(&current_track->drivers,
                                               driver_name);
            current_track = current_track->next;
        }

        current_race = current_race->next;
    }

    if (removed == 0) {
        printf("ERROR: Driver %s not found in the series.\n", driver_name);
    } else {
        printf("Driver %s removed from the racing series!\n", driver_name);
    }
}

void move_driver(struct series *series) {
    char driver_name[MAX_SIZE];
    char current_race_name[MAX_SIZE];
    char new_race_name[MAX_SIZE];

    scan_name(driver_name);
    scan_name(current_race_name);
    scan_name(new_race_name);

    struct race *current_race = find_race(series, current_race_name);
    if (current_race == NULL) {
        printf("ERROR: No race with name %s.\n", current_race_name);
        return;
    }
    if (current_race->status != NOT_STARTED) {
        printf("ERROR: Race %s has already started.\n", current_race_name);
        return;
    }

    struct race *new_race = find_race(series, new_race_name);
    if (new_race == NULL) {
        printf("ERROR: No race with name %s.\n", new_race_name);
        return;
    }
    if (new_race->status != NOT_STARTED) {
        printf("ERROR: Race %s has already started.\n", new_race_name);
        return;
    }

    if (!driver_exists(current_race, driver_name)) {
        printf("ERROR: Driver %s not found in race %s.\n",
               driver_name, current_race_name);
        return;
    }

    if (driver_exists(new_race, driver_name)) {
        printf("ERROR: Driver %s already in race %s.\n",
               driver_name, new_race_name);
        return;
    }

    if (driver_count(new_race) >= 8) {
        printf("ERROR: Race %s already at maximum driver limit.\n",
               new_race_name);
        return;
    }

    struct driver *moved_driver = detach_driver_from_list(
        &current_race->drivers, driver_name
    );
    append_driver_to_list(&new_race->drivers, moved_driver);
}

int track_count(struct track_piece *track) {
    int count = 0;
    while (track != NULL) {
        count++;
        track = track->next;
    }
    return count;
}

int driver_position(struct track_piece *track, struct driver *target) {
    int count = track_count(track);
    struct track_piece *pieces[count];

    struct track_piece *current_track = track;
    int i = 0;
    while (current_track != NULL) {
        pieces[i] = current_track;
        i++;
        current_track = current_track->next;
    }

    int position = 1;
    for (i = count - 1; i >= 0; i--) {
        struct driver *current_driver = pieces[i]->drivers;
        while (current_driver != NULL) {
            if (current_driver == target) {
                return position;
            }
            position++;
            current_driver = current_driver->next;
        }
    }

    return 0;
}

void play_one_turn(struct race *race) {
    int count = track_count(race->track);
    struct track_piece *pieces[count];

    struct track_piece *current_track = race->track;
    int i = 0;
    while (current_track != NULL) {
        pieces[i] = current_track;
        i++;
        current_track = current_track->next;
    }

    for (i = count - 1; i >= 0; i--) {
        struct driver *current_driver = pieces[i]->drivers;
        pieces[i]->drivers = NULL;

        while (current_driver != NULL) {
            struct driver *next_driver = current_driver->next;
            int new_index = i + current_driver->speed;

            if (new_index >= count) {
                new_index = count - 1;
            }

            append_driver_to_list(&pieces[new_index]->drivers, current_driver);
            current_driver = next_driver;
        }
    }
}

int race_finished(struct race *race) {
    struct track_piece *current = race->track;

    while (current->next != NULL) {
        if (current->drivers != NULL) {
            return 0;
        }
        current = current->next;
    }

    return 1;
}

void print_final_positions(struct race *race) {
    printf("Final positions: \n");

    int place = 1;
    struct driver *current = race->drivers;
    while (current != NULL) {
        printf("    %d. %s (%d points)\n",
               place, current->name, place_to_points(place));
        place++;
        current = current->next;
    }
}

void finish_race(struct race *race) {
    struct track_piece *finish_line = last_track_piece(race);

    race->drivers = finish_line->drivers;
    finish_line->drivers = NULL;
    race->status = COMPLETED;

    printf("Race %s has finished!\n", race->name);
    print_final_positions(race);
}

void play_turn(struct series *series) {
    char race_name[MAX_SIZE];
    int turns;

    scan_name(race_name);
    scanf("%d", &turns);

    struct race *race = find_race(series, race_name);
    if (race == NULL) {
        printf("ERROR: No race with name %s.\n", race_name);
        return;
    }
    if (race->status != ACTIVE) {
        printf("ERROR: Race %s is not active.\n", race_name);
        return;
    }
    if (turns < 1) {
        printf("ERROR: Turns must be a positive integer.\n");
        return;
    }

    int i = 0;
    while (i < turns && race->status == ACTIVE) {
        play_one_turn(race);
        if (race_finished(race)) {
            finish_race(race);
        }
        i++;
    }
}

void end_race(struct series *series) {
    char race_name[MAX_SIZE];
    scan_name(race_name);

    struct race *race = find_race(series, race_name);
    if (race == NULL) {
        printf("ERROR: No race with name %s.\n", race_name);
        return;
    }
    if (race->status != ACTIVE) {
        printf("ERROR: Race %s is not active.\n", race_name);
        return;
    }

    while (race->status == ACTIVE) {
        play_one_turn(race);
        if (race_finished(race)) {
            finish_race(race);
        }
    }
}

///////////////////////////////////////////////////////////////////////////////
// Provided function definitions
////////////////////////////////////////////////////////////////////////////////

// Function to print the program usage information
// Params: None
// Returns: None
void print_usage() {

    printf(
       "======================[ Usage Info ]=====================\n"
       "                                                         \n"
       "  ?                                                      \n"
       "    Show this help information.                          \n"
       "  a r [race_name] [location]                             \n"
       "    Add a new race with the given name and location.     \n"
       "  a t [race_name] [piece_type]                           \n"
       "    Add a track piece of the given type to the race.     \n"
       "  a d [race_name] [driver_name] [speed]                  \n"
       "    Add a driver to the specified race.                  \n"
       "  *                                                      \n"
       "    Print the racing series.                             \n"
       "  i t [n] [race_name] [piece_type]                       \n"
       "    Insert a track piece at position [n] in the race.    \n"
       "  i d [n] [race_name] [driver_name] [speed]              \n"
       "    Insert a driver at [position] in the specified race. \n"
       "  c [existing_race] [new_race]                           \n"
       "    Adds a new race with the same track layout.          \n"
       "  s [race_name]                                          \n"
       "    Start the specified race.                            \n"
       "  v [race_name]                                          \n"
       "    Validates the specified rules meets track compliance.\n"
       "  m [driver_name] [current_race] [new_race]              \n"
       "    Moves the driver from one race to another.           \n"
       "  q                                                      \n"
       "    Cancels the karting series.                          \n"
       "  r [driver_name]                                        \n"
       "    Removes the driver from all races.                   \n"
       "  t [race_name] [turns]                                  \n"
       "    Advance the race by [turns].                         \n"
       "  e [race_name]                                          \n"
       "    Automatically run turns until the race finishes.     \n"
       "  f [location]                                           \n"
       "    Create a finals race for the given location.         \n"
       "                                                         \n"
       "=========================================================\n"
    );

}

// Function to print the welcome banner
// Params: None
// Returns: None
void print_welcome_banner() {

    printf(""
    "          Welcome to the CS Karting Racing Series!\n"
    "                  .\n"
    "                  |\\\n"
    "                  |_\\\n"
    "                  |\n"
    "       .==========||=======.    .===================.\n"
    "      /    _______||____    \\  /   _[_0|_[?]_______   \\\n"
    "     /   /'              '\\  \\/  /'               '\\   \\\n"
    "    |   |                  \\/   /                   |   |\n"
    "    |   |                  /   / \\                  |   |\n"
    "     \\  \\                 /   /\\  \\                /   /\n"
    "      \\  '---------------'   /  \\  '--------------'   /\n"
    "       \\.===[_0|====[_0|===./    \\.========|0_]=====./\n"
    "\n"
    );

}

// Helper function to print out the track information
// PARAMS:
//      track - the first track piece in a given race
// RETURNS: None
void print_track(struct track_piece *track) {

    if (track == NULL) {
        printf("        Empty Track!\n");
        return;
    }

    struct track_piece *start = track;

    while (track != NULL) {
        printf("        %s\n", type_to_string(track->type));

        struct driver *current_driver = track->drivers;
        while (current_driver != NULL) {
            printf("        %d. %s\n",
                   driver_position(start, current_driver),
                   current_driver->name);
            current_driver = current_driver->next;
        }

        if (track->next != NULL) {
            printf("        |\n");
            printf("        ⌄\n");
        }

        track = track->next;
    }
}

// Helper function to print out the drivers within a race
// PARAMS:
//      race - the race containing the drivers to be printed
// RETURNS: None
void print_drivers(struct race *race) {
    printf("        Drivers:\n");

    int count = 1;

    if (race->status == ACTIVE) {
        int pieces_count = track_count(race->track);
        struct track_piece *pieces[pieces_count];

        struct track_piece *current_track = race->track;
        int i = 0;
        while (current_track != NULL) {
            pieces[i] = current_track;
            i++;
            current_track = current_track->next;
        }

        for (i = pieces_count - 1; i >= 0; i--) {
            struct driver *current_driver = pieces[i]->drivers;
            while (current_driver != NULL) {
                printf("            %d. %s (speed: %d)\n",
                       count, current_driver->name, current_driver->speed);
                count++;
                current_driver = current_driver->next;
            }
        }
    } else {
        struct driver *current = race->drivers;
        while (current != NULL) {
            printf("            %d. %s (speed: %d)\n",
                   count, current->name, current->speed);
            count++;
            current = current->next;
        }
    }

    if (count == 1) {
        printf("            Empty Driver List!\n");
    }
}

// Scan in the a name string into the provided buffer, placing
// '\0' at the end.
//
// Params:
//      name - a char array of length MAX_SIZE, which will be used
//                  to store the name.
// Returns: None
// Usage:
// ```
//      char name[MAX_SIZE];
//      scan_name(name);
// ```
void scan_name(char name[MAX_SIZE]) {
    scan_token(name, MAX_SIZE);
}

// Scans a string and converts it to a location.
//
// Returns:
//      The corresponding location, if the string was valid,
//      Otherwise, returns INVALID.
//
// Usage:
// ```
//      enum location location = scan_location();
// ```
//
enum location scan_location(void) {
    char type[MAX_SIZE];
    scan_token(type, MAX_SIZE);
    return string_to_location(type);
}

// Scans a string and converts it to a location.
//
// Returns:
//      The corresponding pieve_type, if the string was valid,
//      Otherwise, returns INVALID.
//
// Usage:
// ```
//      enum piece_type type = scan_location();
// ```
//
enum piece_type scan_piece_type(void) {
    char type[MAX_SIZE];
    scan_token(type, MAX_SIZE);
    return string_to_type(type);
}

////////////////////////////////////////////////////////////////////////////////
// Additional provided function definitions
////////////////////////////////////////////////////////////////////////////////

// You don't need to use any of these, or understand how they work!
// We use them to implement some of the provided helper functions.

enum points place_to_points(int place) {
    if (place == 1) {
        return FIRST;
    }
    if (place == 2) {
        return SECOND;
    }
    if (place == 3) {
        return THIRD;
    }
    if (place == 4) {
        return FOURTH;
    }
    if (place == 5) {
        return FIFTH;
    }
    if (place == 6) {
        return SIXTH;
    }
    if (place == 7) {
        return SEVENTH;
    } else {
        return EIGHTH;
    }
}

enum location string_to_location(char *type_str) {
    int len = strlen(type_str);

    if (strncasecmp(type_str, "ALBERT_PARK", len) == 0) {
        return ALBERT_PARK;
    }
    if (strncasecmp(type_str, "MARINA_BAY", len) == 0) {
        return MARINA_BAY;
    }
    if (strncasecmp(type_str, "MONZA", len) == 0) {
        return MONZA;
    }
    if (strncasecmp(type_str, "SUZUKA", len) == 0) {
        return SUZUKA;
    } else {
        return ZANDVOORT;
    }
}

char *location_to_string(enum location location) {

    if (location == ALBERT_PARK) {
        return "ALBERT_PARK";
    }
    if (location == MARINA_BAY) {
        return "MARINA_BAY";
    }
    if (location == MONZA) {
        return "MONZA";
    }
    if (location == SUZUKA) {
        return "SUZUKA";
    } else  {
        return "ZANDVOORT";
    }

}
enum piece_type string_to_type(char *type_str) {
    int len = strlen(type_str);

    if (strncasecmp(type_str, "START_LINE", len) == 0) {
        return START_LINE;
    }
    if (strncasecmp(type_str, "FINISH_LINE", len) == 0) {
        return FINISH_LINE;
    }
    if (strncasecmp(type_str, "STRAIGHT", len) == 0) {
        return STRAIGHT;
    }
    if (strncasecmp(type_str, "LEFT_TURN", len) == 0) {
        return LEFT_TURN;
    }
    if (strncasecmp(type_str, "RIGHT_TURN", len) == 0) {
        return RIGHT_TURN;
    }
    if (strncasecmp(type_str, "JUMP", len) == 0) {
        return JUMP;
    }
    if (strncasecmp(type_str, "MYSTERY_BOX", len) == 0) {
        return MYSTERY_BOX;
    }

    return INVALID;
}

char *type_to_string(enum piece_type type) {
    if (type == START_LINE) {
        return "START_LINE";
    }
    if (type == FINISH_LINE) {
        return "FINISH_LINE";
    }
    if (type == STRAIGHT) {
        return "STRAIGHT";
    }
    if (type == LEFT_TURN) {
        return "LEFT_TURN";
    }
    if (type == RIGHT_TURN) {
        return "RIGHT_TURN";
    }
    if (type == JUMP) {
        return "JUMP";
    }
    if (type == MYSTERY_BOX) {
        return "MYSTERY_BOX";
    }
    return "INVALID";
}

char *status_to_string(enum race_status status) {
    
    if (status == NOT_STARTED) {
        return "NOT_STARTED";
    } else if (status == ACTIVE) {
        return "ACTIVE";
    } else {
        return "COMPLETED";
    }

}

int scan_token(char *buffer, int buffer_size) {
    if (buffer_size == 0) {
        return 0;
    }

    char c;
    int i = 0;
    int num_scanned = 0;

    scanf(" ");

    while (i < buffer_size - 1 && (num_scanned = scanf("%c", &c)) == 1 &&
           !isspace(c)) {
        buffer[i++] = c;
    }

    if (i > 0) {
        buffer[i] = '\0';
    }

    return num_scanned;
}
Editor is loading...
Leave a Comment