Подсчет очков для боулинга

была задача:

Всего 10 кеглей. Игра состоит из 10 фреймов. В одном фрейме до 2х бросков, цель - сбить все кегли.
Результаты фрейма записываются символами:
«Х» – «strike», все 10 кеглей сбиты первым броском
«<число>/», например «4/» - «spare», в первый бросок сбиты 4 кегли, во второй – остальные
«<число><число>», например, «34» – в первый бросок сбито 3, во второй – 4 кегли.
вместо <число> может стоять прочерк «-», например «-4» - ни одной кегли не было сбито за первый бросок
Результат игры – строка с записью результатов фреймов. Символов-разделителей между фреймами нет.
Например, для игры из 4 фреймов запись результатов может выглядеть так:
  «Х4/34-4»
Предлагается упрощенный способ подсчета количества очков:
  «Х» – strike всегда 20 очков
  «4/» - spare всегда 15 очков
  «34» – сумма 3+4=7
  «-4» - сумма 0+4=4
То есть для игры «Х4/34-4» сумма очков равна 20+15+7+4=46

которая была решена таким образом:

def analyzing_result(result):
    global analized_res, total
    analized_res = {}
    total = 0
    frames = 0
    for _ in result:
        for i, k in enumerate(zip(result.replace('X', 'X-')[0::2], result.replace('X', 'X-')[1::2]), start=1):
            analized_res[i] = k
    for k, v in analized_res.items():
        frames += 1
        check_errors(v)
        result_count(v)
    print(total)
    if frames != 10:
        raise Exception('Не правильное количество фреймов!')
    return total


def result_count(v):
    global total
    if 'X' in v:
        total += 20
    elif '/' in v:
        total += 15
    elif '-' in v:
        total += 0
    else:
        total += int(v[0]) + int(v[1])
    return v


def check_errors(v):
    if '0' in v:
        raise ValueError('Введено неправильное значение')
    elif '/' in v[0]:
        raise ValueError('Spare на первом броске')
    elif 'X' in v[1]:
        raise ValueError('Strike на втором броске')
    if v[0].isdigit() and v[1].isdigit() and int(v[0]) + int(v[1]) >= 10:
        raise ValueError('Введено неправильное значение, сумма одного фрейма больше 9 очков')


result = '12X34-/1744XX23--'
analyzing_result(result=result)

result 106

сейчас условия поменялись:

 Если во фрейме страйк, сумма очков за этот фрейм будет равна количеству сбитых кеглей в этом фрейме (10 кеглей)
 плюс количество фактически сбитых кеглей за два следующих броска (в одном или двух фреймах,
 в зависимости от того, был ли страйк в следующем броске).
 Если во фрейме сбит спэр, то сумма очков будет равна количеству сбитых кеглей в этом фрейме (10 кеглей)
 плюс количество фактически сбитых кеглей за первый бросок в следующем фрейме.
 Если фрейм остался открытым, то сумма очков будет равна количеству сбитых кеглей в этом фрейме.
 Страйк и спэр в последнем фрейме - по 10 очков.

 То есть для игры «Х4/34» сумма очков равна 10+10 + 10+3 + 3+4 = 40,
 а для игры «ХXX347/21» - 10+20 + 10+13 + 10+7 + 3+4 + 10+2 + 3 = 92
 Необходимые изменения сделать во всех модулях. Тесты - дополнить.

 "И да, старые правила должны остаться! для внутреннего рынка..." - уточнил менеджер напоследок.

и тут меня настиг ступор, даже не пойму как к ней подойти, и как правильно вести подсчет...


Ответы (1 шт):

Автор решения: barthezz

Этот код помог

def count_worldwide(k, v):
    global total
    if 'X' in v:
        if 'X' in analized_res[k + 1]:
            if 'X' in analized_res[k + 2]:
                total += 30
            elif '-' in analized_res[k + 2][0]:
                total += 20
            else:
                total += 20 + int(analized_res[k + 2][0])
        elif '/' in analized_res[k + 1]:
            total += 20
        elif '-' in analized_res[k + 1][0]:
            if '-' in analized_res[k + 1][1]:
                total += 10
            else:
                total += 10 + int(analized_res[k + 1][1])
        elif '-' in analized_res[k + 1][1]:
            total += 10 + int(analized_res[k + 1][0])
        else:
            total += 10 + int(analized_res[k + 1][0]) + int(analized_res[k + 1][1])
    elif '/' in v:
        if 'X' in analized_res[k + 1]:
            total += 20
        elif '/' in analized_res[k + 1][0]:
            raise ValueError('Spare на первом броске')
        elif '-' in analized_res[k + 1][0]:
            total += 10
        else:
            total += 10 + int(analized_res[k + 1][0])
    elif '-' in v[0]:
        if '-' in v[1]:
            total += 0
        elif '/' in v[1]:
            pass
        else:
            total += int(v[1])
    elif '-' in v[1]:
        if '-' in v[0]:
            total += 0
        elif 'X' in v[0]:
            pass
        else:
            total += int(v[0])
    else:
        if v[0].isdigit and v[1].isdigit:
            total += int(v[0]) + int(v[1])
→ Ссылка