finished implementing tournaments, slowed game ticks to 8 seconds
This commit is contained in:
parent
63db3ba1be
commit
ff582d8709
5
games.py
5
games.py
|
@ -185,12 +185,11 @@ class team(object):
|
||||||
for this_player in self.rotation:
|
for this_player in self.rotation:
|
||||||
for stat in this_player.game_stats.keys():
|
for stat in this_player.game_stats.keys():
|
||||||
this_player.game_stats[stat] = 0
|
this_player.game_stats[stat] = 0
|
||||||
return True
|
return self
|
||||||
|
|
||||||
def finalize(self):
|
def finalize(self):
|
||||||
if self.is_ready():
|
if self.is_ready():
|
||||||
if self.pitcher is None:
|
self.set_pitcher()
|
||||||
self.set_pitcher()
|
|
||||||
while len(self.lineup) <= 4:
|
while len(self.lineup) <= 4:
|
||||||
self.lineup.append(random.choice(self.lineup))
|
self.lineup.append(random.choice(self.lineup))
|
||||||
return self
|
return self
|
||||||
|
|
53
leagues.py
53
leagues.py
|
@ -20,14 +20,25 @@ class division(object):
|
||||||
self.teams = {} #key: team object, value: {wins; rd (run diff)}
|
self.teams = {} #key: team object, value: {wins; rd (run diff)}
|
||||||
|
|
||||||
class tournament(object):
|
class tournament(object):
|
||||||
def __init__(self, name, team_dic, series_length = 5, max_innings = 9):
|
def __init__(self, name, team_dic, series_length = 5, finals_series_length = 7, max_innings = 9, id = None, secs_between_games = 300, secs_between_rounds = 600):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.teams = team_dic #same format as division, wins/losses will be used for seeding later
|
self.teams = team_dic #same format as division, wins/losses will be used for seeding later
|
||||||
self.bracket = None
|
self.bracket = None
|
||||||
self.results = None
|
self.results = None
|
||||||
self.series_length = series_length
|
self.series_length = series_length
|
||||||
|
self.finals_length = finals_series_length
|
||||||
self.game_length = max_innings
|
self.game_length = max_innings
|
||||||
self.active = False
|
self.active = False
|
||||||
|
self.delay = secs_between_games
|
||||||
|
self.round_delay = secs_between_rounds
|
||||||
|
self.finals = False
|
||||||
|
self.id = id
|
||||||
|
|
||||||
|
if id is None:
|
||||||
|
self.id = random.randint(1111,9999)
|
||||||
|
else:
|
||||||
|
self.id = id
|
||||||
|
|
||||||
|
|
||||||
def build_bracket(self, random_sort = False, by_wins = False):
|
def build_bracket(self, random_sort = False, by_wins = False):
|
||||||
teams_list = list(self.teams.keys()).copy()
|
teams_list = list(self.teams.keys()).copy()
|
||||||
|
@ -46,12 +57,12 @@ class tournament(object):
|
||||||
|
|
||||||
teams_list.sort(key=sorter, reverse=True)
|
teams_list.sort(key=sorter, reverse=True)
|
||||||
|
|
||||||
|
|
||||||
bracket_layers = int(math.ceil(math.log(len(teams_list), 2)))
|
bracket_layers = int(math.ceil(math.log(len(teams_list), 2)))
|
||||||
empty_slots = int(math.pow(2, bracket_layers) - len(teams_list))
|
empty_slots = int(math.pow(2, bracket_layers) - len(teams_list))
|
||||||
|
|
||||||
for i in range(0, empty_slots):
|
for i in range(0, empty_slots):
|
||||||
teams_list.append(None)
|
teams_list.append(None)
|
||||||
print(teams_list)
|
|
||||||
|
|
||||||
previous_bracket_layer = teams_list.copy()
|
previous_bracket_layer = teams_list.copy()
|
||||||
for i in range(0, bracket_layers - 1):
|
for i in range(0, bracket_layers - 1):
|
||||||
|
@ -60,19 +71,27 @@ class tournament(object):
|
||||||
if pair % 2 == 0: #if even number
|
if pair % 2 == 0: #if even number
|
||||||
this_layer.insert(0+int(pair/2), [previous_bracket_layer.pop(0), previous_bracket_layer.pop(-1)]) #every other pair goes at front of list, moving forward
|
this_layer.insert(0+int(pair/2), [previous_bracket_layer.pop(0), previous_bracket_layer.pop(-1)]) #every other pair goes at front of list, moving forward
|
||||||
else:
|
else:
|
||||||
this_layer.insert(0-int((1+pair)/2), [previous_bracket_layer.pop(0), previous_bracket_layer.pop(-1)]) #every other pair goes at end of list, moving backward
|
this_layer.insert(0-int((1+pair)/2), [previous_bracket_layer.pop(int(len(previous_bracket_layer)/2)-1), previous_bracket_layer.pop(int(len(previous_bracket_layer)/2))]) #every other pair goes at end of list, moving backward
|
||||||
previous_bracket_layer = this_layer
|
previous_bracket_layer = this_layer
|
||||||
print(previous_bracket_layer)
|
|
||||||
self.bracket = bracket(previous_bracket_layer, bracket_layers)
|
self.bracket = bracket(previous_bracket_layer, bracket_layers)
|
||||||
self.bracket.get_bottom_row()
|
|
||||||
|
def round_check(self):
|
||||||
|
if self.bracket.depth == 1:
|
||||||
|
self.finals = True
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
class bracket(object):
|
class bracket(object):
|
||||||
|
this_bracket = []
|
||||||
|
|
||||||
def __init__(self, bracket_list, depth):
|
def __init__(self, bracket_list, depth):
|
||||||
self.this_bracket = bracket_list
|
self.this_bracket = bracket_list
|
||||||
self.depth = depth
|
self.depth = depth
|
||||||
self.bottom_row = []
|
self.bottom_row = []
|
||||||
|
|
||||||
def get_bottom_row(self):
|
def get_bottom_row(self):
|
||||||
|
self.depth = 1
|
||||||
self.bottom_row = []
|
self.bottom_row = []
|
||||||
self.dive(self.this_bracket)
|
self.dive(self.this_bracket)
|
||||||
return self.bottom_row
|
return self.bottom_row
|
||||||
|
@ -81,4 +100,28 @@ class bracket(object):
|
||||||
if not isinstance(branch[0], list): #if it's a pair of games
|
if not isinstance(branch[0], list): #if it's a pair of games
|
||||||
self.bottom_row.append(branch)
|
self.bottom_row.append(branch)
|
||||||
else:
|
else:
|
||||||
|
self.depth += 1
|
||||||
return self.dive(branch[0]), self.dive(branch[1])
|
return self.dive(branch[0]), self.dive(branch[1])
|
||||||
|
|
||||||
|
#def set_winners(self, branch, winners_list):
|
||||||
|
#new_bracket =
|
||||||
|
|
||||||
|
def set_winners_dive(self, winners_list, index = 0, branch = None, parent = None):
|
||||||
|
if branch is None:
|
||||||
|
branch = self.this_bracket.copy()
|
||||||
|
if not isinstance(branch[0], list): #if it's a pair of games
|
||||||
|
if branch[0].name in winners_list or branch[1] is None:
|
||||||
|
winner = branch[0]
|
||||||
|
if parent is not None:
|
||||||
|
parent[index] = winner
|
||||||
|
elif branch[1].name in winners_list:
|
||||||
|
winner = branch[1]
|
||||||
|
if parent is not None:
|
||||||
|
parent[index] = winner
|
||||||
|
else:
|
||||||
|
self.set_winners_dive(winners_list, index = 0, branch = branch[0], parent = branch)
|
||||||
|
self.set_winners_dive(winners_list, index = 1, branch = branch[1], parent = branch)
|
||||||
|
|
||||||
|
if parent is None:
|
||||||
|
self.this_bracket = branch
|
||||||
|
return branch
|
|
@ -153,4 +153,4 @@ def update_loop():
|
||||||
})
|
})
|
||||||
|
|
||||||
socketio.emit("states_update", data_to_send)
|
socketio.emit("states_update", data_to_send)
|
||||||
time.sleep(6)
|
time.sleep(8)
|
||||||
|
|
190
the_prestige.py
190
the_prestige.py
|
@ -427,25 +427,38 @@ class AssignOwnerCommand(Command):
|
||||||
|
|
||||||
class StartTournamentCommand(Command):
|
class StartTournamentCommand(Command):
|
||||||
name = "starttournament"
|
name = "starttournament"
|
||||||
template = "m;starttournament"
|
template = """m;starttournament
|
||||||
description = "We'll DM you and get your own tournament set up. Just follow our instructions and we'll be right as rain."
|
[tournament name]
|
||||||
|
[list of teams, each on a new line]"""
|
||||||
|
description = "Starts a tournament with the teams given. Byes will be given to teams to allow for numbers other than powers of two. The current tournament format is:\nBest of 5 until the finals, which are Best of 7"
|
||||||
|
|
||||||
async def execute(self, msg, command):
|
async def execute(self, msg, command):
|
||||||
test_bracket = {
|
to_parse = command.split("\n")[0]
|
||||||
games.get_team("Milwaukee Lockpicks") : {"wins": 10, "rd": 0},
|
if "--rounddelay " in to_parse:
|
||||||
games.get_team("Madagascar Penguins") : {"wins": 2, "rd": 0},
|
try:
|
||||||
games.get_team("Twin Cities Evening") : {"wins": 1, "rd": 0},
|
round_delay = int(to_parse.split("--rounddelay ")[1].split(" ")[0])
|
||||||
games.get_team("Washington State Houses") : {"wins": 9, "rd": 0},
|
except ValueError:
|
||||||
games.get_team("Appalachian Underground") : {"wins": 8, "rd": 0},
|
await msg.channel.send("The delay between rounds should be a whole number.")
|
||||||
games.get_team("Pacific2 Rams") : {"wins": 3, "rd": 0},
|
return
|
||||||
games.get_team("New Jersey Radio") : {"wins": 45, "rd": 0},
|
if round_delay < 1 or round_delay > 120:
|
||||||
games.get_team("Moline Jolenes") : {"wins": 44, "rd": 0},
|
await msg.channel.send("The delay between rounds has to be between 1 and 120 minutes.")
|
||||||
games.get_team("California Commissioners") : {"wins": 41, "rd": 0},
|
else:
|
||||||
games.get_team("Pigeon’s Reckoning") : {"wins": 45, "rd": 0},
|
round_delay = 10
|
||||||
games.get_team("Kernow Technologists") : {"wins": 42, "rd": 0}
|
|
||||||
}
|
tourney_name = command.split("\n")[1]
|
||||||
tourney = leagues.tournament("Test Tourney", test_bracket, max_innings=3)
|
list_of_team_names = command.split("\n")[2:]
|
||||||
tourney.build_bracket(by_wins=True)
|
team_dic = {}
|
||||||
|
for name in list_of_team_names:
|
||||||
|
team = get_team_fuzzy_search(name.strip())
|
||||||
|
if team == None:
|
||||||
|
await msg.channel.send(f"We couldn't find {name}. Try again?")
|
||||||
|
return
|
||||||
|
team_dic[team] = {"wins": 0}
|
||||||
|
|
||||||
|
id = random.randint(1111,9999)
|
||||||
|
|
||||||
|
tourney = leagues.tournament(tourney_name, team_dic, id=id, secs_between_rounds = round_delay * 60)
|
||||||
|
tourney.build_bracket(random_sort = True)
|
||||||
|
|
||||||
await start_tournament_round(msg.channel, tourney)
|
await start_tournament_round(msg.channel, tourney)
|
||||||
|
|
||||||
|
@ -477,7 +490,7 @@ commands = [
|
||||||
|
|
||||||
client = discord.Client()
|
client = discord.Client()
|
||||||
gamesarray = []
|
gamesarray = []
|
||||||
gamesqueue = []
|
active_tournaments = []
|
||||||
setupmessages = {}
|
setupmessages = {}
|
||||||
|
|
||||||
thread1 = threading.Thread(target=main_controller.update_loop)
|
thread1 = threading.Thread(target=main_controller.update_loop)
|
||||||
|
@ -684,7 +697,10 @@ async def watch_game(channel, newgame, user = None, league = None):
|
||||||
discrim_string = league
|
discrim_string = league
|
||||||
state_init["is_league"] = True
|
state_init["is_league"] = True
|
||||||
elif user is not None:
|
elif user is not None:
|
||||||
discrim_string = f"Started by {user.name}"
|
if isinstance(user, str):
|
||||||
|
discrim_string = f"Started by {user}"
|
||||||
|
else:
|
||||||
|
discrim_string = f"Started by {user.name}"
|
||||||
state_init["is_league"] = False
|
state_init["is_league"] = False
|
||||||
else:
|
else:
|
||||||
discrim_string = "Unclaimed game."
|
discrim_string = "Unclaimed game."
|
||||||
|
@ -739,13 +755,12 @@ async def start_tournament_round(channel, tourney, seeding = None):
|
||||||
|
|
||||||
for pair in games_to_start:
|
for pair in games_to_start:
|
||||||
if pair[0] is not None and pair[1] is not None:
|
if pair[0] is not None and pair[1] is not None:
|
||||||
this_game = games.game(pair[0].finalize(), pair[1].finalize(), length = tourney.game_length)
|
this_game = games.game(pair[0].prepare_for_save().finalize(), pair[1].prepare_for_save().finalize(), length = tourney.game_length)
|
||||||
this_game, state_init = prepare_game(this_game)
|
this_game, state_init = prepare_game(this_game)
|
||||||
|
|
||||||
state_init["is_league"] = True
|
state_init["is_league"] = True
|
||||||
state_init["title"] = f"{tourney.name}: Round of {len(games_to_start)*2}"
|
state_init["title"] = f"0 - 0"
|
||||||
discrim_string = tourney.name
|
discrim_string = tourney.name
|
||||||
print(discrim_string)
|
|
||||||
|
|
||||||
timestamp = str(time.time() * 1000.0 + random.randint(0,3000))
|
timestamp = str(time.time() * 1000.0 + random.randint(0,3000))
|
||||||
current_games.append((this_game, timestamp))
|
current_games.append((this_game, timestamp))
|
||||||
|
@ -753,28 +768,100 @@ async def start_tournament_round(channel, tourney, seeding = None):
|
||||||
|
|
||||||
ext = "?league=" + urllib.parse.quote_plus(tourney.name)
|
ext = "?league=" + urllib.parse.quote_plus(tourney.name)
|
||||||
|
|
||||||
await channel.send(f"{len(current_games)} games started for the {tourney.name} tournament, at {config()['simmadome_url']+ext}")
|
if tourney.round_check(): #if finals
|
||||||
await tourney_watcher(channel, tourney, current_games)
|
await channel.send(f"The {tourney.name} finals are starting now, at {config()['simmadome_url']+ext}")
|
||||||
|
finals = True
|
||||||
|
else:
|
||||||
|
await channel.send(f"{len(current_games)} games started for the {tourney.name} tournament, at {config()['simmadome_url']+ext}")
|
||||||
|
finals = False
|
||||||
|
await tourney_round_watcher(channel, tourney, current_games, config()['simmadome_url']+ext, finals)
|
||||||
|
|
||||||
|
async def continue_tournament_series(tourney, queue, games_list, wins_in_series):
|
||||||
|
for oldgame in queue:
|
||||||
|
away_team = games.get_team(oldgame.teams["away"].name)
|
||||||
|
home_team = games.get_team(oldgame.teams["home"].name)
|
||||||
|
this_game = games.game(away_team.finalize(), home_team.finalize(), length = tourney.game_length)
|
||||||
|
this_game, state_init = prepare_game(this_game)
|
||||||
|
|
||||||
async def tourney_watcher(channel, tourney, games_list):
|
state_init["is_league"] = True
|
||||||
|
|
||||||
|
state_init["title"] = f"{wins_in_series[oldgame.teams['away'].name]} - {wins_in_series[oldgame.teams['home'].name]}"
|
||||||
|
|
||||||
|
discrim_string = tourney.name
|
||||||
|
|
||||||
|
timestamp = str(time.time() * 1000.0 + random.randint(0,3000))
|
||||||
|
games_list.append((this_game, timestamp))
|
||||||
|
main_controller.master_games_dic[timestamp] = (this_game, state_init, discrim_string)
|
||||||
|
|
||||||
|
return games_list
|
||||||
|
|
||||||
|
async def tourney_round_watcher(channel, tourney, games_list, filter_url, finals = False):
|
||||||
tourney.active = True
|
tourney.active = True
|
||||||
while len(games_list) > 0:
|
active_tournaments.append(tourney)
|
||||||
try:
|
wins_in_series = {}
|
||||||
for i in range(0, len(games_list)):
|
winner_list = []
|
||||||
game, key = games_list[i]
|
while tourney.active:
|
||||||
if game.over and main_controller.master_games_dic[key][1]["end_delay"] <= 9:
|
queued_games = []
|
||||||
final_embed = game_over_embed(game)
|
while len(games_list) > 0:
|
||||||
await channel.send(f"A {tourney.name} game just ended!")
|
try:
|
||||||
await channel.send(embed=final_embed)
|
for i in range(0, len(games_list)):
|
||||||
games_list.pop(i)
|
game, key = games_list[i]
|
||||||
break
|
if game.over and main_controller.master_games_dic[key][1]["end_delay"] <= 9:
|
||||||
except:
|
if game.teams['home'].name not in wins_in_series.keys():
|
||||||
print("something went wrong in tourney_watcher")
|
wins_in_series[game.teams["home"].name] = 0
|
||||||
|
if game.teams['away'].name not in wins_in_series.keys():
|
||||||
|
wins_in_series[game.teams["away"].name] = 0
|
||||||
|
|
||||||
|
winner_name = game.teams['home'].name if game.teams['home'].score > game.teams['away'].score else game.teams['away'].name
|
||||||
|
|
||||||
|
if winner_name in wins_in_series.keys():
|
||||||
|
wins_in_series[winner_name] += 1
|
||||||
|
else:
|
||||||
|
wins_in_series[winner_name] = 1
|
||||||
|
|
||||||
|
final_embed = game_over_embed(game)
|
||||||
|
await channel.send(f"A {tourney.name} game just ended!")
|
||||||
|
await channel.send(embed=final_embed)
|
||||||
|
if wins_in_series[winner_name] >= int((tourney.series_length+1)/2) and not finals:
|
||||||
|
winner_list.append(winner_name)
|
||||||
|
elif wins_in_series[winner_name] >= int((tourney.finals_length+1)/2):
|
||||||
|
winner_list.append(winner_name)
|
||||||
|
else:
|
||||||
|
queued_games.append(game)
|
||||||
|
|
||||||
|
games_list.pop(i)
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
print("something went wrong in tourney_watcher")
|
||||||
|
await asyncio.sleep(4)
|
||||||
|
|
||||||
|
|
||||||
|
if len(queued_games) > 0:
|
||||||
|
await channel.send(f"The next batch of games for {tourney.name} will start in {int(tourney.delay/60)} minutes.")
|
||||||
|
await asyncio.sleep(tourney.delay)
|
||||||
|
await channel.send(f"{len(queued_games)} games for {tourney.name}, starting at {filter_url}")
|
||||||
|
games_list = await continue_tournament_series(tourney, queued_games, games_list, wins_in_series)
|
||||||
|
else:
|
||||||
|
tourney.active = False
|
||||||
|
|
||||||
|
if finals: #if this last round was finals
|
||||||
|
embed = discord.Embed(color = discord.Color.dark_purple(), title = f"{winner_list[0]} win the {tourney.name} finals!")
|
||||||
|
await channel.send(embed=embed)
|
||||||
|
active_tournaments.pop(active_tournaments.index(tourney))
|
||||||
|
return
|
||||||
|
|
||||||
|
tourney.bracket.set_winners_dive(winner_list)
|
||||||
|
|
||||||
|
winners_string = ""
|
||||||
|
for game in tourney.bracket.get_bottom_row():
|
||||||
|
winners_string += f"{game[0].name}\n{game[1].name}\n"
|
||||||
|
await channel.send(f"""
|
||||||
|
This round of games for {tourney.name} is now complete! The next round will be starting in {int(tourney.round_delay/60)} minutes.
|
||||||
|
Advancing teams:
|
||||||
|
{winners_string}""")
|
||||||
|
await asyncio.sleep(tourney.round_delay)
|
||||||
|
await start_tournament_round(channel, tourney)
|
||||||
|
|
||||||
await asyncio.sleep(4)
|
|
||||||
tourney.active = False
|
|
||||||
await channel.send(f"This round of games for {tourney.name} is now complete!")
|
|
||||||
|
|
||||||
|
|
||||||
async def team_delete_confirm(channel, team, owner):
|
async def team_delete_confirm(channel, team, owner):
|
||||||
|
@ -843,8 +930,8 @@ def team_from_collection(newteam_json):
|
||||||
raise CommandError("We've given you 100 characters for the slogan. Discord puts limits on us and thus, we put limits on you. C'est la vie.")
|
raise CommandError("We've given you 100 characters for the slogan. Discord puts limits on us and thus, we put limits on you. C'est la vie.")
|
||||||
if len(newteam_json["lineup"]) > 20:
|
if len(newteam_json["lineup"]) > 20:
|
||||||
raise CommandError("20 players in the lineup, maximum. We're being really generous here.")
|
raise CommandError("20 players in the lineup, maximum. We're being really generous here.")
|
||||||
if not len(newteam_json["rotation"]) == 1:
|
if not len(newteam_json["rotation"]) > 8:
|
||||||
raise CommandError("One and only one pitcher per team, thanks.")
|
raise CommandError("8 pitchers on the rotation, max. That's a *lot* of pitchers.")
|
||||||
for player in newteam_json["lineup"] + newteam_json["rotation"]:
|
for player in newteam_json["lineup"] + newteam_json["rotation"]:
|
||||||
if len(player["name"]) > 70:
|
if len(player["name"]) > 70:
|
||||||
raise CommandError(f"{player['name']} is too long, chief. 70 or less.")
|
raise CommandError(f"{player['name']} is too long, chief. 70 or less.")
|
||||||
|
@ -1003,4 +1090,23 @@ def get_team_fuzzy_search(team_name):
|
||||||
team = teams[0]
|
team = teams[0]
|
||||||
return team
|
return team
|
||||||
|
|
||||||
|
|
||||||
|
#test_bracket = {
|
||||||
|
# "Milwaukee Lockpicks" : {"wins": 4, "rd": 0},
|
||||||
|
# "Madagascar Penguins" : {"wins": 2, "rd": 0},
|
||||||
|
# "Twin Cities Evening" : {"wins": 1, "rd": 0},
|
||||||
|
# "Washington State Houses" : {"wins": 9, "rd": 0},
|
||||||
|
# "Appalachian Underground" : {"wins": 8, "rd": 0},
|
||||||
|
# "Pacific2 Rams" : {"wins": 3, "rd": 0},
|
||||||
|
# "New Jersey Radio" : {"wins": 11, "rd": 0},
|
||||||
|
# "Moline Jolenes" : {"wins": 6, "rd": 0},
|
||||||
|
# "California Commissioners" : {"wins": 10, "rd": 0},
|
||||||
|
# "Pigeon’s Reckoning" : {"wins": 7, "rd": 0},
|
||||||
|
# "Kernow Technologists" : {"wins": 5, "rd": 0}
|
||||||
|
# }
|
||||||
|
#tourney = leagues.tournament("Test Tourney", test_bracket, max_innings=3)
|
||||||
|
#tourney.build_bracket(by_wins=True)
|
||||||
|
#tourney.bracket.set_winners_dive(['Twin Cities Evening','Madagascar Penguins', 'Pacific2 Rams'])
|
||||||
|
#print(tourney.bracket.this_bracket)
|
||||||
|
|
||||||
client.run(config()["token"])
|
client.run(config()["token"])
|
Loading…
Reference in New Issue
Block a user