/** fill a substitution matrix */ HSubstitutionMatrix makeSubstitutionMatrix( const ScoreVector & scores, int nrows, int ncols) { debug_func_cerr( 5 ); assert( nrows * ncols == scores.size() ); HSubstitutionMatrix matrix(new SubstitutionMatrix( nrows, ncols, 0)); unsigned int row = 0; unsigned int col = 0; for (int x = 0; x < scores.size(); ++ x) { matrix->setValue( row, col++, scores[x] ); if (col > ncols) { ++nrows; col = 0; } } return matrix; }
// this is terrible code int calculate_final_score( const ScoreVector& score_sheet ) { int final_score = 0; auto get_score = [&]( int index ) -> int { switch ( score_sheet[index] ) { case STRIKE: return MAX_SCORE; case SPARE: if ( STRIKE == score_sheet[index-1] || SPARE == score_sheet[index-1] ) { throw Exception(MESSAGE_INVALID); } return MAX_SCORE - char_to_int( score_sheet[index - 1] ); default: return char_to_int( score_sheet[index] ); } }; int frames_played = 0; for ( size_t i = 0; i < score_sheet.size(); ) { int score_1 = 0, score_2 = 0; switch ( score_sheet[i] ) { case STRIKE: // check for end of score sheet if ( i + 2 >= score_sheet.size() ) { i += 2; break; } // strike must be alone if ( STRIKE != score_sheet[i+1] && STRIKE == score_sheet[i+2] ) { throw Exception(MESSAGE_INVALID); } score_1 = get_score( i + 1 ); score_2 = get_score( i + 2 ); if ( is_num( score_sheet[i+1] ) && is_num( score_sheet[i+2] ) && MAX_SCORE <= score_1 + score_2 ) { throw Exception(MESSAGE_INVALID); } final_score += MAX_SCORE + score_1 + score_2; i += 1; frames_played++; // check for end of score sheet if ( i + 2 >= score_sheet.size() ) { i += 2; } break; // can only end with a spare case SPARE: throw Exception(MESSAGE_INVALID); // digit default: { // following a strike as the bowl of the last frame there should be two more bowls // following neither a strike or spare there should be nothing if ( 0 != i && i + 1 == score_sheet.size() && (STRIKE == score_sheet[i-1] || SPARE != score_sheet[i-1]) ) { throw Exception(MESSAGE_INVALID); } // check for end of score sheet if ( i + 1 >= score_sheet.size() ) { i += 1; break; } int score = char_to_int( score_sheet[i] ); switch ( score_sheet[i+1] ) { // a strike is always by itself case STRIKE: throw Exception(MESSAGE_INVALID); case SPARE: // if last frame there should be another bowl if ( i + 2 >= score_sheet.size() ) { throw Exception(MESSAGE_INVALID); } final_score += MAX_SCORE + get_score( i + 2 ); break; default: int total_score = score + char_to_int( score_sheet[i + 1] ); if ( MAX_SCORE <= total_score ) { throw Exception(MESSAGE_INVALID); } final_score += total_score; break; } i+= 2; frames_played++; }break; } if ( frames_played > FRAMES_PER_GAME ) { throw Exception(MESSAGE_INVALID); } } if ( frames_played < FRAMES_PER_GAME ) { throw Exception(MESSAGE_INVALID); } return final_score; }