Last active
January 4, 2021 08:34
-
-
Save leehosung/f784d9efc71dce12855739647dd98877 to your computer and use it in GitHub Desktop.
PyCon Korea 2017 - dodo fighter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
import sys | |
import random | |
# λλ νμ΄ν°μ μ°Έκ°νκΈ° μν΄μλ μμ΄μ νΈλ₯Ό λ§λ€μ΄μ μ μΆν΄ μ£Όμ μΌ ν©λλ€. | |
# μμ΄μ νΈλ μ¬μ©μκ° μμ±νλ μΈκ³΅μ§λ₯ μ½λλ‘μ, μ£Όμ΄μ§λ νμ¬ κ²μ μνλ₯Ό λ°νμΌλ‘ | |
# μ΄λ€ μ‘μ μ μ·¨ν μ§λ₯Ό κ²°μ νλ μν μ ν©λλ€. | |
# | |
# μ‘μ μ€λͺ | |
# - idle - μ무κ²λ νμ§ μμ΅λλ€. | |
# - forward - μμΌλ‘ μμ§μ λλ€. μλκ° λ°λ‘ μμ μμ κ²½μ° λ μμ§μ΄μ§ μμ΅λλ€. | |
# - backward - λ€λ‘ μμ§μ λλ€. μ²μ μμμ§μ μμ μΈμΉΈ μ΄μ λ€λ‘ κ° μ μμ΅λλ€. | |
# - punch - μλ¨μ 곡격ν©λλ€. | |
# - kick - νλ¨μ 곡격ν©λλ€. | |
# - crouch - μλ¨ κ³΅κ²©μ νΌν©λλ€. | |
# - jump - νλ¨ κ³΅κ²©μ νΌν©λλ€. | |
# - guard - 곡격μ λ°©μ΄ν©λλ€. μνλ¨ λͺ¨λ λ°©μ΄ν μ μμ§λ§ μ½κ°μ λ°λ―Έμ§λ₯Ό μ μ΅λλ€. | |
# | |
# μν μ€λͺ | |
# - distance - μλλ°©κ³Ό λμμ 거리. 0μΌ κ²½μ°μλ§ κ³΅κ²©μ΄ κ°λ₯ν©λλ€. | |
# - time_left - λ¨μ μκ° | |
# - health - λμ 체λ ₯ | |
# - opponent_health - μλμ 체λ ₯ | |
# - opponent_action - μ§λ ν΄μμ μλμ μ‘μ | |
# - given_damage - μ§μ μ‘μ μμ λ΄κ° μλλ°©μκ² κ°ν λ°λ―Έμ§ | |
# - taken_damage - μ§μ μ‘μ μμ μλλ°©μ΄ λμκ² κ°ν λ°λ―Έμ§ | |
# - match_records - μ§κΈκΉμ§μ κ²½κΈ° κΈ°λ‘. 리μ€νΈ νμμ λλ€. | |
# μλ₯Ό λ€μ΄ [None, True, False]μΈ κ²½μ°, 첫λ²μ§Έ κ²½κΈ°λ 무μΉλΆ, | |
# λλ²μ§Έ κ²½κΈ°λ λΉμ μ΄, μΈλ²μ§Έ κ²½κΈ°λ μλλ°©μ΄ μ΄κ²Όλ€λ λ»μ λλ€. | |
# | |
# μ£Όμμ¬ν | |
# - κ°μ μ‘μ μ κ³μ λ°λ³΅νμ§ λ§μΈμ. 곡격λ ₯μ΄ νλ½λλ νλν°κ° μμ΅λλ€. | |
# - μλμ 곡격μ ννΌνκ±°λ λ§λλ° μ±κ³΅νλ©΄ λ€μ 곡격μμ 곡격λ ₯ 보λμ€κ° μμ΅λλ€. | |
# - ν ν΄ λ΄μμλ μ΄λκ³Ό λ°©μ΄ λμμ΄ κ³΅κ²© λμλ³΄λ€ μ°μ ν©λλ€. | |
# μ¦, P1μ΄ κ³΅κ²©μ νκ³ P2κ° μ΄λνλ€λ©΄ P2κ° μ΄λνλ μ‘μ μ μ°μ νκ°ν©λλ€. | |
# - μ¬μ©ν μ μλ λͺ¨λμ random, json, sys, mathλ‘ νμ λμ΄ μμ΅λλ€. | |
# - μ€ν¬λ¦½νΈ μ€ν μκ°μ΄ 3μ΄λ₯Ό λμ΄κ°λ©΄ νλ½ μ²λ¦¬λ©λλ€. | |
last_action = 'idle' | |
attack_actions = ['punch', 'kick'] | |
defence_actions = ['crouch', 'jump', 'guard'] | |
available_backsteps = 3 | |
accumulated_given_damage = 0 | |
accumulated_taken_damage = 0 | |
def action(what): | |
global last_action | |
if what not in ('idle', 'forward', 'backward', 'punch', 'kick', | |
'crouch', 'jump', 'guard'): | |
raise ValueError(f'Unknown action type: {what}') | |
last_action = what | |
sys.stdout.write(what + '\n') | |
sys.stdout.flush() | |
def read_status(): | |
data = sys.stdin.readline() | |
while data: | |
yield json.loads(data) | |
data = sys.stdin.readline() | |
def attack(): | |
"""곡격""" | |
action(random.choice(attack_actions)) | |
def defence(): | |
"""λ°©μ΄μ ννΌ | |
λ°©μ΄μ μ΅μ μ λ§μ§ μλ κ²μ λλ€. λ€λ‘ λλ§κ° μ μμΌλ©΄ λλ§κ°λλ€. | |
λ μ΄μ λλ§κ° κ³³μ΄ μμΌλ©΄ λλ€μΌλ‘ νΌνκ±°λ λ§μ΅λλ€. | |
""" | |
global available_backsteps | |
if available_backsteps > 0: | |
available_backsteps -= 1 | |
action('backward') | |
else: | |
action(random.choice(defence_actions)) | |
def success_defence(taken_damage, opponent_action): | |
"""λ°©μ΄μ μ±κ³΅ νλκ°? | |
κ±°λ¦¬κ° 0 μΌλ, λ€μ 3κ°μ§ κ²½μ°λ λ°©μ΄μ μ±κ³΅ν κ²μ λλ€. | |
- λ°©μ΄(guard)λ₯Ό μ ννλλ° λ°λ―Έμ§λ₯Ό μ μ κ²½μ° | |
- μλ¨ννΌ(crouch)λ₯Ό μ ννλλ° μλλ°©μ΄ μλ¨κ³΅κ²©(punch)μ ν κ²½μ° | |
- νλ¨ννΌ(jump)λ₯Ό μ ννλλ° μλλ°©μ΄ νλ¨κ³΅κ²©(kick)μ ν κ²½μ° | |
λ°©μ΄μ μ±κ³΅νλ©΄ 곡격λ ₯ 보λμ€λ₯Ό λ°μ΅λλ€. 곡격! | |
:param taken_damage: λ΄κ° μ μ λ°λ―Έμ§ | |
:param opponent_action: μλλ°©μ΄ μ νν λμ | |
:return: | |
bool: λ°©μ΄μ μ±κ³΅ νμΌλ©΄ True, λ°©μ΄μ μ€ν¨ νμΌλ©΄ False | |
""" | |
return (taken_damage > 0 and last_action == 'guard') or \ | |
(last_action == 'crouch' and opponent_action == 'punch') or \ | |
(last_action == 'jump' and opponent_action == 'kick') | |
def fail_attack(given_damage, opponent_action): | |
"""곡격μ μ€ν¨νλκ°? μ¦, μλλ°©μ΄ λ°©μ΄,ννΌμ μ±κ³΅ νλκ°? | |
κ±°λ¦¬κ° 0μΌ λ, λ€μ 3κ°μ§ κ²½μ°λ μλλ°©μ΄ λ°©μ΄μ μ±κ³΅ν κ²μ λλ€. | |
- 곡격μ μ ννλλ° μλνΈμ΄ λ°©μ΄(guard)λ₯Ό μ νν κ²½μ° | |
- 곡격μ μ ννλλ° μλνΈμ΄ λ°λ―Έμ§λ₯Ό μ μ§ μμ κ²½μ°, μ¦ μ,νλ¨μ λ§μΆ°μ νΌν κ²½μ° | |
μλλ°©μ΄ κ³΅κ²©λ ₯ 보λμ€λ₯Ό λ°μ΅λλ€. λλ§κ°κ±°λ λ°©μ΄λ₯Ό ν©μλ€. | |
:param given_damage: μλλ°©μ΄ λ§μ λ°λ―Έμ§ | |
:param opponent_action: μλλ°©μ΄ μ νν λμ | |
:return: | |
bool: 곡격μ μ€ν¨ νμΌλ©΄ True, 곡격μ μ±κ³΅ νμΌλ©΄ False | |
""" | |
return last_action in attack_actions and (given_damage == 0 or opponent_action == 'guard') | |
def do_random_action(health, opponent_health): | |
"""λλ€ νλμ ν©λλ€. | |
μ리λ₯Ό μ΄λνμ§ μκ³ κ³΅κ²©μ±μ λ°λΌμ λλ€ νλμ ν©λλ€. μ§κ³ μμ μλ‘ μ κ·Ήμ μΌλ‘ 곡격μ ν΄μ μμ μ λ Έλ €μΌ ν©λλ€. | |
곡격μ±μ "μλλ°©μ 체λ ₯/(μλλ°©μ 체λ ₯ + λμ 체λ ₯)" μΌλ‘ μ μν©λλ€. μμͺ½μ 체λ ₯μ΄ κ°μ λμλ 곡격과 λ°©μ΄λ₯Ό μ νν νλ₯ μ΄ κ°μ΅λλ€. | |
:param health: λμ 체λ ₯ | |
:param opponent_health: μλλ°©μ 체λ ₯ | |
""" | |
aggressivity = opponent_health * 1.0 / (opponent_health + health) | |
random_action = random.choices([attack, defence], weights=[aggressivity, 1 - aggressivity])[0] | |
random_action() | |
for status in read_status(): | |
distance = status['distance'] | |
time_left = status['time_left'] | |
health = status['health'] | |
opponent_health = status['opponent_health'] | |
opponent_action = status['opponent_action'] | |
given_damage = status['given_damage'] | |
taken_damage = status['taken_damage'] | |
match_records = status['match_records'] | |
accumulated_given_damage += given_damage | |
accumulated_taken_damage += taken_damage | |
# κ±°λ¦¬κ° 2μΉΈμ΄λ©΄ λ€κ°κ°λ λ§μ§ μμ΅λλ€. ν κ±Έμ λ€κ°κ°λλ€. λμ€μ λλ§κ° μ¬μ λ₯Ό λ§λ€μ΄ λ‘λλ€. | |
if distance >= 2: | |
action('forward') | |
available_backsteps += 1 | |
# κ±°λ¦¬κ° 1μΉΈμ΄λ©΄ λ€κ°κ°λ©΄ λ§μ΅λλ€. μλλ°©μ΄ λ€κ°μ¬μ§ λͺ¨λ₯΄λ 곡격μ ν©μλ€. | |
elif distance == 1: | |
# μλ‘κ° μΈμ΄μ μ΄ μμΌλ©΄ λ€κ°κ°μ§ μμ΅λλ€. νλ²λ μΈμ°μ§ μμ κ²½μ°μλ κ°λ§ν μλ λλ―Έ μμ΄μ νΈλ₯Ό μ΄κΈ°κΈ° μν΄μ 5μ΄λ₯Ό λ¨κΈ°κ³ λ€κ°κ°λλ€. | |
if accumulated_given_damage == 0 and accumulated_taken_damage == 0 and time_left < 5: | |
action('forward') | |
# μλλ°©μ΄ λ€κ°μ€μ§ μμΌλ©΄ ν곡μ κ³μ μ£Όλ¨Ήμ§, λ°κΈΈμ§μ νκ³ μμ κ°λ₯μ±μ΄ λμ΅λλ€. | |
# κ°μ λμμ μ°μμΌλ‘ νλ©΄ ν¨λν°κ° μμ΅λλ€. μ£Όλ¨Ήμ§, λ°κΈΈμ§μ λ²κ°μ κ°λ©΄μ ν©μλ€. | |
elif last_action == 'punch': | |
action('kick') | |
elif last_action == 'kick': | |
action('punch') | |
# μ무 곡격μ΄λ ν©μλ€. | |
else: | |
attack() | |
# κ±°λ¦¬κ° 0μΉΈ μ λλ€. | |
else: | |
# λ°©μ΄μ μ±κ³΅νλ€λ©΄ 곡격λ ₯ 보λμ€κ° μκΉλλ€. 곡격ν©μλ€. | |
if success_defence(taken_damage, opponent_action): | |
attack() | |
# 곡격μ μ€ν¨νλ€λ©΄ μλλ°©μ΄ κ³΅κ²©λ ₯ 보λμ€κ° μκΉλλ€. λλ§κ°κ±°λ λ§μμλ€. | |
elif fail_attack(given_damage, opponent_action): | |
defence() | |
# μμͺ½λ€ 보λμ€κ° μλ μν©μ΄λΌλ©΄ λλ€νλμ ν©λλ€. | |
else: | |
do_random_action(health, opponent_health) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment