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;
	// read in from cin
	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;
		}
		// read again from cin
		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;
}
 
/*
	Prints menu options
*/
void print_menu()
{
	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
@return index of name_to_find in team_names, or -1 if not found
*/
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
	@param name_to_add name to add
	@return new size after attempted addition
*/
int add_team(string team_names[], int array_size, string name_to_add)
{
	// 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
			team_names[array_size] = name_to_add;
			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 is not found in the list
	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)
	{
		print_menu();
		int choice = get_user_input(1,6);
 
		if (choice == 1)
		{
			// Add a team
			cout << "ADD A TEAM" << endl;
			string name_to_add = prompt_and_get_string("Team to add: ");
			size = add_team(names, size, name_to_add); // remember to update the size here
		}
		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);  // remember to update the size here
		}
		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;
}
cs-142/byu-acm-tournament-tracker.txt · Last modified: 2015/05/21 19:02 by cs142ta
Back to top
CC Attribution-Share Alike 4.0 International
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0