added rotations to teams, and automatic conversion. updated saveteam to new format, supporting rotation. games choose random pitcher

This commit is contained in:
Sakimori 2021-01-02 01:10:52 -05:00
parent a0b047668d
commit 07a7c5c3c3
6 changed files with 188 additions and 27 deletions

View File

@ -207,6 +207,21 @@ def save_team(name, team_json_string, user_id):
except: except:
return False return False
def update_team(name, team_json_string):
conn = create_connection()
try:
if conn is not None:
c = conn.cursor()
store_string = "UPDATE teams SET team_json_string = ? WHERE name=?"
c.execute(store_string, (team_json_string, (re.sub('[^A-Za-z0-9 ]+', '', name)))) #this regex removes all non-standard characters
conn.commit()
conn.close()
return True
conn.close()
return False
except:
return False
def get_team(name, owner=False): def get_team(name, owner=False):
conn = create_connection() conn = create_connection()
if conn is not None: if conn is not None:

110
games.py
View File

@ -102,10 +102,26 @@ class team(object):
self.name = None self.name = None
self.lineup = [] self.lineup = []
self.lineup_position = 0 self.lineup_position = 0
self.rotation = []
self.pitcher = None self.pitcher = None
self.score = 0 self.score = 0
self.slogan = None self.slogan = None
def swap_player(self, name):
if len(self.lineup) > 1:
for index in range(0,len(self.lineup)):
if self.lineup[index].name == name:
if self.add_pitcher(self.lineup[index]):
self.lineup.pop(index)
return True
if len(self.rotation) > 1:
for index in range(0,len(self.rotation)):
if self.rotation[index].name == name:
if self.add_lineup(self.rotation[index])[0]:
self.rotation.pop(index)
return True
return False
def add_lineup(self, new_player): def add_lineup(self, new_player):
if len(self.lineup) < 20: if len(self.lineup) < 20:
self.lineup.append(new_player) self.lineup.append(new_player)
@ -113,26 +129,47 @@ class team(object):
else: else:
return (False, "20 players in the lineup, maximum. We're being really generous here.") return (False, "20 players in the lineup, maximum. We're being really generous here.")
def set_pitcher(self, new_player): def add_pitcher(self, new_player):
self.pitcher = new_player if len(self.rotation) < 8:
return (True,) self.rotation.append(new_player)
return True
else:
return False
def set_pitcher(self, rotation_slot = None, use_lineup = False):
temp_rotation = self.rotation.copy()
if use_lineup:
for batter in self.rotation:
temp_rotation.append(batter)
if rotation_slot is None:
self.pitcher = random.choice(temp_rotation)
else:
self.pitcher = temp_rotation[rotation_slot % len(temp_rotation)]
def is_ready(self): def is_ready(self):
return (len(self.lineup) >= 1 and self.pitcher is not None) return (len(self.lineup) >= 1 and len(self.rotation) > 0)
def prepare_for_save(self): def prepare_for_save(self):
self.lineup_position = 0 self.lineup_position = 0
self.score = 0 self.score = 0
if self.pitcher is not None and self.pitcher not in self.rotation:
self.rotation.append(self.pitcher)
self.pitcher = None
for this_player in self.lineup: for this_player in self.lineup:
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
for this_player in self.rotation:
for stat in this_player.game_stats.keys():
this_player.game_stats[stat] = 0
return True return True
def finalize(self): def finalize(self):
if self.is_ready(): if self.is_ready():
if self.pitcher is None:
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 True return self
else: else:
return False return False
@ -619,20 +656,40 @@ def get_team(name):
try: try:
team_json = jsonpickle.decode(db.get_team(name)[0], keys=True, classes=team) team_json = jsonpickle.decode(db.get_team(name)[0], keys=True, classes=team)
if team_json is not None: if team_json is not None:
if team_json.pitcher is not None: #detects old-format teams, adds pitcher
team_json.rotation.append(team_json.pitcher)
team_json.pitcher = None
update_team(team_json)
return team_json return team_json
return None return None
except AttributeError:
team_json.rotation = []
team_json.rotation.append(team_json.pitcher)
team_json.pitcher = None
update_team(team_json)
return team_json
except: except:
return None return None
def get_team_and_owner(name): def get_team_and_owner(name):
#try: try:
counter, name, team_json_string, timestamp, owner_id = db.get_team(name, owner=True) counter, name, team_json_string, timestamp, owner_id = db.get_team(name, owner=True)
team_json = jsonpickle.decode(team_json_string, keys=True, classes=team) team_json = jsonpickle.decode(team_json_string, keys=True, classes=team)
if team_json is not None: if team_json is not None:
if team_json.pitcher is not None: #detects old-format teams, adds pitcher
team_json.rotation.append(team_json.pitcher)
team_json.pitcher = None
update_team(team_json)
return (team_json, owner_id)
return None
except AttributeError:
team_json.rotation = []
team_json.rotation.append(team_json.pitcher)
team_json.pitcher = None
update_team(team_json)
return (team_json, owner_id) return (team_json, owner_id)
return None except:
#except: return None
#return None
def save_team(this_team, user_id): def save_team(this_team, user_id):
try: try:
@ -643,6 +700,15 @@ def save_team(this_team, user_id):
except: except:
return None return None
def update_team(this_team):
try:
this_team.prepare_for_save()
team_json_string = jsonpickle.encode(this_team, keys=True)
db.update_team(this_team.name, team_json_string)
return True
except:
return None
def get_all_teams(): def get_all_teams():
teams = [] teams = []
for team_pickle in db.get_all_teams(): for team_pickle in db.get_all_teams():
@ -653,9 +719,23 @@ def get_all_teams():
def search_team(search_term): def search_team(search_term):
teams = [] teams = []
for team_pickle in db.search_teams(search_term): for team_pickle in db.search_teams(search_term):
this_team = jsonpickle.decode(team_pickle[0], keys=True, classes=team) team_json = jsonpickle.decode(team_pickle[0], keys=True, classes=team)
teams.append(this_team) try:
return teams if team_json.pitcher is not None:
if len(team_json.rotation) == 0: #detects old-format teams, adds pitcher
team_json.rotation.append(team_json.pitcher)
team_json.pitcher = None
update_team(team_json)
except AttributeError:
team_json.rotation = []
team_json.rotation.append(team_json.pitcher)
team_json.pitcher = None
update_team(team_json)
except:
return None
teams.append(team_json)
return teams
def base_string(base): def base_string(base):
if base == 1: if base == 1:

