**This is an old revision of the document!**

# BYU ACM Tournament Tracker

## Problem

• You are the BYU ACM secretary
• For the upcoming Team Coding Challenge you need a program to keep track of teams in the order that they finish the competition.
• You program should be able to:
• Add a team to an ordered list
• Delete a team
• Edit a team name
• Get a team’s finish position
• Display teams ordered by finish order
• Display teams ordered A-Z
• Assume valid input and team names without spaces

## Solution

/*
A NOTE ON TEST CASES
Each option should have its own set of test cases to test each branch of the program

In addition, however, a set of test cases should *theoretically* be developed to also test any possible
sequence of options selected (or rather sequence of branches of options)

Because you can't feasibly test all possible sequences, be sure to test at least a handful of likely
sequences.

It becomes particularly important to test each option thoroughly in isolation so that
you can be more confident that it works properly when executed in any arbitrary sequence
*/

#include <iostream>
#include <string>

using namespace std;

// Use a constant to represent the capacity of our array of names
const int CAPACITY = 1000;

/*
Reads for integer input and reprompts until valid integer input is provided within range
@param min minimum value for range of input
@param max maximum value for range of input
@return first valid input integer
*/
int get_user_input(int min, int max)
{
int input;
cin >> input;

// while it's bad (non-int or not in range)
while (cin.fail() || input < min || input > max)
{
// send message, reprompt
cout << "That's bad input. Gimme a value between " << min << " and " << max << ":";
if (cin.fail())
{
cin.clear();
string dummy;
cin >> dummy;
}
cin >> input;
}
cout << endl;

return input;
}

/*
Function that prints a prompt, reads a single word as input and returns it
@param prompt prompt to display
@return word input by user
*/
string prompt_and_get_string(string prompt)
{
string input;
cout << prompt;
cin >> input;

return input;
}

/*
*/
{
cout << "Choose from the following options: " << endl
<< "1. Add a team" << endl
<< "2. Delete a team" << endl
<< "3. Rename a team" << endl
<< "4. Get a team's finish place" << endl
<< "5. Display teams ordered by date added" << endl
<< "6. Display teams ordered A-Z" << endl
<< "Choice: ";
}

/*
Prints contents of an array to the console
@param array_to_display array to display
@param array_size size of the array
*/
void display_array(string array_to_display[], int array_size)
{
for (int i = 0; i < array_size; i++)
{
cout << (i + 1) << ". " << array_to_display[i] << endl;
}
}

/*
Prompts user for a team name, finds the 0-based index of the name, and returns it to the caller
@param team_names array to find team in
@param array_size size of array of team names
@param name_to_find name to find
*/
int get_team_index(string team_names[], int array_size, string name_to_find)
{
for (int i = 0; i < array_size; i++)
{
if (team_names[i] == name_to_find)
{
return i;
}
}

return -1;
}

/*
Function to add a new team if capacity allows and name is not already in the list
@param team_names array to add new team to
@param array_size size of array before adding team
@return new size after attempted addition
*/
{
// Something we did not do in class, but should have is
// Check if the name already exists in the array
int index_of_name = get_team_index(team_names, array_size, name_to_add);

// If the name isn't in the list
if (index_of_name == -1)
{
//Check that the array has room to add a new name
if (array_size < CAPACITY)
{
// add the new name at the index pointed to by array_size
cout << "Team added successfully" << endl;

// increment array size only if we've actually added it, which we just did
array_size++;
}
else
{
cout << "Unable to add team. Capacity reached." << endl;
}
}
else
{
cout << "That name's already on the list. Sorry, no duplicate names." << endl;
}

// We tell the caller the new array_size since we can't modify the original
return array_size;
}

/*
Delete a name (if it is found) from a list of team names
@param team_names array to delete team from
@param array_size size of array of team names
@param name_to_delete name to delete
@return size of array after attempted deletion
*/
int delete_team(string team_names[], int array_size, string name_to_delete)
{
int team_position = get_team_index(team_names, array_size, name_to_delete);

if (team_position == -1)
{
cout << "Team not in list" << endl;
}
else
{
// otherwise remove the team
// starting at index of the name_to_delete, replace each name with the one after it
// We only go to (array_size - 1) because we don't replace the last name with anything
for (int i = team_position; i < (array_size - 1); i++)
{
// move the (i+1)th element to the ith element
team_names[i] = team_names[i + 1];
}
cout << "Team removed successfully" << endl;

// modify our companion variable
array_size--;
}

// return the new size
return array_size;
}

