set up at-bat simulation in games.py, and a test function in the_prestige.
This commit is contained in:
parent
0141723e1b
commit
8235532819
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -341,6 +341,7 @@ healthchecksdb
|
||||||
|
|
||||||
# Personal config file, contains bot token
|
# Personal config file, contains bot token
|
||||||
config.json
|
config.json
|
||||||
|
games_config.json
|
||||||
ids
|
ids
|
||||||
|
|
||||||
# database
|
# database
|
||||||
|
|
21
database.py
21
database.py
|
@ -30,10 +30,31 @@ def initialcheck():
|
||||||
player_name text NOT NULL,
|
player_name text NOT NULL,
|
||||||
player_json_string text NOT NULL
|
player_json_string text NOT NULL
|
||||||
);"""
|
);"""
|
||||||
|
|
||||||
|
player_stats_table_check_string = """ CREATE TABLE IF NOT EXISTS stats (
|
||||||
|
counter integer PRIMARY KEY,
|
||||||
|
id text,
|
||||||
|
name text,
|
||||||
|
json_string text,
|
||||||
|
outs_pitched integer DEFAULT 0,
|
||||||
|
walks_allowed integer DEFAULT 0,
|
||||||
|
hits_allowed integer DEFAULT 0,
|
||||||
|
strikeouts_given integer DEFAULT 0,
|
||||||
|
runs_allowed integer DEFAULT 0,
|
||||||
|
plate_appearances integer DEFAULT 0,
|
||||||
|
walks_taken integer DEFAULT 0,
|
||||||
|
hits integer DEFAULT 0,
|
||||||
|
home_runs integer DEFAULT 0,
|
||||||
|
total_bases integer DEFAULT 0,
|
||||||
|
rbis integer DEFAULT 0,
|
||||||
|
strikeouts_taken integer DEFAULT 0
|
||||||
|
);"""
|
||||||
|
|
||||||
if conn is not None:
|
if conn is not None:
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
c.execute(soulscream_table_check_string)
|
c.execute(soulscream_table_check_string)
|
||||||
c.execute(player_table_check_string)
|
c.execute(player_table_check_string)
|
||||||
|
c.execute(player_stats_table_check_string)
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
172
games.py
Normal file
172
games.py
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
import json, random, os, math
|
||||||
|
from enum import Enum
|
||||||
|
import database as db
|
||||||
|
|
||||||
|
def config():
|
||||||
|
if not os.path.exists("games_config.json"):
|
||||||
|
#generate default config
|
||||||
|
config_dic = {
|
||||||
|
"default_length" : 3,
|
||||||
|
"stlat_weights" : {
|
||||||
|
"batting_stars" : 1, #batting
|
||||||
|
"pitching_stars" : 1, #pitching
|
||||||
|
"baserunning_stars" : 1, #baserunning
|
||||||
|
"defense_stars" : 1 #defense
|
||||||
|
}
|
||||||
|
}
|
||||||
|
with open("games_config.json", "w") as config_file:
|
||||||
|
json.dump(config_dic, config_file, indent=4)
|
||||||
|
return config_dic
|
||||||
|
else:
|
||||||
|
with open("games_config.json") as config_file:
|
||||||
|
return json.load(config_file)
|
||||||
|
|
||||||
|
class appearance_outcomes(Enum):
|
||||||
|
strikeoutlooking = "strikes out looking."
|
||||||
|
strikeoutswinging = "strikes out swinging."
|
||||||
|
groundout = "grounds out to"
|
||||||
|
flyout = "flies out to"
|
||||||
|
fielderschoice = "reaches on fielder's choice."
|
||||||
|
doubleplay = "grounds into a double play!"
|
||||||
|
walks = "draws a walk."
|
||||||
|
single = "hits a single!"
|
||||||
|
double = "hits a double!"
|
||||||
|
triple = "hits a triple!"
|
||||||
|
homerun = "hits a home run!"
|
||||||
|
grandslam = "hits a grand slam!"
|
||||||
|
|
||||||
|
|
||||||
|
class player(object):
|
||||||
|
def __init__(self, json_string):
|
||||||
|
self.stlats = json.loads(json_string)
|
||||||
|
self.id = self.stlats["id"]
|
||||||
|
self.name = self.stlats["name"]
|
||||||
|
self.game_stats = {}
|
||||||
|
|
||||||
|
|
||||||
|
class team(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.name = None
|
||||||
|
self.lineup = []
|
||||||
|
self.lineup_position = 0
|
||||||
|
self.pitcher = None
|
||||||
|
|
||||||
|
def add_lineup(self, new_player):
|
||||||
|
if len(self.lineup) <= 12:
|
||||||
|
self.lineup.append(new_player)
|
||||||
|
return (True,)
|
||||||
|
else:
|
||||||
|
return (False, "12 players in the lineup, maximum. We're being generous here.")
|
||||||
|
|
||||||
|
def set_pitcher(self, new_player):
|
||||||
|
self.pitcher = new_player
|
||||||
|
return (True,)
|
||||||
|
|
||||||
|
def is_ready(self):
|
||||||
|
return (len(self.lineup) >= 1 and self.pitcher is not None)
|
||||||
|
|
||||||
|
def finalize(self):
|
||||||
|
if self.is_ready():
|
||||||
|
while len(self.lineup) <= 4:
|
||||||
|
self.lineup.append(random.choice(self.lineup))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class game(object):
|
||||||
|
|
||||||
|
def __init__(self, team1, team2, length=None):
|
||||||
|
self.teams = {"away" : team1, "home" : team2}
|
||||||
|
self.inning = 1
|
||||||
|
self.top_of_inning = True
|
||||||
|
if length is not None:
|
||||||
|
self.max_innings = length
|
||||||
|
else:
|
||||||
|
self.max_innings = config()["default_length"]
|
||||||
|
self.bases = {1 : None, 2 : None, 3 : None}
|
||||||
|
|
||||||
|
def get_batter(self):
|
||||||
|
if self.top_of_inning:
|
||||||
|
bat_team = self.teams["away"]
|
||||||
|
else:
|
||||||
|
bat_team = self.teams["home"]
|
||||||
|
return bat_team.lineup[bat_team.lineup_position % len(bat_team.lineup)]
|
||||||
|
|
||||||
|
def get_pitcher(self):
|
||||||
|
if self.top_of_inning:
|
||||||
|
return self.teams["home"].pitcher
|
||||||
|
else:
|
||||||
|
return self.teams["away"].pitcher
|
||||||
|
|
||||||
|
def at_bat(self):
|
||||||
|
pitcher = self.get_pitcher()
|
||||||
|
batter = self.get_batter()
|
||||||
|
if self.top_of_inning:
|
||||||
|
defender = random.choice(self.teams["home"].lineup)
|
||||||
|
else:
|
||||||
|
defender = random.choice(self.teams["away"].lineup)
|
||||||
|
|
||||||
|
bat_stat = random_star_gen("batting_stars", batter)
|
||||||
|
pitch_stat = random_star_gen("pitching_stars", pitcher)
|
||||||
|
def_stat = random_star_gen("defense_stars", defender)
|
||||||
|
pb_system_stat = (random.gauss(1.5*math.erf((bat_stat - pitch_stat)/2)-1.5,3))
|
||||||
|
hitnum = random.gauss(2*math.erf(bat_stat)-0.5,3)
|
||||||
|
|
||||||
|
|
||||||
|
outcome = {}
|
||||||
|
if pb_system_stat <= 0:
|
||||||
|
outcome["ishit"] = False
|
||||||
|
fc_flag = False
|
||||||
|
if hitnum < 1:
|
||||||
|
outcome["text"] = random.choice([appearance_outcomes.strikeoutlooking, appearance_outcomes.strikeoutswinging])
|
||||||
|
elif hitnum < 2:
|
||||||
|
outcome["text"] = appearance_outcomes.groundout
|
||||||
|
outcome["defender"] = defender
|
||||||
|
else:
|
||||||
|
outcome["text"] = appearance_outcomes.flyout
|
||||||
|
outcome["defender"] = defender
|
||||||
|
|
||||||
|
if self.bases[1] is not None and hitnum < 1:
|
||||||
|
outcome["text"] = appearance_outcomes.doubleplay
|
||||||
|
for base in self.bases.values():
|
||||||
|
if base is not None:
|
||||||
|
fc_flag = True
|
||||||
|
if fc_flag and 1 <= hitnum and hitnum < 2:
|
||||||
|
outcome["text"] = appearance_outcomes.fielderschoice
|
||||||
|
else:
|
||||||
|
if hitnum < 1:
|
||||||
|
outcome["text"] = appearance_outcomes.single
|
||||||
|
elif hitnum < 2:
|
||||||
|
outcome["text"] = appearance_outcomes.double
|
||||||
|
elif hitnum < 3:
|
||||||
|
outcome["text"] = appearance_outcomes.triple
|
||||||
|
else:
|
||||||
|
if self.bases[1] is not None and self.bases[2] is not None and self.bases[3] is not None:
|
||||||
|
outcome["text"] = appearance_outcomes.grandslam
|
||||||
|
else:
|
||||||
|
outcome["text"] = appearance_outcomes.homerun
|
||||||
|
|
||||||
|
if self.top_of_inning:
|
||||||
|
self.teams["away"].lineup_position += 1
|
||||||
|
else:
|
||||||
|
self.teams["home"].lineup_position += 1
|
||||||
|
return outcome
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def random_star_gen(key, player):
|
||||||
|
return random.gauss(config()["stlat_weights"][key] * player.stlats[key],1)
|
||||||
|
# innings_pitched
|
||||||
|
# walks_allowed
|
||||||
|
# strikeouts_given
|
||||||
|
# runs_allowed
|
||||||
|
# plate_appearances
|
||||||
|
# walks
|
||||||
|
# hits
|
||||||
|
# total_bases
|
||||||
|
# rbis
|
||||||
|
# walks_taken
|
||||||
|
# strikeouts_taken
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,7 @@ name_stats_hook = "generateStats2?name="
|
||||||
def get_stats(name):
|
def get_stats(name):
|
||||||
#yell at onomancer if not in cache or too old
|
#yell at onomancer if not in cache or too old
|
||||||
response = requests.get(onomancer_url + name_stats_hook + urllib.parse.quote_plus(name))
|
response = requests.get(onomancer_url + name_stats_hook + urllib.parse.quote_plus(name))
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
|
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
def get_scream(username):
|
def get_scream(username):
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
<Compile Include="onomancer.py">
|
<Compile Include="onomancer.py">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="games.py">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="roman.py" />
|
<Compile Include="roman.py" />
|
||||||
<Compile Include="the_prestige.py" />
|
<Compile Include="the_prestige.py" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -44,6 +47,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="config.json" />
|
<Content Include="config.json" />
|
||||||
|
<Content Include="games_config.json" />
|
||||||
<Content Include="ids" />
|
<Content Include="ids" />
|
||||||
<Content Include="matteo.db" />
|
<Content Include="matteo.db" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import discord, json, os, roman
|
import discord, json, os, roman, games
|
||||||
import database as db
|
import database as db
|
||||||
import onomancer as ono
|
import onomancer as ono
|
||||||
|
|
||||||
|
@ -82,6 +82,24 @@ async def on_message(msg):
|
||||||
except:
|
except:
|
||||||
await msg.channel.send("We can't find your idol. Looked everywhere, too.")
|
await msg.channel.send("We can't find your idol. Looked everywhere, too.")
|
||||||
|
|
||||||
|
elif command == "testab":
|
||||||
|
team1 = games.team()
|
||||||
|
team2 = games.team()
|
||||||
|
team1.add_lineup(games.player(json.dumps(ono.get_stats("xvi"))))
|
||||||
|
team1.set_pitcher(games.player(json.dumps(ono.get_stats("16"))))
|
||||||
|
team1.finalize()
|
||||||
|
team2.add_lineup(games.player(json.dumps(ono.get_stats("artemis"))))
|
||||||
|
team2.set_pitcher(games.player(json.dumps(ono.get_stats("alphy"))))
|
||||||
|
team2.finalize()
|
||||||
|
|
||||||
|
game = games.game(team1, team2)
|
||||||
|
batter = game.get_batter()
|
||||||
|
atbat = game.at_bat()
|
||||||
|
try:
|
||||||
|
await msg.channel.send(f"{batter.name} {atbat['text'].value} {atbat['defender'].name}.")
|
||||||
|
except KeyError:
|
||||||
|
await msg.channel.send(f"{batter.name} {atbat['text'].value}")
|
||||||
|
|
||||||
elif command == "credit":
|
elif command == "credit":
|
||||||
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.")
|
||||||
|
|
||||||
|
@ -110,11 +128,12 @@ def build_star_embed(player_json):
|
||||||
else:
|
else:
|
||||||
starnum = int(player_json[key])
|
starnum = int(player_json[key])
|
||||||
addhalf = False
|
addhalf = False
|
||||||
embedstring = "⭐" * starnum
|
embedstring += "⭐" * starnum
|
||||||
if addhalf:
|
if addhalf:
|
||||||
embedstring += "✨"
|
embedstring += "✨"
|
||||||
embed.add_field(name=starkeys[key], value=embedstring, inline=False)
|
embed.add_field(name=starkeys[key], value=embedstring, inline=False)
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
client.run(config()["token"])
|
client.run(config()["token"])
|
Loading…
Reference in New Issue
Block a user