Подсчет очков для боулинга
была задача:
Всего 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])