Draft controller class

This commit is contained in:
joe 2021-01-03 15:19:48 -08:00
parent e733059ac1
commit 2718f79c19
3 changed files with 165 additions and 0 deletions

2
.gitignore vendored
View File

@ -350,3 +350,5 @@ matteo.db
matteo.db-wal matteo.db-wal
matteo.db-shm matteo.db-shm
/matteo_env/Lib/site-packages/flask_socketio/__init__.py /matteo_env/Lib/site-packages/flask_socketio/__init__.py
env

View File

@ -7,6 +7,7 @@ import database as db
onomancer_url = "https://onomancer.sibr.dev/api/" onomancer_url = "https://onomancer.sibr.dev/api/"
name_stats_hook = "getOrGenerateStats?name=" name_stats_hook = "getOrGenerateStats?name="
collection_hook = "getCollection?token=" collection_hook = "getCollection?token="
names_hook = "getNames"
def get_stats(name): def get_stats(name):
player = db.get_stats(name) player = db.get_stats(name)
@ -36,3 +37,20 @@ def get_collection(collection_url):
db.cache_stats(player['name'], json.dumps(player)) db.cache_stats(player['name'], json.dumps(player))
return json.dumps(response.json()) return json.dumps(response.json())
def get_names(limit=20, threshold=1):
"""
Get `limit` random players that have at least `threshold` upvotes.
Returns dictionary keyed by player name of stats.
"""
response = requests.get(
onomancer_url + names_hook,
params={
'limit': limit,
'threshold': threshold,
'with_stats': 1,
'random': 1,
},
)
return {p['name']: p for p in response.json()}

145
the_draft.py Normal file
View File

@ -0,0 +1,145 @@
from collections import namedtuple
import games
import uuid
import onomancer
DRAFT_SIZE = 20
REFRESH_DRAFT_SIZE = 4 # fewer players remaining than this and the list refreshes
DRAFT_ROUNDS = 13
Participant = namedtuple('Participant', ['handle', 'team'])
BOOKMARK = Participant(handle="bookmark", team=None) # keep track of start/end of draft round
class Draft:
"""
Represents a draft party with n participants constructing their team from a pool
of names.
"""
_ongoing_drafts = {}
@classmethod
def make_draft(cls):
draft = cls()
cls._ongoing_drafts[draft._id] = draft
return draft
def __init__(self):
self._id = str(uuid.uuid4())[:6]
self._participants = []
self._active_participant = BOOKMARK # draft mutex
self._players = onomancer.get_names(limit=DRAFT_SIZE)
self._round = 0
@property
def round(self):
"""
Current draft round. 1 indexed.
"""
return self._round
@property
def active_drafter(self):
"""
Handle of whomever is currently up to draft.
"""
return self._active_participant.handle
def add_participant(self, handle, team_name, slogan):
"""
A participant is someone participating in this draft. Initializes an empty team for them
in memory.
`handle`: discord @ handle, for ownership and identification
"""
team = games.team()
team.name = team_name
team.slogan = slogan
self._participants.append(Participant(handle=handle, team=team))
def start_draft(self):
"""
Call after adding all participants and confirming they're good to go.
"""
self.advance_draft()
def refresh_players(self):
self._players = onomancer.get_names(limit=DRAFT_SIZE)
def advance_draft(self):
"""
The participant list is treated as a circular queue with the head being popped off
to act as the draftign mutex.
"""
if self._active_participant == BOOKMARK:
self._round += 1
self._participants.append(self._active_participant)
self._active_participant = self._participants.pop(0)
def get_draftees(self):
return list(self._players.keys())
def draft_player(self, handle, player_name):
"""
`handle` is the participant's discord handle.
"""
if self._active_participant.handle != handle:
raise ValueError('Invalid drafter')
player = self._players.get(player_name)
if not player:
# might be some whitespace shenanigans
for name, stats in self._players.items():
if name.replace('\xa0', ' ') == player_name:
player = stats
break
else:
# still not found
raise ValueError('Player not in draft list')
del self._players[player['name']]
if len(self._players) <= REFRESH_DRAFT_SIZE:
self.refresh_players()
if self._round < DRAFT_ROUNDS:
self._active_participant.team.add_lineup(player['name'])
elif self._round == DRAFT_ROUNDS:
self._active_participant.team.set_pitcher(player['name'])
self.advance_draft()
if self._active_participant == BOOKMARK:
self.advance_draft()
return player
def get_teams(self):
teams = {}
teams[self._active_participant.handle] = self._active_participant.team
for participant in self._participants:
teams[participant.handle] = participant.team
return teams
if __name__ == '__main__':
# extremely robust testing OC do not steal
# DRAFT_ROUNDS = 3
draft = Draft.make_draft()
draft.add_participant('@bluh', 'Bluhstein Bluhs', 'bluh bluh bluh')
draft.add_participant('@what', 'Barcelona IDK', 'huh')
draft.start_draft()
while draft.round <= DRAFT_ROUNDS:
print(draft.get_draftees())
cmd = input(f'{draft.round} {draft.active_drafter}:')
drafter, player = cmd.split(' ', 1)
try:
draft.draft_player(drafter, player)
except ValueError as e:
print(e)
print(draft.get_teams())
print(draft.get_teams()['@bluh'].lineup)
print(draft.get_teams()['@bluh'].pitcher)
print(draft.get_teams()['@what'].lineup)
print(draft.get_teams()['@what'].pitcher)