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
 | 
					# 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()
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -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[0].value} {atbat[1].name}.")
 | 
				
			||||||
 | 
					        except IndexError:
 | 
				
			||||||
 | 
					            await msg.channel.send(f"{batter.name} {atbat[0].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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user