19
leagues.py Normal file
View File

@ -0,0 +1,19 @@
import time, asyncio, jsonpickle
import database as db
class league(object):
def __init__(self, name, subleagues_dic):
self.subleagues = {} #key: name, value: [divisions]
self.max_days
self.day = 1
self.name = name
self.subleagues = subleagues_dic
class division(object):
def __init__(self):
self.teams = {} #key: team name, value: {wins; losses; run diff}

View File

@ -1,4 +1,4 @@
import asyncio, time, datetime, games, json, threading, jinja2 import asyncio, time, datetime, games, json, threading, jinja2, leagues
from flask import Flask, url_for, Response, render_template, request, jsonify from flask import Flask, url_for, Response, render_template, request, jsonify
from flask_socketio import SocketIO, emit from flask_socketio import SocketIO, emit

View File

@ -29,6 +29,9 @@
<Compile Include="debug storage.py"> <Compile Include="debug storage.py">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="leagues.py">
<SubType>Code</SubType>
</Compile>
<Compile Include="main_controller.py"> <Compile Include="main_controller.py">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>

View File

@ -1,4 +1,4 @@
import discord, json, math, os, roman, games, asyncio, random, main_controller, threading, time import discord, json, math, os, roman, games, asyncio, random, main_controller, threading, time, leagues
import database as db import database as db
import onomancer as ono import onomancer as ono
from flask import Flask from flask import Flask
@ -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, team2, length=innings) game = games.game(msg.author.name, team1.finalize(), team2.finalize(), length=innings)
channel = msg.channel channel = msg.channel
await msg.delete() await msg.delete()
@ -205,12 +205,19 @@ class SetupGameCommand(Command):
class SaveTeamCommand(Command): class SaveTeamCommand(Command):
name = "saveteam" name = "saveteam"
template = "m;saveteam [name] [slogan] [players]" template = """m;saveteam
[name]
[slogan]
[lineup]
[rotation]"""
description = """Saves a team to the database allowing it to be used for games. Send this command at the top of a list, with entries separated by new lines (shift+enter in discord, or copy+paste from notepad). description = """Saves a team to the database allowing it to be used for games. Send this command at the top of a list, with entries separated by new lines (shift+enter in discord, or copy+paste from notepad).
- the first line of the list is your team's name (cannot contain emoji). - the first line of the list is your team's name (cannot contain emoji).
- the second line is your team's icon and slogan, this should begin with an emoji followed by a space, followed by a short slogan. - the second line is your team's icon and slogan, this should begin with an emoji followed by a space, followed by a short slogan.
- the third line must be blank.
- the next lines are your batters' names in the order you want them to appear in your lineup, lineups can contain any number of batters between 1 and 12. - the next lines are your batters' names in the order you want them to appear in your lineup, lineups can contain any number of batters between 1 and 12.
- the final line is your pitcher's name. - there must be another blank line between your batters and your pitchers.
- the final lines are your pitchers' names.
if you did it correctly, you'll get a team embed with a prompt to confirm. hit the 👍 and it'll be saved.""" if you did it correctly, you'll get a team embed with a prompt to confirm. hit the 👍 and it'll be saved."""
async def execute(self, msg, command): async def execute(self, msg, command):
@ -287,6 +294,31 @@ class CreditCommand(Command):
async def execute(self, msg, command): async def execute(self, msg, command):
await msg.channel.send("Our avatar was graciously provided to us, with permission, by @HetreaSky on Twitter.") await msg.channel.send("Our avatar was graciously provided to us, with permission, by @HetreaSky on Twitter.")
class SwapPlayerCommand(Command):
name = "swap"
template = """m;swap
[team name]
[player name]"""
description = "Swaps a player from lineup to rotation, or from rotation to lineup. Requires team ownership."
async def execute(self, msg, command):
team_name = command.split("\n")[1].strip()
player_name = command.split("\n")[2].strip()
team, owner_id = games.get_team_and_owner(team_name)
if team is None:
await msg.channel.send("Can't find that team, boss. Typo?")
return
elif owner_id != msg.author.id or msg.author.id not in config()["owners"]:
await msg.channel.send("You're not authorized to mess with this team. Sorry, boss.")
return
elif not team.swap_player(player_name):
await msg.channel.send("Either we can't find that player, or they're your last member of that side of the roster. Can't field an empty lineup, chief.")
return
else:
await msg.channel.send(embed=build_team_embed(team))
games.update_team(team)
await msg.channel.send("Paperwork signed, stamped, and copied.")
class HelpCommand(Command): class HelpCommand(Command):
name = "help" name = "help"
template = "m;help [command]" template = "m;help [command]"
@ -353,6 +385,7 @@ commands = [
#SetupGameCommand(), #SetupGameCommand(),
SaveTeamCommand(), SaveTeamCommand(),
ImportCommand(), ImportCommand(),
SwapPlayerCommand(),
DeleteTeamCommand(), DeleteTeamCommand(),
ShowTeamCommand(), ShowTeamCommand(),
ShowAllTeamsCommand(), ShowAllTeamsCommand(),
@ -660,7 +693,10 @@ def build_team_embed(team):
for player in team.lineup: for player in team.lineup:
lineup_string += f"{player.name} {player.star_string('batting_stars')}\n" lineup_string += f"{player.name} {player.star_string('batting_stars')}\n"
embed.add_field(name="Pitcher:", value=f"{team.pitcher.name} {team.pitcher.star_string('pitching_stars')}", inline = False) rotation_string = ""
for player in team.rotation:
rotation_string += f"{player.name} {player.star_string('pitching_stars')}\n"
embed.add_field(name="Rotation:", value=rotation_string, inline = False)
embed.add_field(name="Lineup:", value=lineup_string, inline = False) embed.add_field(name="Lineup:", value=lineup_string, inline = False)
embed.set_footer(text=team.slogan) embed.set_footer(text=team.slogan)
return embed return embed
@ -710,14 +746,22 @@ def team_from_message(command):
roster = command.split("\n",1)[1].split("\n") roster = command.split("\n",1)[1].split("\n")
newteam.name = roster[0] #first line is team name newteam.name = roster[0] #first line is team name
newteam.slogan = roster[1] #second line is slogan newteam.slogan = roster[1] #second line is slogan
for rosternum in range(2,len(roster)-1): if not roster[2].strip() == "":
raise CommandError("The third line should be blank. It wasn't, so just in case, we've not done anything on our end.")
pitchernum = len(roster)-2
for rosternum in range(3,len(roster)-1):
if roster[rosternum] != "": if roster[rosternum] != "":
if len(roster[rosternum]) > 70: if len(roster[rosternum]) > 70:
raise CommandError(f"{roster[rosternum]} is too long, chief. 70 or less.") raise CommandError(f"{roster[rosternum]} is too long, chief. 70 or less.")
newteam.add_lineup(games.player(ono.get_stats(roster[rosternum].rstrip()))) newteam.add_lineup(games.player(ono.get_stats(roster[rosternum].rstrip())))
if len(roster[len(roster)-1]) > 70: else:
raise CommandError(f"{roster[len(roster)-1]} is too long, chief. 70 or less.") pitchernum = rosternum + 1
newteam.set_pitcher(games.player(ono.get_stats(roster[len(roster)-1].rstrip()))) #last line is pitcher name break
for rosternum in range(pitchernum, len(roster)):
if len(roster[rosternum]) > 70:
raise CommandError(f"{roster[len(roster)-1]} is too long, chief. 70 or less.")
newteam.add_pitcher(games.player(ono.get_stats(roster[rosternum].rstrip())))
if len(newteam.name) > 30: if len(newteam.name) > 30:
raise CommandError("Team names have to be less than 30 characters! Try again.") raise CommandError("Team names have to be less than 30 characters! Try again.")