m;starttournament now starts a debug tournament
This commit is contained in:
parent
22150033ca
commit
12255e3eef
3
games.py
3
games.py
|
@ -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
|
||||||
|
|
53
leagues.py
53
leagues.py
|
@ -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])
|
|
@ -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>
|
||||||
|
|
204
the_prestige.py
204
the_prestige.py
|
@ -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("Pigeon’s 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"])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user