m;starttournament now starts a debug tournament

This commit is contained in:
Sakimori 2021-01-03 06:06:51 -05:00
parent 22150033ca
commit 12255e3eef
4 changed files with 164 additions and 110 deletions

View File

@ -200,8 +200,7 @@ class team(object):
class game(object): class game(object):
def __init__(self, name, team1, team2, length=None): def __init__(self, team1, team2, length=None):
self.name = name
self.over = False self.over = False
self.teams = {"away" : team1, "home" : team2} self.teams = {"away" : team1, "home" : team2}
self.inning = 1 self.inning = 1

View File

@ -16,18 +16,22 @@ class league(object):
class division(object): class division(object):
def __init__(self): def __init__(self):
self.teams = {} #key: team object, value: {wins; losses; run diff} self.teams = {} #key: team object, value: {wins; rd (run diff)}
class tournament(object): class tournament(object):
def __init__(self, team_dic): def __init__(self, name, team_dic, series_length = 5, maxinnings = 9):
self.teams = {} #same format as division, wins/losses will be used for seeding later self.name = name
self.bracket = {} self.teams = team_dic #same format as division, wins/losses will be used for seeding later
self.bracket_layers = 0 self.bracket = None
self.results = None
self.series_length = series_length
self.game_length = maxinnings
self.active = False
def build_bracket(self, random = False, by_wins = False): def build_bracket(self, random_sort = False, by_wins = False):
teams_list = self.teams.keys().copy() teams_list = list(self.teams.keys()).copy()
if random: if random_sort:
def sorter(team_in_list): def sorter(team_in_list):
return random.random() return random.random()
@ -35,14 +39,43 @@ class tournament(object):
def sorter(team_in_list): def sorter(team_in_list):
return self.teams[team_in_list][0] #sorts by wins return self.teams[team_in_list][0] #sorts by wins
if not random and not by_wins: #sort by average stars else: #sort by average stars
def sorter(team_in_list): def sorter(team_in_list):
return team_in_list.average_stars() return team_in_list.average_stars()
teams_list.sort(key=sorter, reverse=True) teams_list.sort(key=sorter, reverse=True)
self.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)
previous_bracket_layer = teams_list.copy()
for i in range(0, bracket_layers-1):
this_layer = []
for pair in range(0, int(len(previous_bracket_layer)/2)):
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
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
previous_bracket_layer = this_layer
self.bracket = bracket(previous_bracket_layer, bracket_layers)
self.bracket.get_bottom_row()
class bracket(object):
def __init__(self, bracket_list, depth):
self.this_bracket = bracket_list
self.depth = depth
self.bottom_row = []
def get_bottom_row(self):
self.bottom_row = []
self.dive(self.this_bracket)
return self.bottom_row
def dive(self, branch):
if not isinstance(branch[0], list): #if it's a pair of games
self.bottom_row.append(branch)
else:
return self.dive(branch[0]), self.dive(branch[1])

View File

@ -61,10 +61,6 @@
<Content Include="ids" /> <Content Include="ids" />
<Content Include="matteo.db" /> <Content Include="matteo.db" />
<Content Include="static\discord.png" /> <Content Include="static\discord.png" />
<Content Include="static\game.html" />
<Content Include="static\games_page.css" />
<Content Include="static\loader.js" />
<Content Include="static\prism.png" />
<Content Include="templates\game.html" /> <Content Include="templates\game.html" />
<Content Include="templates\index.html" /> <Content Include="templates\index.html" />
</ItemGroup> </ItemGroup>

View File

