티스토리 뷰


[lv1]


-  플레이어 객체를 만든다 (Player)

class Player:


[lv2]


-  생성자에는 가위, 바위, 보 확률 3개를 각각 0~100 까지 정수로 정의한다.

> 3개 합은 정확히 100이 되어야만 한다.


home = Player(30, 50, 20)



[lv3]


- Player 클래스에서 match() 를 작성한다.

> 매개변수는 Player 인스턴스 2개를 받는다


예시)

home = Player(30, 50, 20)
away = Player(50, 30, 20)
Player.match(home, away)


- 출력 첫줄에는 홈, 어웨이의 결과와 승패를 다음과 같이 출력한다.

- 둘째 줄에는 현재까지 승수(승률) 패수(패률) 무승부수(무승부율)을 홈, 어웨이 각각 다음과 같이 출력한다.


출력)

match: home=바위(lose) away=보(win)
record: home=2430(0.362),1947(0.29),2338(0.348) away=1947(0.29),2430(0.362),2338(0.348)


 

[lv4]


Player 클래스에 prediction() 함수를 작성한다.

- 매개변수에는 홈, 어웨이 2개를 받는다.


home = Player(30, 50, 20)
away = Player(50, 30, 20)
Player.predict(home, away)


- 출력은 홈과 어웨이의 예상 승율/패율/무승부율 을 다음과 같이 출력한다.

predict: home=[0.37, 0.29, 0.34] away=[0.29, 0.37, 0.34]



[테스트]


- 실제 결과가 예상 승률에 수렴하면 정답


- 100% 일치하지는 않아도 횟수가 증가할 수록 오차는 줄어들어야 한다.

predict: home=[0.37, 0.29, 0.34] away=[0.29, 0.37, 0.34]
match: home=바위(lose) away=보(win)
record: home=2430(0.362),1947(0.29),2338(0.348) away=1947(0.29),2430(0.362),2338(0.348)





소스

from itertools import cycle
import random


class Player:
types, max_p = ("가위", "바위", "보"), 100

def __init__(self, *args):
size = len(Player.types)
assert len(args) == size and sum(args) == Player.max_p, "invalid syntax"
self.ps, self.history, self.rates = args, [0] * size, [0] * size

def put(self):
return Player.types.index(random.choice([Player.types[i] for i, p in enumerate(self.ps) for __ in range(p)]))

def set(self, i):
self.history[i] += 1
self.rates = [round(case/sum(self.history), 3) for i, case in enumerate(self.history)]

@classmethod
def record(cls, h, a, r_h, r_a):
h.set(r_h), a.set(r_a)
print("{}: home={} away={}".format(cls.record.__name__, h, a))

@classmethod
def match(cls, h, a, r_ts=("win", "lose", "draw")):
h_p, a_p = h.put(), a.put()
key = {1: 'h_win', -2: 'h_win', -1: 'h_lose', 2: 'h_lose', 0: 'h_draw'}[h_p - a_p]
r_h, r_a = {'h_win': (0, 1), 'h_lose': (1, 0), 'h_draw': (2, 2)}[key]
print("{}: home={}({}) away={}({})".format(cls.match.__name__, cls.types[h_p], r_ts[r_h], cls.types[a_p], r_ts[r_a]))
cls.record(h, a, r_h, r_a)

@classmethod
def win(cls, w, l, draw=False):
w_cy, l_cy = cycle(w.ps), cycle(l.ps)
if not draw:
next(w_cy)
return sum([next(w_cy) * next(l_cy) for _ in cls.types]) / (cls.max_p ** 2)

@classmethod
def predict(cls, h, a):
w, l, d = cls.win(h, a), cls.win(a, h), cls.win(h, a, draw=True)
print("{}: home={} away={}".format(cls.predict.__name__, *((w, l, d), (l, w, d))))

def __str__(self):
return "{}".format(",".join([str(case[0]) + "(" + str(case[1]) + ")" for case in list(zip(self.history, self.rates))]))


home = Player(10, 10, 80)
away = Player(50, 30, 20)
while True:
Player.predict(home, away)
Player.match(home, away)


댓글