diff --git a/database.py b/database.py
index 79b5e49..a53da43 100644
--- a/database.py
+++ b/database.py
@@ -207,6 +207,21 @@ def save_team(name, team_json_string, user_id):
except:
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):
conn = create_connection()
if conn is not None:
diff --git a/games.py b/games.py
index 805e4c4..a077faf 100644
--- a/games.py
+++ b/games.py
@@ -102,10 +102,26 @@ class team(object):
self.name = None
self.lineup = []
self.lineup_position = 0
+ self.rotation = []
self.pitcher = None
self.score = 0
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):
if len(self.lineup) < 20:
self.lineup.append(new_player)
@@ -113,27 +129,48 @@ class team(object):
else:
return (False, "20 players in the lineup, maximum. We're being really generous here.")
- def set_pitcher(self, new_player):
- self.pitcher = new_player
- return (True,)
+ def add_pitcher(self, new_player):
+ if len(self.rotation) < 8:
+ 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):
- 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):
self.lineup_position = 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 stat in this_player.game_stats.keys():
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
def finalize(self):
if self.is_ready():
+ if self.pitcher is None:
+ self.set_pitcher()
while len(self.lineup) <= 4:
- self.lineup.append(random.choice(self.lineup))
- return True
- else:
+ self.lineup.append(random.choice(self.lineup))
+ return self
+ else:
return False
@@ -619,20 +656,40 @@ def get_team(name):
try:
team_json = jsonpickle.decode(db.get_team(name)[0], keys=True, classes=team)
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 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:
return None
def get_team_and_owner(name):
- #try:
- 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)
- if team_json is not None:
+ try:
+ 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)
+ 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 None
- #except:
- #return None
+ except:
+ return None
def save_team(this_team, user_id):
try:
@@ -643,6 +700,15 @@ def save_team(this_team, user_id):
except:
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():
teams = []
for team_pickle in db.get_all_teams():
@@ -653,9 +719,23 @@ def get_all_teams():
def search_team(search_term):
teams = []
for team_pickle in db.search_teams(search_term):
- this_team = jsonpickle.decode(team_pickle[0], keys=True, classes=team)
- teams.append(this_team)
- return teams
+ team_json = jsonpickle.decode(team_pickle[0], keys=True, classes=team)
+ try:
+ 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):
if base == 1:
diff --git a/leagues.py b/leagues.py
new file mode 100644
index 0000000..bf44a2e
--- /dev/null
+++ b/leagues.py
@@ -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}
+
diff --git a/main_controller.py b/main_controller.py
index c439608..91df7c2 100644
--- a/main_controller.py
+++ b/main_controller.py
@@ -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_socketio import SocketIO, emit
diff --git a/the-prestige.pyproj b/the-prestige.pyproj
index c9f6968..351afa6 100644
--- a/the-prestige.pyproj
+++ b/the-prestige.pyproj
@@ -29,6 +29,9 @@
Code
+
+ Code
+
Code
diff --git a/the_prestige.py b/the_prestige.py
index 89584a2..239595b 100644
--- a/the_prestige.py
+++ b/the_prestige.py
@@ -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 onomancer as ono
from flask import Flask
@@ -169,7 +169,7 @@ class StartGameCommand(Command):
return
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
await msg.delete()
@@ -205,12 +205,19 @@ class SetupGameCommand(Command):
class SaveTeamCommand(Command):
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).
- 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 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 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."""
async def execute(self, msg, command):
@@ -287,6 +294,31 @@ class CreditCommand(Command):
async def execute(self, msg, command):
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):
name = "help"
template = "m;help [command]"
@@ -353,6 +385,7 @@ commands = [
#SetupGameCommand(),
SaveTeamCommand(),
ImportCommand(),
+ SwapPlayerCommand(),
DeleteTeamCommand(),
ShowTeamCommand(),
ShowAllTeamsCommand(),
@@ -660,7 +693,10 @@ def build_team_embed(team):
for player in team.lineup:
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.set_footer(text=team.slogan)
return embed
@@ -710,14 +746,22 @@ def team_from_message(command):
roster = command.split("\n",1)[1].split("\n")
newteam.name = roster[0] #first line is team name
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 len(roster[rosternum]) > 70:
raise CommandError(f"{roster[rosternum]} is too long, chief. 70 or less.")
newteam.add_lineup(games.player(ono.get_stats(roster[rosternum].rstrip())))
- if len(roster[len(roster)-1]) > 70:
- raise CommandError(f"{roster[len(roster)-1]} is too long, chief. 70 or less.")
- newteam.set_pitcher(games.player(ono.get_stats(roster[len(roster)-1].rstrip()))) #last line is pitcher name
+ else:
+ pitchernum = rosternum + 1
+ 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:
raise CommandError("Team names have to be less than 30 characters! Try again.")