@ -169,7 +169,7 @@ class StartGameCommand(Command):
return return
if team1 is not None and team2 is not None: if team1 is not None and team2 is not None:
game = games.game(msg.author.name, team1.finalize(), team2.finalize(), length=innings) game = games.game(team1.finalize(), team2.finalize(), length=innings)
channel = msg.channel channel = msg.channel
await msg.delete() await msg.delete()
@ -179,30 +179,6 @@ class StartGameCommand(Command):
await msg.channel.send("We can't find one or both of those teams. Check your staging, chief.") await msg.channel.send("We can't find one or both of those teams. Check your staging, chief.")
return return
class SetupGameCommand(Command):
name = "setupgame"
template = "m;setupgame"
description = "Begins setting up a 3-inning pickup game. Pitchers, lineups, and team names are given during the setup process by anyone able to type in that channel. Idols are easily signed up via emoji during the process. The game will start automatically after setup."
async def execute(self, msg, command):
if len(gamesarray) > 45:
await msg.channel.send("We're running 45 games and we doubt Discord will be happy with any more. These edit requests don't come cheap.")
return
elif config()["game_freeze"]:
await msg.channel.send("Patch incoming. We're not allowing new games right now.")
return
for game in gamesarray:
if game.name == msg.author.name:
await msg.channel.send("You've already got a game in progress! Wait a tick, boss.")
return
try:
inningmax = int(command)
except:
inningmax = 3
game_task = asyncio.create_task(setup_game(msg.channel, msg.author, games.game(msg.author.name, games.team(), games.team(), length=inningmax)))
await game_task
class SaveTeamCommand(Command): class SaveTeamCommand(Command):
name = "saveteam" name = "saveteam"
template = """m;saveteam template = """m;saveteam
@ -445,7 +421,6 @@ class AssignOwnerCommand(Command):
return user.id in config()["owners"] return user.id in config()["owners"]
async def execute(self, msg, command): async def execute(self, msg, command):
#try:
new_owner = msg.mentions[0] new_owner = msg.mentions[0]
team_name = command.strip().split(new_owner.mention+" ")[1] team_name = command.strip().split(new_owner.mention+" ")[1]
print(team_name) print(team_name)
@ -453,8 +428,32 @@ class AssignOwnerCommand(Command):
await msg.channel.send(f"{team_name} is now owned by {new_owner.display_name}. Don't break it.") await msg.channel.send(f"{team_name} is now owned by {new_owner.display_name}. Don't break it.")
else: else:
await msg.channel.send("We couldn't find that team. Typo?") await msg.channel.send("We couldn't find that team. Typo?")
#except:
#await msg.channel.send("We hit a snag. Tell xvi.") class StartTournamentCommand(Command):
name = "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."
async def execute(self, msg, command):
test_bracket = {
games.get_team("Milwaukee Lockpicks") : {"wins": 0, "rd": 0},
games.get_team("Madagascar Penguins") : {"wins": 0, "rd": 0},
games.get_team("Twin Cities Evening") : {"wins": 0, "rd": 0},
games.get_team("Washington State Houses") : {"wins": 0, "rd": 0},
games.get_team("Appalachian Underground") : {"wins": 0, "rd": 0},
games.get_team("Pacific2 Rams") : {"wins": 0, "rd": 0},
games.get_team("New Jersey Radio") : {"wins": 0, "rd": 0},
games.get_team("Moline Jolenes") : {"wins": 0, "rd": 0},
games.get_team("California Commissioners") : {"wins": 0, "rd": 0},
games.get_team("Pigeons Reckoning") : {"wins": 0, "rd": 0},
games.get_team("Kernow Technologists") : {"wins": 0, "rd": 0}
}
tourney = leagues.tournament("Test Tourney", test_bracket)
tourney.build_bracket(random_sort=True)
tourney_task = asyncio.create_task(start_tournament_round(msg.channel, tourney))
await tourney_task
commands = [ commands = [
@ -476,6 +475,7 @@ commands = [
ShowAllTeamsCommand(), ShowAllTeamsCommand(),
SearchTeamsCommand(), SearchTeamsCommand(),
StartGameCommand(), StartGameCommand(),
StartTournamentCommand(),
CreditCommand(), CreditCommand(),
RomanCommand(), RomanCommand(),
HelpCommand(), HelpCommand(),
@ -558,19 +558,6 @@ async def on_message(msg):
except CommandError as ce: except CommandError as ce:
await msg.channel.send(str(ce)) await msg.channel.send(str(ce))
async def start_game(channel):
msg = await channel.send("Play ball!")
await asyncio.sleep(4)
newgame = games.debug_game()
gamesarray.append(newgame)
while not newgame.over:
state = newgame.gamestate_update_full()
if not state.startswith("Game over"):
await msg.edit(content=state)
await asyncio.sleep(3)
await channel.send(state)
gamesarray.pop()
async def setup_game(channel, owner, newgame): async def setup_game(channel, owner, newgame):
newgame.owner = owner newgame.owner = owner
@ -697,32 +684,7 @@ Creator, type `{newgame.name} done` to finalize lineups.""")
await game_task await game_task
async def watch_game(channel, newgame, user = None, league = None): async def watch_game(channel, newgame, user = None, league = None):
blank_emoji = discord.utils.get(client.emojis, id = 790899850295509053) newgame, state_init = prepare_game(newgame)
empty_base = discord.utils.get(client.emojis, id = 790899850395779074)
occupied_base = discord.utils.get(client.emojis, id = 790899850320543745)
out_emoji = discord.utils.get(client.emojis, id = 791578957241778226)
in_emoji = discord.utils.get(client.emojis, id = 791578957244792832)
await asyncio.sleep(1)
weathers = games.all_weathers()
newgame.weather = weathers[random.choice(list(weathers.keys()))]
state_init = {
"away_name" : newgame.teams['away'].name,
"home_name" : newgame.teams['home'].name,
"max_innings" : newgame.max_innings,
"update_pause" : 0,
"top_of_inning" : True,
"victory_lap" : False,
"weather_emoji" : newgame.weather.emoji,
"weather_text" : newgame.weather.name,
"start_delay" : 5,
"end_delay" : 10
}
if newgame.weather.name == "Heavy Snow":
newgame.weather.counter_away = random.randint(0,len(newgame.teams['away'].lineup)-1)
newgame.weather.counter_home = random.randint(0,len(newgame.teams['home'].lineup)-1)
if league is not None: if league is not None:
discrim_string = league discrim_string = league
@ -743,14 +705,78 @@ async def watch_game(channel, newgame, user = None, league = None):
await channel.send(f"{newgame.teams['away'].name} vs. {newgame.teams['home'].name}, starting at {config()['simmadome_url']+ext}") await channel.send(f"{newgame.teams['away'].name} vs. {newgame.teams['home'].name}, starting at {config()['simmadome_url']+ext}")
gamesarray.append((newgame, channel, user, timestamp)) gamesarray.append((newgame, channel, user, timestamp))
main_controller.master_games_dic[timestamp] = (newgame, state_init, discrim_string) main_controller.master_games_dic[timestamp] = (newgame, state_init, discrim_string)
async def play_from_queue(channel, game, user_mention): def prepare_game(newgame, league = None, weather_name = None):
await channel.send(f"{user_mention}, your game's ready.") if weather_name is None:
game_task = asyncio.create_task(watch_game(channel, game)) weathers = games.all_weathers()
await game_task newgame.weather = weathers[random.choice(list(weathers.keys()))]
state_init = {
"away_name" : newgame.teams['away'].name,
"home_name" : newgame.teams['home'].name,
"max_innings" : newgame.max_innings,
"update_pause" : 0,
"top_of_inning" : True,
"victory_lap" : False,
"weather_emoji" : newgame.weather.emoji,
"weather_text" : newgame.weather.name,
"start_delay" : 5,
"end_delay" : 10
}
if league is None:
state_init["is_league"] = False
else:
state_init["is_league"] = True
if newgame.weather.name == "Heavy Snow":
newgame.weather.counter_away = random.randint(0,len(newgame.teams['away'].lineup)-1)
newgame.weather.counter_home = random.randint(0,len(newgame.teams['home'].lineup)-1)
return newgame, state_init
async def start_tournament_round(channel, tourney, seeding = None):
current_games = []
if tourney.bracket is None:
if seeding is None:
tourney.build_bracket(random_sort=True)
games_to_start = tourney.bracket.get_bottom_row()
for pair in games_to_start:
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, state_init = prepare_game(this_game)
state_init["is_league"] = True
discrim_string = tourney.name
print(discrim_string)
timestamp = str(time.time() * 1000.0 + random.randint(0,3000))
current_games.append((this_game, timestamp))
main_controller.master_games_dic[timestamp] = (this_game, state_init, discrim_string)
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}")
tourney_task = asyncio.create_task(tourney_watcher(channel, tourney, current_games))
await tourney_task
async def tourney_watcher(channel, tourney, games_list):
tourney.active = True
while len(games_list) > 0:
for i in range(0, len(games_list)):
game, key = games_list[i]
if game.over and main_controller.master_games_dic[key][1]["end_delay"] <= 9:
final_embed = game_over_embed(game)
await channel.send(f"A {tourney.name} game just ended!")
await channel.send(embed=final_embed)
gamesarray.pop(i)
break
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):
team_msg = await channel.send(embed=build_team_embed(team)) team_msg = await channel.send(embed=build_team_embed(team))
@ -934,6 +960,19 @@ async def game_watcher():
for i in range(0,len(this_array)): for i in range(0,len(this_array)):
game, channel, user, key = this_array[i] game, channel, user, key = this_array[i]
if game.over and main_controller.master_games_dic[key][1]["end_delay"] <= 9: if game.over and main_controller.master_games_dic[key][1]["end_delay"] <= 9:
final_embed = game_over_embed(game)
if user is not None:
await channel.send(f"{user.mention}'s game just ended.")
else:
await channel.send("A game started from this channel just ended.")
await channel.send(embed=final_embed)
gamesarray.pop(i)
break
except:
print("something broke in game_watcher")
await asyncio.sleep(4)
def game_over_embed(game):
title_string = f"{game.teams['away'].name} at {game.teams['home'].name} ended after {game.inning-1} innings" title_string = f"{game.teams['away'].name} at {game.teams['home'].name} ended after {game.inning-1} innings"
if (game.inning - 1) > game.max_innings: #if extra innings if (game.inning - 1) > game.max_innings: #if extra innings
title_string += f" with {game.inning - (game.max_innings+1)} extra innings." title_string += f" with {game.inning - (game.max_innings+1)} extra innings."
@ -949,21 +988,8 @@ async def game_watcher():
else: else:
winstring += f"{winning_team} wins!" winstring += f"{winning_team} wins!"
if user is not None: embed = discord.Embed(color=discord.Color.dark_purple(), title=title_string)
await channel.send(f"{user.mention}'s game just ended.") embed.add_field(name="Final score:", value=winstring)
else: return embed
await channel.send("A game started from this channel just ended.")
final_embed = discord.Embed(color=discord.Color.dark_purple(), title=title_string)
final_embed.add_field(name="Final score:", value=winstring)
await channel.send(embed=final_embed)
gamesarray.pop(i)
break
except:
print("something broke in game_watcher")
await asyncio.sleep(6)
client.run(config()["token"]) client.run(config()["token"])