// driver.cpp Functions for communicating between BAL & amulet functions /******************************************************************************* // MODULE NAME: Driver // INTERFACE FILE: driver.h // IMPLEMENTATION FILE: driver.cpp // // PURPOSE: To provide functions useful for integrating existing BAL code with // Amulet GUI library functions // // EXTERNAL FUNCTIONS: Name Purpose // openFile Open specified BAM file & store info // into linked lists // closeFile Destroy linked lists // writeFile Write linked list info into new BAM file // w/specified filename // getNextRecord Change current record to next record // getPrevRecord Change current reocrd to previous record // getFirstRecord Change current record to first record // getLastRecord Change current record to last record // noRecords Determine if there are no active records // searchByAlley Search for a record w/specified string // in the alley name field // searchByEvent Search for a record w/specified string // in the event title field // searchByDate Search for a record w/specified string // in the date field // Alley Return Alley field of current record // Event Return Event field of current record // Date Return Date field of current record // Ball Return Ball field of current record // Lift Return Lift field of current record // Conditions Return Conditions fld of current record // Mark_1...Mark_10 Return appropriate markings field of // current record // Score_1...Score_10 Return appropriate score field of // current record // INTERNAL FUNCTIONS: Name Purpose // BuildBamList Insert data into BamList // BuildGameFramesList Create subset of Frames list // based on game index # // SyncFramesList Combine Frames master list & sublist // ParseFrame Determine frame scoring information // BallValue Evaluate individual score marking // // AUTHOR: Amy Langill *2B DATE: 5/2/1999 *******************************************************************************/ #include "driver.h" // For function prototypes #include "parsefile.h" // For ListTypes and ParseFile() #include "bamlist.h" // For BamListType #include "report.h" // For WriteBAMFile() #include // Stringstreams for conversions using namespace std; // The linked lists that hold the bam data. // These are static because the driver file goes out of scope // during the execution of bam static AlleyListType Alleys; // File-scoped linked lists static EventListType Events; // static ToolsListType Tools; // static BallListType BallList; // static ReleaseListType Release; // static ConditionsListType CondList; // static GameListType Games; // static FrameListType Frames; // static BamListType BamList; // static BamListPtr CurrentBamRecord; // File-scoped record pointer /******************************************************************************* // FUNCTION NAME: openFile // // DESCRIPTION OF FUNCTION: Opens a specified BAM file and loads the data // contained therein into the linked list structures and sets the active record // to the first record in the resulting BamList // // DESCRIPTION OF ALGORITHM: If the file can be opened,calls ParseFile to load // the data into linked lists, then creates the BamList with BuildBamList and // calls BamList::getFirst to set CurrentBamRecord to the first BamRecord in // BamList // // CALLED BY: file_open_do, main // CALLS: ParseFile,BuildBamList,BamList::getFirst // // PARAMETERS: / in / fileName - string that indicates the full name, including // extension, of the BAM file to be opened // // PRECONDITIONS: none // // POSTCONDITIONS: Returns true if the BAM file could be opened and loads the // correct data from the BAM file into the linked lists // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ bool openFile(string fileName) { ifstream inputFile; // for testing existence of file name bool fileOK=true; // for testing if file already exists void BuildBamList(AlleyListType& Alleys,EventListType& Events, BallListType& Ball, ReleaseListType& Release, ConditionsListType& Conditions, GameListType& Games, FrameListType& Frames, BamListType& BamList); inputFile.open(fileName.c_str()); // open the file fileOK = (!inputFile.fail()); // File is ok if open didn't fail if (!fileOK) return fileOK; else { ParseFile(inputFile,fileName,Alleys,Events,Tools,BallList,Release,CondList, Games,Frames); inputFile.close(); BuildBamList(Alleys, Events, BallList, Release, CondList, Games, Frames, BamList); BamList.getFirst(CurrentBamRecord); } return fileOK; } /******************************************************************************* // FUNCTION NAME: closeFile // // DESCRIPTION OF FUNCTION: Destroys the linked lists // // DESCRIPTION OF ALGORITHM: Calls the destroyList member function of each of // the classes for every list // // CALLED BY: file_close_do, file_quit_do, file_open_do // CALLS: AlleyListType::destroyList,EventListType::destroyList, // ToolsListType::destroyList,BallListType::destroyList, // ReleaseListType::destroyList,ConditionsListType::destroyList, // GameListType::destroyList,FrameListType::destroyList, // BamListType::destroyList // // PARAMETERS: none // // PRECONDITIONS: none // // POSTCONDITIONS: All linked lists are no empty // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ void closeFile() { Alleys.destroyList(); Events.destroyList(); Tools.destroyList(); BallList.destroyList(); Release.destroyList(); CondList.destroyList(); Games.destroyList(); Frames.destroyList(); BamList.destroyList(); return; } /******************************************************************************* // FUNCTION NAME: writeFile // // DESCRIPTION OF FUNCTION: Writes out the current BAM data into a properly // formatted BAM file // // DESCRIPTION OF ALGORITHM: Calls WriteBAMFile to create a file with the data // contained in the linked lists // // CALLED BY: file_saveas_do // CALLS: WriteBAMFile // // PARAMETERS: / in / fileName - string that is to be used as the new file's // name, including extension // // PRECONDITIONS: none // // POSTCONDITIONS: A BAM file is produced, named according to filename, // containing the data stored in the linked lists // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ void writeFile(string fileName) { WriteBAMFile(Alleys,Events,Tools,BallList,Release,CondList,Games,Frames, fileName); return; } /******************************************************************************* // FUNCTION NAME: getNextRecord // // DESCRIPTION OF FUNCTION: Sets the next record in the list as the active one // // DESCRIPTION OF ALGORITHM: If the list is empty, returns false. Otherwise, // attempts to advance the CurrentBamRecord pointer to the next record using // the BamList::getNext member function // // CALLED BY: games_next_do // CALLS: BamList::getNext // // PARAMETERS: none // // PRECONDITIONS: none // // POSTCONDITIONS: If the list is empty or no record follows the current one, // CurrentBamRecord is not moved and the function returns false. Otherwise, // CurrentBamRecord is moved and the function returns true. // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ bool getNextRecord() { if (BamList.isEmpty()) return false; return (BamList.getNext(CurrentBamRecord)); } /******************************************************************************* // FUNCTION NAME: getPrev // // DESCRIPTION OF FUNCTION: Sets the previous record in the list as active // // DESCRIPTION OF ALGORITHM: If the list is empty, returns false. Otherwise, // attempts to move the CurrentBamRecord pointer to the previous record using // the BamList::getPrev member function // // CALLED BY: games_prev_do // CALLS: BamList::getPrev // // PARAMETERS: none // // PRECONDITIONS: none // // POSTCONDITIONS: If the list is empty or no record precedes the current one, // CurrentBamRecord is not moved and the function returns false. Otherwise, // CurrentBamRecord is moved and the function returns true. // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ bool getPrevRecord() { if (BamList.isEmpty()) return false; return (BamList.getPrev(CurrentBamRecord)); } /******************************************************************************* // FUNCTION NAME: getFirstRecord // // DESCRIPTION OF FUNCTION: Sets the first record in the list as the active one // // DESCRIPTION OF ALGORITHM: If the list is empty, returns false. Otherwise, // attempts to advance the CurrentBamRecord pointer to the first record using // the BamList::getFirst member function // // CALLED BY: games_first_do // CALLS: BamList::getFirst // // PARAMETERS: none // // PRECONDITIONS: none // // POSTCONDITIONS: If the list is empty ,CurrentBamRecord is not moved and the // function returns false. Otherwise, CurrentBamRecord is moved and the // function returns true. // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ bool getFirstRecord() { if (BamList.isEmpty()) return false; return (BamList.getFirst(CurrentBamRecord)); } /******************************************************************************* // FUNCTION NAME: getLastRecord // // DESCRIPTION OF FUNCTION: Sets the last record in the list as the active one // // DESCRIPTION OF ALGORITHM: If the list is empty, returns false. Otherwise, // attempts to advance the CurrentBamRecord pointer to the last record using // the BamList::getLast member function // // CALLED BY: games_last_do // CALLS: BamList::getLast // // PARAMETERS: none // // PRECONDITIONS: none // // POSTCONDITIONS: If the list is empty ,CurrentBamRecord is not moved and the // function returns false. Otherwise, CurrentBamRecord is moved and the // function returns true. // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ bool getLastRecord() { if (BamList.isEmpty()) return false; return (BamList.getLast(CurrentBamRecord)); } /******************************************************************************* // FUNCTION NAME: noRecords // // DESCRIPTION OF FUNCTION: Determines if there are no active records // // DESCRIPTION OF ALGORITHM: Calls BamList::isEmpty member function // // CALLED BY: file_open_do, file_saveas_do, file_close_do, games_first_do, // games_prev_do, games_next_do, games_last_do, search_alley_do, // search_event_do, search_date_do // CALLS: BamList::isEmpty // // PARAMETERS: none // // PRECONDITIONS: none // // POSTCONDITIONS: Returns true if the BamList is empty and false otherwise // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ bool noRecords() { return (BamList.isEmpty()); } /******************************************************************************* // FUNCTION NAME: searchByAlley // // DESCRIPTION OF FUNCTION: Determine if a record exists with a certain value // in its alley field. // // DESCRIPTION OF ALGORITHM: Checks to see if the list is empty and returns // false if it is, then calls the BamList::getRecord member function with // the field parameter BR_ALLEY to search for a matching record // // CALLED BY: search_alley_do // CALLS: BamList::isEmpty,BamList::getRecord // // PARAMETERS: / in / alleyString - string that we're looking for in an alley // field of any record // // PRECONDITIONS: none // // POSTCONDITIONS: If the list is empty or no record with that value exists, // returns false, otherwise, returns true and moves CurrentBamRecord to // reference the appropriate record // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ bool searchByAlley(string alleyString) { if (BamList.isEmpty()) return false; else return (BamList.getRecord(alleyString,BR_ALLEY,CurrentBamRecord)); } /******************************************************************************* // FUNCTION NAME: searchByEvent // // DESCRIPTION OF FUNCTION: Determine if a record exists with a certain value // in its event field. // // DESCRIPTION OF ALGORITHM: Checks to see if the list is empty and returns // false if it is, then calls the BamList::getRecord member function with // the field parameter BR_EVENT to search for a matching record // // CALLED BY: search_event_do // CALLS: BamList::isEmpty,BamList::getRecord // // PARAMETERS: / in / eventString - string that we're looking for in an event // field of any record // // PRECONDITIONS: none // // POSTCONDITIONS: If the list is empty or no record with that value exists, // returns false, otherwise, returns true and moves CurrentBamRecord to // reference the appropriate record // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ bool searchByEvent(string eventString) { if (BamList.isEmpty()) return false; else return (BamList.getRecord(eventString,BR_EVENT,CurrentBamRecord)); } /******************************************************************************* // FUNCTION NAME: searchByDate // // DESCRIPTION OF FUNCTION: Determine if a record exists with a certain value // in its date field. // // DESCRIPTION OF ALGORITHM: Checks to see if the list is empty and returns // false if it is, then calls the BamList::getRecord member function with // the field parameter BR_DATE to search for a matching record // // CALLED BY: search_date_do // CALLS: BamList::isEmpty,BamList::getRecord // // PARAMETERS: / in / dateString - string that we're looking for in a date // field of any record // // PRECONDITIONS: none // // POSTCONDITIONS: If the list is empty or no record with that value exists, // returns false, otherwise, returns true and moves CurrentBamRecord to // reference the appropriate record // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ bool searchByDate(string dateString) { if (BamList.isEmpty()) return false; else return (BamList.getRecord(dateString,BR_DATE,CurrentBamRecord)); } /******************************************************************************* // FUNCTION NAME: Alley // // DESCRIPTION OF FUNCTION: Returns value of current record's alley field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Alley() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_ALLEY); else return ""; } /******************************************************************************* // FUNCTION NAME: Event // // DESCRIPTION OF FUNCTION: Returns value of current record's event field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Event() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_EVENT); else return ""; } /******************************************************************************* // FUNCTION NAME: Date // // DESCRIPTION OF FUNCTION: Returns value of current record's date field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Date() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_DATE); else return ""; } /******************************************************************************* // FUNCTION NAME: Ball // // DESCRIPTION OF FUNCTION: Returns value of current record's ball field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Ball() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_BALL); else return ""; } /******************************************************************************* // FUNCTION NAME: Lift // // DESCRIPTION OF FUNCTION: Returns value of current record's lift field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Lift() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_LIFT); else return ""; } /******************************************************************************* // FUNCTION NAME: Conditions // // DESCRIPTION OF FUNCTION: Returns value of current record's conditions field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Conditions() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_COND); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_1 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_1 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_1() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK1); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_2 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_2 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_2() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK2); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_3 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_3 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_3() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK3); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_4 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_4 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_4() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK4); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_5 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_5 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_5() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK5); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_6 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_6 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_6() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK6); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_7 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_7 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_7() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK7); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_8 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_8 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_8() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK8); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_9 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_9 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_9() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK9); else return ""; } /******************************************************************************* // FUNCTION NAME: Mark_10 // // DESCRIPTION OF FUNCTION: Returns value of current record's Mark_10 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Mark_10() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_MARK10); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_1 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE1 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_1() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE1); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_2 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE2 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_2() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE2); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_3 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE3 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_3() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE3); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_4 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE4 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_4() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE4); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_5 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE5 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_5() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE5); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_6 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE6 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_6() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE6); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_7 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE7 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_7() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE7); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_8 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE8 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_8() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE8); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_9 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE9 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_9() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE9); else return ""; } /******************************************************************************* // FUNCTION NAME: Score_10 // // DESCRIPTION OF FUNCTION: Returns value of current record's SCORE10 field // // DESCRIPTION OF ALGORITHM: If the current record is valid, calls // BamRecord::FieldContains with the appropriate BamRecordFieldType value. // Otherwise, returns a blank string. // // CALLED BY: UpdateAllObjects // CALLS: BamRecord::FieldContains // // PARAMETERS: none // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ string Score_10() { if (CurrentBamRecord) return CurrentBamRecord->element.FieldContains(BR_SCORE10); else return ""; } /******************************************************************************* // FUNCTION NAME: BuildBamList // // DESCRIPTION OF FUNCTION: Creates a linked-list of BamRecords from the data // stored in the other linked-lists // // DESCRIPTION OF ALGORITHM: For each game record, creates a BamRecord and // updates the fields with the slots referred to by the indices in the // original game record // // CALLED BY: openFile // CALLS: BuildGameFramesList,SyncFramesLists,ParseFrame // // PARAMETERS: / in / Alleys - AlleyListType that contains all of the records // referred to be G_ADEX in the game records // / in / Events - EventListType that contains all of the records // referred to by G_EDEX in the game reccords // / in / BallList - BallListType that contains all of the records // referred to by F_BDEX in the frame records // / in / Release - ReleaseListType that contains all of the // records referred to by F_RDEX in the frame // records // / in / CondList - ConditionsListType that contains all of the // records referred to by G_CDEX in the game // records // / in / Games - GameListType that contains all of the game // records to be added to the BamList // / in / Frames - FrameListType that contains all of the frame // records attached to the game records contained // in Games // / inout / BamList - BamListType to hold all of the newly // created BamRecords // // PRECONDITIONS: Any references in Games to Alley, Event or Conditions records // are valid. Any references in Frames to Games, Ball, or Release records are // valid. BamList is empty. // // POSTCONDITIONS: BamList contains one record for each record in Games, with // the information from parent tables included in its fields // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ void BuildBamList(AlleyListType& Alleys,EventListType& Events, BallListType& BallList, ReleaseListType& Release, ConditionsListType& CondList, GameListType& Games, FrameListType& Frames, BamListType& BamList) { GameListPtr currGamePtr; // Pointers for referencing parent tables AlleyListPtr currAlleyPtr; // EventListPtr currEventPtr; // ConditionsListPtr currCondPtr; // BallListPtr currBallPtr; // ReleaseListPtr currReleasePtr; // BamRecord insertRecord; // Temporary record for building list FrameListType tempFrames; // Temporary frames list for scoring FrameListPtr firstShot; // Frame pointer for referencing scores BamRecordFieldType markField=BR_MARK1; // Enum for loop control BamRecordFieldType scoreField=BR_SCORE1; // Enum for loop control int alleyIndex,eventIndex,ballIndex,releaseIndex; // For referencing parent int condIndex,gameIndex,bamIndex; // records char condBlock, relLift; // For converting from char to string data int frameCounter=1; // For loop control string Marks[10]; // To hold frame marking data string Scores[10]; // To hold cummulative score data int numberShots; // How many balls per frame? bool moreGames; // To control while-loop // To build subsidiary list for easy referencing within a game void BuildGameFramesList(int gameIndex, FrameListType& shortFrameList, FrameListType& wholeFrameList,GameListType& GameList); // To recombine the two lists into one big list void SyncFramesLists(FrameListType& littleList,FrameListType& bigList); // To score a frame void ParseFrame(FrameListPtr& firstBall,string& marks,string prevScore, string& currScore,int currFrame,int& ballsInFrame, FrameListType& FramesList); // Prime the loop moreGames = Games.getRecord(Games.smallestIndex(),currGamePtr); bamIndex=1; // Index of first new record while (moreGames) // For each active game record { insertRecord.NewIndex(bamIndex); // Store the record index bamIndex++; // Find the indices stored in the game record alleyIndex = atoi((currGamePtr->element.FieldContains(G_ADEX)).c_str()); eventIndex = atoi((currGamePtr->element.FieldContains(G_EDEX)).c_str()); condIndex = atoi((currGamePtr->element.FieldContains(G_CDEX)).c_str()); gameIndex = currGamePtr->element.IndexIs(); Alleys.getRecord(alleyIndex, currAlleyPtr); // get matching referenced Events.getRecord(eventIndex, currEventPtr); // records CondList.getRecord(condIndex, currCondPtr); // condBlock = (currCondPtr->element.FieldContains(C_BLOCK)).at(0); // Pull out the frame records that pertain to this game: BuildGameFramesList(gameIndex, tempFrames, Frames, Games); tempFrames.getRecord(tempFrames.smallestIndex(),firstShot); // Get the Release & Ball records that go with the first shot of the game ballIndex = atoi((firstShot->element.FieldContains(F_BDEX)).c_str()); releaseIndex = atoi((firstShot->element.FieldContains(F_RDEX)).c_str()); BallList.getRecord(ballIndex, currBallPtr); Release.getRecord(releaseIndex, currReleasePtr); relLift = (currReleasePtr->element.FieldContains(R_LIFT)).at(0); frameCounter=1; // Priming the while-loop while (frameCounter<10) // Gets all the frame info { if (frameCounter==1) ParseFrame(firstShot, Marks[frameCounter-1], "0",Scores[0], frameCounter, numberShots, tempFrames); else ParseFrame(firstShot, Marks[frameCounter-1],Scores[frameCounter-2], Scores[frameCounter-1], frameCounter, numberShots, tempFrames); if (numberShots==1) // If only 1 ball in frame, move pointer to next shot tempFrames.getNext(firstShot); else // If 2 shots in frame, move pointer down list 2 records { tempFrames.getNext(firstShot); tempFrames.getNext(firstShot); } frameCounter++; } if (frameCounter==10) // Tenth frame doesn't get pointers moved { ParseFrame(firstShot, Marks[9], Scores[8], Scores[9], frameCounter, numberShots, tempFrames); } int counter=0; // Store the frame marks into the temp record for (markField=BR_MARK1;markField<=BR_MARK10;markField=BamRecordFieldType(markField+1)) { insertRecord.Update(Marks[counter],markField); counter++; } counter=0; // Store the cummulative scores into the temp record for (scoreField=BR_SCORE1;scoreField<=BR_SCORE10;scoreField=BamRecordFieldType(scoreField+1)) { insertRecord.Update(Scores[counter],scoreField); counter++; } // Store the Alley Name, Event, Date, and Ball Name insertRecord.Update(currAlleyPtr->element.FieldContains(A_NAME),BR_ALLEY); insertRecord.Update(currEventPtr->element.FieldContains(E_TITLE),BR_EVENT); insertRecord.Update(currBallPtr->element.FieldContains(B_MODEL),BR_BALL); insertRecord.Update(currGamePtr->element.FieldContains(G_DATE),BR_DATE); switch (condBlock) // Store the Conditions Type { case 'C': insertRecord.Update("Crown",BR_COND); break; case 'B': insertRecord.Update("Block",BR_COND); break; case 'R': insertRecord.Update("Reverse",BR_COND); break; case 'T': insertRecord.Update("Tight",BR_COND); break; case 'L': insertRecord.Update("Loose",BR_COND); break; case 'U': insertRecord.Update("Unknown",BR_COND); break; default: insertRecord.Update("",BR_COND); break; } switch (relLift) // Store the Lift type { case 'N': insertRecord.Update("None",BR_LIFT); break; case 'T': insertRecord.Update("Touch",BR_LIFT); break; case 'L': insertRecord.Update("Light",BR_LIFT); break; case 'M': insertRecord.Update("Medium",BR_LIFT); break; case 'H': insertRecord.Update("Heavy",BR_LIFT); break; case 'X': insertRecord.Update("maX",BR_LIFT); break; default: insertRecord.Update("",BR_LIFT); break; } SyncFramesLists(tempFrames,Frames); // Recombine the frames lists if (!Games.isLastRecord(currGamePtr)) Games.getNext(currGamePtr); // move on to next game record else moreGames = false; BamList.insert(insertRecord); } // end of while-loop return; } /******************************************************************************* // FUNCTION NAME: BuildGameFramesList // // DESCRIPTION OF FUNCTION: Queries user for the index of the game they wish to // edit the frames for, then pulls any current frames with that game index out // of the wholeFrameList into a subsidiary list, shortFrameList. Reports back // the value of the game index chosen. // // DESCRIPTION OF ALGORITHM: Calls PromptForGameIndex to get user's selection // of which game's frames are being edited. Uses FrameListType member functions // to insert copies of the appropriate frame records into shortFramelist and // remove the originals from wholeFrameList // // CALLED BY: BuildBamList // CALLS:FrameListType::firstRecord,FrameListType::getNext, // FrameRecord::IndexIs,FrameListType::getRecord,FrameListType::insert, // FrameListType::remove // // PARAMETERS: / inout / shortFrameList - FrameListType to contain only the // frame records for the game being // edited // / inout / wholeFramelist - FrameListType that contains all // existing frame records // / in / GameList - GameListType that contains at least one game // record for selecting the index of the game's // frames to edit // // PRECONDITIONS: GameList is not empty // // POSTCONDITIONS: Any frame records in wholeFrameList which have the game // index value specified by the user have been copied into shortFrameList and // removed from wholeFrameList. // // AUTHOR: Amy Langill *2B DATE: 4/2/1999 *******************************************************************************/ void BuildGameFramesList(int gameIndex, FrameListType& shortFrameList, FrameListType& wholeFrameList,GameListType& GameList) { bool moreRecords; // Are there any more records in wholeFrameList? FrameListPtr showRecord; // Pointers to frame records for FrameListPtr nextRecord; // moving things around FrameRecord pullRecord; // For moving records between lists // Determine if there are any records in wholeFrameList moreRecords = wholeFrameList.firstRecord(showRecord); while (moreRecords) // While there are still more records in the list { if ((showRecord->element.IndexIs())/F_GDEX_MULTIPLIER == gameIndex) { // If it matches the right index: // Extract the data into the temporary record nextRecord = showRecord; moreRecords = wholeFrameList.getNext(nextRecord); if (wholeFrameList.getRecord(showRecord->element.IndexIs(),pullRecord)) { shortFrameList.insert(pullRecord); // Copy the record into new list wholeFrameList.remove(pullRecord); // Delete from old list } showRecord = nextRecord; } else moreRecords = wholeFrameList.getNext(showRecord); // If this record didn't } // match, try the next return; } /******************************************************************************* // FUNCTION NAME: SyncFramesLists // // DESCRIPTION OF FUNCTION: Combines the working frames list back into the // master frames list. // // DESCRIPTION OF ALGORITHM: For each record in littleList, copies that record // into bigList and removes it from LittleList. // // CALLED BY: BuildBamList // CALLS: FrameListType::firstRecord,FrameListType::insert, // FrameListType::remove,FrameRecord::IndexIs // // PARAMETERS: / inout / littleList - FrameListType to be copied into bigList // and emptied // / inout / bigList - FrameListType to contain entries in // littleList and self. // // PRECONDITIONS: none // // POSTCONDITIONS: Any records in littleList have been moved into bigList. // // AUTHOR: Amy Langill *2B DATE: 4/2/1999 *******************************************************************************/ void SyncFramesLists(FrameListType& littleList,FrameListType& bigList) { FrameListPtr showRecord; // Pointer for moving down list bool moreRecords; // Are there more record in the list? FrameRecord pullRecord; // Temp record for holding data for transfer moreRecords = littleList.firstRecord(showRecord); // Are there any records? while (moreRecords) // As long as there are records in littleList { // Copy the first record into the temp record littleList.getRecord(showRecord->element.IndexIs(),pullRecord); bigList.insert(pullRecord); // Copy it into the bigList littleList.remove(pullRecord); // Delete it from the littleList moreRecords = littleList.firstRecord(showRecord); // Move the pointer down } return; } /******************************************************************************* // FUNCTION NAME: ParseFrame // // DESCRIPTION OF FUNCTION: Determines the score and markings for a given frame // of a game, which can span more than one FrameRecord // // DESCRIPTION OF ALGORITHM: Retrieves first FrameRecord.Score. If that is a // strike, retrieves 2 more for scoring and computes score. If the first mark // isn't a strike but the second mark is a spare, retrieves 1 more mark for // scoring and computes score. Otherwise, computes score as the value of the // first two rolls. // // CALLED BY: BuildBamList // CALLS: BallValue // // PARAMETERS: / in / firstBall - FrameListPtr that indicates which record is // the first shot of the current frame // / inout / marks - string to hold the score markings for the // current frame // / in / prevScore - string that holds the cummulative score for // all previous frames // / inout / currScore - string to hold cummulative score through // current frame // / in / currFrame - int that tells which frame number is being // processed // / inout / ballsInFrame - int that tells how many shots were // taken in this frame // / in / FramesList - FrameListType that holds the FrameRecords // being scored // // PRECONDITIONS: FramesList is logically correct, and the values of all // records in the list are logically correct // // POSTCONDITIONS: marks contains a string which indicates what scoring marks // apply for the current frame. currScore contains a string which indicates // the cummulative score through the current frame. ballsInFrame indicates how // many rolls were bowled during the current frame. // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ void ParseFrame(FrameListPtr& firstBall,string& marks,string prevScore, string& currScore,int currFrame,int& ballsInFrame, FrameListType& FramesList) { FrameListPtr secondBall=firstBall; // Pointer to read second ball FramesList.getNext(secondBall); // Moving pointer to second ball FrameListPtr thirdBall=secondBall; // Pointer to read third ball, if needed char firstShot,secondShot,thirdShot; // Chars to hold score markings for each // ball bowled int frameScore=0; // int value of the score of this frame int prevString; // int value of the cummulative score thus far ballsInFrame=2; // number of shots taken during this frame istringstream prevConvert(prevScore); // Converting prevScore from string prevConvert >> prevString; // to int int BallValue(char frameMark); // For determining value of mark // Get the first two score marks firstShot = (firstBall->element.FieldContains(F_SCORE)).at(0); secondShot = (secondBall->element.FieldContains(F_SCORE)).at(0); if (currFrame < 10) // first nine frames are different from last one { FramesList.getNext(thirdBall); thirdShot = (thirdBall->element.FieldContains(F_SCORE)).at(0); if (firstShot=='X') { marks = " X"; ballsInFrame = 1; if (thirdShot=='/') frameScore=20; else frameScore = 10 + BallValue(secondShot) + BallValue(thirdShot); } else { ballsInFrame = 2; marks = firstShot; marks += secondShot; if (secondShot = '/') frameScore = 10 + BallValue(thirdShot); else frameScore = BallValue(firstShot) + BallValue(secondShot); } } else { if (firstShot=='X') { ballsInFrame = 3; FramesList.getNext(thirdBall); thirdShot = (thirdBall->element.FieldContains(F_SCORE)).at(0); marks = firstShot; marks += secondShot; marks += thirdShot; if (thirdShot=='/') frameScore = 20; else frameScore = 10 + BallValue(secondShot) + BallValue(thirdShot); } else if (secondShot=='/') { ballsInFrame = 3; FramesList.getNext(thirdBall); thirdShot = (thirdBall->element.FieldContains(F_SCORE)).at(0); marks = firstShot; marks += secondShot; marks += thirdShot; frameScore = 10 + BallValue(thirdShot); } else { ballsInFrame = 2; marks = firstShot; marks += secondShot; frameScore = BallValue(firstShot) + BallValue(secondShot); } } frameScore += prevString; // add up cummulative score ostringstream convertStream; // Convert to string convertStream << frameScore; // currScore = convertStream.str(); // return; } /******************************************************************************* // FUNCTION NAME: BallValue // // DESCRIPTION OF FUNCTION: Indicates how much a particular score mark is worth // // DESCRIPTION OF ALGORITHM: Depending on the value of frameMark, returns // 10, 0, or the integer equivalent of the frameMark character // // CALLED BY: ParseFrame // CALLS: none // // PARAMETERS: / in / frameMark - char that contains one of the valid bowling // scoring abbreviations // // AUTHOR: Amy Langill *2B DATE: 4/30/1999 *******************************************************************************/ int BallValue(char frameMark) { int value; // what the mark is worth string score; // for converting to integer score = frameMark; // switch (frameMark) { case 'X': value = 10; // strikes are worth 10 break; case '9': // integer score marks are worth the integer case '8': // equivalent of the score mark case '7': // case '6': // case '5': // case '4': // case '3': // case '2': // case '1': // case '0': // value = atoi(score.c_str()); // Calculating integer equivalent break; default: // Everything else is worth zilch value = 0; break; } return value; }