matteo-the-prestige/games.py

173 lines
5.5 KiB
Python
Raw Normal View History

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