-
Notifications
You must be signed in to change notification settings - Fork 0
/
nfl_draft.py
114 lines (91 loc) · 3.37 KB
/
nfl_draft.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import numpy as np
class DraftState:
def __init__(self, rosters, turns, freeagents, playerjm=None):
self.rosters = rosters
self.turns = turns
self.freeagents = freeagents
self.playerJustMoved = playerjm
class NflPlayer:
def __init__(self, name, position, points, high, low):
self.name = name
self.position = position
self.points = points
self.high = high
self.low = low
def __repr__(self):
return "|".join([self.name, self.position, str(self.points)])
def GetResult(self, playerjm):
""" Get the game result from the viewpoint of playerjm.
"""
if playerjm is None: return 0
pos_wgts = {
("QB"): [.5, .5],
("WR"): [.5, .5, .5, .5],
("RB"): [.5, .5, .5, .5],
("TE"): [.02],
("RB", "WR", 'TE'): [.5, .5, 0.2]
}
result = 0
# map the drafted players to the weights
for p in self.rosters[playerjm]:
max_wgt, _, max_pos, old_wgts = max(
((wgts[0], -len(lineup_pos), lineup_pos, wgts) for lineup_pos, wgts in pos_wgts.items()
if p.position in lineup_pos),
default=(0, 0, (), []))
if max_wgt > 0:
random_points = np.random.randint(p.low, p.high + 1, 1)[0]
result += max_wgt * random_points
old_wgts.pop(0)
if not old_wgts:
pos_wgts.pop(max_pos)
# map the remaining weights to the top three free agents
for pos, wgts in pos_wgts.items():
result += np.mean(
[np.random.randint(p.low, p.high + 1, 1)[0] for p in self.freeagents if p.position in pos][:5])
return result
def GetMoves(self):
""" Get all possible moves from this state.
"""
pos_max = {"QB": 2, "WR": 6, "RB": 6, "TE": 2}
if len(self.turns) == 0: return []
roster_positions = np.array([p.position for p in self.rosters[self.turns[0]]], dtype=str)
moves = [pos for pos, max_ in pos_max.items() if np.sum(roster_positions == pos) < max_]
return moves
def DoMoveDraft(self, player):
player = [p for p in self.freeagents if p.name == player][0]
self.freeagents.remove(player)
rosterId = self.turns.pop(0)
self.rosters[rosterId].append(player)
self.playerJustMoved = rosterId
def DoMove(self, move):
""" Update a state by carrying out the given move.
Must update playerJustMoved.
"""
# get highest random
def random_sample(p):
v = []
for i in np.arange(0, 25):
v.append(np.random.randint(p.low, p.high+1, 1)[0])
random_dist = np.abs(np.random.normal(p.points, (p.high - p.low) / 4))
return (np.mean(v) + p.points + random_dist + p.high - p.low) / 4
try:
ss = [[p, random_sample(p)] for p in self.freeagents if p.position == move]
if len(ss) >= 5:
ss = ss[:5]
else:
ss = ss[:3]
ss = sorted(ss, key=lambda x: x[1], reverse=True)
player = next(p[0] for p in ss)
except:
player = None
self.freeagents.remove(player)
rosterId = self.turns.pop(0)
self.rosters[rosterId].append(player)
self.playerJustMoved = rosterId
def Clone(self):
""" Create a deep clone of this game state.
"""
rosters = list(map(lambda r: r[:], self.rosters))
st = DraftState(rosters, self.turns[:], self.freeagents[:],
self.playerJustMoved)
return st