set up at-bat simulation in games.py, and a test function in the_prestige.
This commit is contained in:
		
							parent
							
								
									0141723e1b
								
							
						
					
					
						commit
						cdf9d96cc6
					
				
							
								
								
									
										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()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										167
									
								
								games.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								games.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,167 @@
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
        if pb_system_stat <= 0:
 | 
			
		||||
            fc_flag = False
 | 
			
		||||
            if hitnum < 1:
 | 
			
		||||
                outcome = random.choice([(appearance_outcomes.strikeoutlooking,), (appearance_outcomes.strikeoutswinging,)])
 | 
			
		||||
            elif hitnum < 2:
 | 
			
		||||
                outcome = (appearance_outcomes.groundout, defender)
 | 
			
		||||
            else:
 | 
			
		||||
                outcome = (appearance_outcomes.flyout, defender)
 | 
			
		||||
 | 
			
		||||
            if self.bases[1] is not None and hitnum < 1:
 | 
			
		||||
                outcome = (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 = (appearance_outcomes.fielderschoice,)
 | 
			
		||||
        else:
 | 
			
		||||
            if hitnum < 1:
 | 
			
		||||
                outcome = (appearance_outcomes.single,)
 | 
			
		||||
            elif hitnum < 2:
 | 
			
		||||
                outcome = (appearance_outcomes.double,)
 | 
			
		||||
            elif hitnum < 3:
 | 
			
		||||
                outcome = (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 = (appearance_outcomes.grandslam,)
 | 
			
		||||
                else:
 | 
			
		||||
                    outcome = (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[0].value} {atbat[1].name}.")
 | 
			
		||||
        except IndexError:
 | 
			
		||||
            await msg.channel.send(f"{batter.name} {atbat[0].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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user