Написать класс Monster(Имя, Позиция, Задержка, Сила), определяющий поведение монстра в одномерной аркаде.
Имя — строка, остальные параметры — натуральные числа.
Класс имеет также метод-корутину .run(начало_эпизода, конец_эпизода).
начало_эпизода и конец_эпизода — это asyncio барьеры, которые предполагается использовать в программе
При задержке == N корутина прибавляет 1 к Позиции монстра каждое N-е событие начало_эпизода, если этот монстр жив
Написать также корутину game(монстры, начало_эпизода, конец_эпизода, эпоха), которая после каждого события конец_эпизода:
Просматривает массив монстров монстры
Находит в нём самую левую пару живых монстров, чья Позиция совпадает
- Если таких больше двух, берутся первые два в порядке перечисления в массиве
Заставляет эту пару сражаться: если их Сила равна, умирают оба, если нет — сила выжившего уменьшается на значение силы умершего
Работа game() заканчивается:
Если все монстры умерли, тогда она возвращает "All dead"
Если все монстры выжили после эпоха эпизодов, возвращает "All flee"
- В противном случае возвращается список выживших монстров (через пробел с запятой)
Корутина main() в тестах не меняется
1 async def main(*specs):
2 monsters = [Monster(*spec) for spec in specs]
3 animate, freeze = asyncio.Barrier(len(monsters) + 1), asyncio.Barrier(len(monsters) + 1)
4 squad = [asyncio.create_task(m.run(animate, freeze)) for m in monsters]
5 result = await game(monsters, animate, freeze, 10000)
6 _ = [m.cancel() for m in squad]
7 return result
8
9 print(asyncio.run(main(("Kano", 1, 1, 20), ("Sonya", 2, 2, 15), ("Liu Kang", 4, 3, 10))))
10 print(asyncio.run(main(("Sonya", 2, 2, 15), ("Johnny Cage", 1, 3, 1))))
11 print(asyncio.run(main(("Kano", 1, 1, 20), ("Sonya", 2, 2, 15), ("Liu Kang", 4, 3, 10), ("Kabal", 5, 1, 5))))
12 print(asyncio.run(main(("Milena", 1, 1, 15), ("Kitana", 2, 2, 15))))
Главный затык у меня был с тем, что корутины после прохождения барьера активизируются в рандомном порядке, но достаточно после прохождения в game() добавить .sleep(0), чтобы оно ещё раз выпало в образующий цикл, и вернулось строго после монстров
Liu Kang All flee Liu Kang, Kabal All dead