/*
This function sorts an array alphabetically. See Special Topic 6.2 in the book
for breakdown of the algorithm.
@param array_to_sort an array we want to sort
@param array_size number of elements in array_to_sort
*/
void sort_alphabetically(string array_to_sort[], int array_size)
{
for (int i = 0; i < array_size; i++)
{
//Find the position of the minimum starting at i (we assume everything before i is "sorted area")
int index_of_min_element = i; // until we find otherwise, it's the ith element

for (int j = i; j < array_size; j++)
{
if (array_to_sort[j] < array_to_sort[index_of_min_element])
{
index_of_min_element = j;
}
}

//Swap the minimum into the "sorted area"
string temp = array_to_sort[i];
array_to_sort[i] = array_to_sort[index_of_min_element];
array_to_sort[index_of_min_element] = temp;
}
}

/*
Given a old team name, and a new name, this function replaces the old with the new (assuming
we find it in the list)
@param team_names list containing names
@param array_size size of team_names
@param name_to_rename the old name
@param new_name the new name
*/
void rename_team(string team_names[], int array_size, string name_to_rename, string new_name)
{
// First we find where the team is in the list
int team_position = get_team_index(team_names, array_size, name_to_rename);

if (team_position == -1)
{
cout << "Team not in list" << endl;
}
else
{
// rename team at position
team_names[team_position] = new_name;
cout << "Name changed successfully" << endl;
}
}

/*
Function to copy an array
@param source_array the array we want to copy
@param destination_array the array that will represent the copy
@param array_size companion variable to track number of elements in each of the copies
*/
void copy_array_to_array(string source_array[], string destination_array[], int array_size)
{
for (int i = 0; i < array_size; i++)
{
destination_array[i] = source_array[i];
}
}

/*
Print out to the console the team's 1-based ranking or error if not found
@param team_names array with team names
@param array_size number of elements in team_names
@param name_to_find name for which to find ranking
*/
void get_team_ranking(string team_names[], int array_size, string name_to_find)
{
int team_position = get_team_index(team_names, array_size, name_to_find);
if (team_position == -1)
{
cout << "That team isn't in the list" << endl;
}
else
{
// return 1-based position to user
cout << "Team is in position " << (team_position + 1) << endl;
}
cout << endl;
}

/*
Display to the console the list of teams sorted alphabetically
@param team_names array with team names
@param array_size number of elements in team_names
*/
void display_teams_alphabetically(string team_names[], int array_size)
{
// We don't want to modify the original order, so we'll make a copy just for sorting a-z
string names_copy[CAPACITY];
copy_array_to_array(team_names, names_copy, array_size);

sort_alphabetically(names_copy, array_size);

// names_copy is now sorted alphabetically
display_array(names_copy, array_size);
}

int main()
{
string names[CAPACITY];
int size = 0;

// Loop until I manually terminate the program
while (true)
{
int choice = get_user_input(1,6);

if (choice == 1)
{
cout << "ADD A TEAM" << endl;
}
else if (choice == 2)
{
// Delete a team
cout << "DELETE A TEAM" << endl;
string name_to_delete = prompt_and_get_string("Team name: ");
size = delete_team(names, size, name_to_delete);
}
else if (choice == 3)
{
// Rename a team
cout << "RENAME TEAM" << endl;
string name_to_rename = prompt_and_get_string("Team to rename: ");
string new_name = prompt_and_get_string("New name: ");
rename_team(names, size, name_to_rename, new_name);
}
else if (choice == 4)
{
// Get team's finish position
cout << "GET TEAM'S POSITION" << endl;
string name_to_find = prompt_and_get_string("Team name: ");
get_team_ranking(names, size, name_to_find);
}
else if (choice == 5)
{
// Display teams ordered by finish order
cout << "DISPLAY TEAMS ORDERED BY TIME FINISHED" << endl;
display_array(names, size);
}
else if (choice == 6)
{
// Display teams ordered by name - should not change the order of the original array
cout << "DISPLAY TEAMS ORDERED ALPHABETICALLY" << endl;
display_teams_alphabetically(names, size);
}
cout << endl;
}

system("pause");
return 0;
}