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
|
||||
config.json
|
||||
games_config.json
|
||||
ids
|
||||
|
||||
# database
|
||||
|
|
21
database.py
21
database.py
|
@ -30,10 +30,31 @@ def initialcheck():
|
|||
player_name 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:
|
||||
c = conn.cursor()
|
||||
c.execute(soulscream_table_check_string)
|
||||
c.execute(player_table_check_string)
|
||||
c.execute(player_stats_table_check_string)
|
||||
|
||||
conn.commit()
|
||||
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
|
||||
|
||||
|
|
@ -11,7 +11,6 @@ def get_stats(name):
|
|||
#yell at onomancer if not in cache or too old
|
||||
response = requests.get(onomancer_url + name_stats_hook + urllib.parse.quote_plus(name))
|
||||
if response.status_code == 200:
|
||||
|
||||
return response.json()
|
||||
|
||||
def get_scream(username):
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
<Compile Include="onomancer.py">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="games.py">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="roman.py" />
|
||||
<Compile Include="the_prestige.py" />
|
||||
</ItemGroup>
|
||||
|
@ -44,6 +47,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="config.json" />
|
||||
<Content Include="games_config.json" />
|
||||
<Content Include="ids" />
|
||||
<Content Include="matteo.db" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import discord, json, os, roman
|
||||
import discord, json, os, roman, games
|
||||
import database as db
|
||||
import onomancer as ono
|
||||
|
||||
|
@ -82,6 +82,24 @@ async def on_message(msg):
|
|||
except:
|
||||
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":
|
||||
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:
|
||||
starnum = int(player_json[key])
|
||||
addhalf = False
|
||||
embedstring = "⭐" * starnum
|
||||
embedstring += "⭐" * starnum
|
||||
if addhalf:
|
||||
embedstring += "✨"
|
||||
embed.add_field(name=starkeys[key], value=embedstring, inline=False)
|
||||
return embed
|
||||
|
||||
|
||||
|
||||
client.run(config()["token"])
|
Loading…
Reference in New Issue
Block a user