t | import asyncio | t | import asyncio |
| | | |
| class Monster: | | class Monster: |
| | | |
| def __init__(self, name, position, delay, power): | | def __init__(self, name, position, delay, power): |
| self.name = name | | self.name = name |
| self.position = position | | self.position = position |
| self.delay = delay | | self.delay = delay |
| self.power = power | | self.power = power |
| self.alive = True | | self.alive = True |
| self.episode_count = 0 | | self.episode_count = 0 |
| | | |
| async def run(self, start_event, end_event): | | async def run(self, start_event, end_event): |
| try: | | try: |
| while True: | | while True: |
| await start_event.wait() | | await start_event.wait() |
| self.episode_count += 1 | | self.episode_count += 1 |
| if self.alive and self.delay > 0 and (self.episode_count | | if self.alive and self.delay > 0 and (self.episode_count |
| % self.delay == 0): | | % self.delay == 0): |
| self.position += 1 | | self.position += 1 |
| await end_event.wait() | | await end_event.wait() |
| except asyncio.CancelledError: | | except asyncio.CancelledError: |
| pass | | pass |
| | | |
| async def game(monsters, start_event, end_event, epochs): | | async def game(monsters, start_event, end_event, epochs): |
| for _ in range(epochs): | | for _ in range(epochs): |
| await start_event.wait() | | await start_event.wait() |
| await end_event.wait() | | await end_event.wait() |
| positions = {} | | positions = {} |
| for i, m in enumerate(monsters): | | for i, m in enumerate(monsters): |
| if m.alive: | | if m.alive: |
| positions.setdefault(m.position, []).append((i, m)) | | positions.setdefault(m.position, []).append((i, m)) |
| pair = None | | pair = None |
| for pos in sorted(positions.keys()): | | for pos in sorted(positions.keys()): |
| if len(positions[pos]) > 1: | | if len(positions[pos]) > 1: |
| i1, m1 = positions[pos][0] | | i1, m1 = positions[pos][0] |
| i2, m2 = positions[pos][1] | | i2, m2 = positions[pos][1] |
| pair = (m1, m2) | | pair = (m1, m2) |
| break | | break |
| if pair is not None: | | if pair is not None: |
| m1, m2 = pair | | m1, m2 = pair |
| if m1.power == m2.power: | | if m1.power == m2.power: |
| m1.alive = False | | m1.alive = False |
| m2.alive = False | | m2.alive = False |
| elif m1.power > m2.power: | | elif m1.power > m2.power: |
| m1.power -= m2.power | | m1.power -= m2.power |
| m2.alive = False | | m2.alive = False |
| else: | | else: |
| m2.power -= m1.power | | m2.power -= m1.power |
| m1.alive = False | | m1.alive = False |
| living = [m for m in monsters if m.alive] | | living = [m for m in monsters if m.alive] |
| if not living: | | if not living: |
| return 'All dead' | | return 'All dead' |
| if len(living) == 1: | | if len(living) == 1: |
| return living[0].name | | return living[0].name |
| living = [m for m in monsters if m.alive] | | living = [m for m in monsters if m.alive] |
| if len(living) == len(monsters): | | if len(living) == len(monsters): |
| return 'All flee' | | return 'All flee' |
| else: | | else: |
| return ', '.join((m.name for m in living)) | | return ', '.join((m.name for m in living)) |