Move weathers to new file

This commit is contained in:
hillexed 2021-02-21 13:02:47 -05:00
parent e478589b8e
commit a2c5d3cb0d
4 changed files with 86 additions and 82 deletions

View file

@ -222,7 +222,7 @@ class game(object):
else: else:
self.max_innings = config()["default_length"] self.max_innings = config()["default_length"]
self.bases = {1 : None, 2 : None, 3 : None} self.bases = {1 : None, 2 : None, 3 : None}
self.weather = weather.Weather() self.weather = weather.Weather(self)
self.current_batter = None self.current_batter = None
def choose_next_batter(self): def choose_next_batter(self):
@ -261,38 +261,34 @@ class game(object):
outcome["batter"] = batter outcome["batter"] = batter
outcome["defender"] = "" outcome["defender"] = ""
bat_stat = random_star_gen("batting_stars", batter) player_rolls = {}
pitch_stat = random_star_gen("pitching_stars", pitcher) player_rolls["bat_stat"] = random_star_gen("batting_stars", batter)
player_rolls["pitch_stat"] = random_star_gen("pitching_stars", pitcher)
bat_stat, pitch_stat = self.weather.modify_stats_preroll(bat_stat, pitch_stat) self.weather.modify_atbat_stats(player_rolls)
pb_system_stat = (random.gauss(1*math.erf((bat_stat - pitch_stat)*1.5)-1.8,2.2)) roll = {}
hitnum = random.gauss(2*math.erf(bat_stat/4)-1,3) roll["pb_system_stat"] = (random.gauss(1*math.erf((player_rolls["bat_stat"] - player_rolls["pitch_stat"])*1.5)-1.8,2.2))
roll["hitnum"] = random.gauss(2*math.erf(player_rolls["bat_stat"]/4)-1,3)
if self.weather.name == "Twilight": self.weather.modify_atbat_roll(outcome, roll, defender)
error_line = - (math.log(defender.stlats["defense_stars"] + 1)/50) + 1
error_roll = random.random()
if error_roll > error_line:
outcome["error"] = True
outcome["defender"] = defender
pb_system_stat = 0.1
if pb_system_stat <= 0: if roll["pb_system_stat"] <= 0:
outcome["ishit"] = False outcome["ishit"] = False
fc_flag = False fc_flag = False
if hitnum < -1.5: if roll["hitnum"] < -1.5:
outcome["text"] = random.choice([appearance_outcomes.strikeoutlooking, appearance_outcomes.strikeoutswinging]) outcome["text"] = random.choice([appearance_outcomes.strikeoutlooking, appearance_outcomes.strikeoutswinging])
elif hitnum < 1: elif roll["hitnum"] < 1:
outcome["text"] = appearance_outcomes.groundout outcome["text"] = appearance_outcomes.groundout
outcome["defender"] = defender outcome["defender"] = defender
elif hitnum < 4: elif roll["hitnum"] < 4:
outcome["text"] = appearance_outcomes.flyout outcome["text"] = appearance_outcomes.flyout
outcome["defender"] = defender outcome["defender"] = defender
else: else:
outcome["text"] = appearance_outcomes.walk outcome["text"] = appearance_outcomes.walk
if self.bases[1] is not None and hitnum < -2 and self.outs != 2: if self.bases[1] is not None and roll["hitnum"] < -2 and self.outs != 2:
outcome["text"] = appearance_outcomes.doubleplay outcome["text"] = appearance_outcomes.doubleplay
outcome["defender"] = "" outcome["defender"] = ""
@ -309,20 +305,20 @@ class game(object):
if self.outs < 2 and len(runners) > 1: #fielder's choice replaces not great groundouts if any forceouts are present if self.outs < 2 and len(runners) > 1: #fielder's choice replaces not great groundouts if any forceouts are present
def_stat = random_star_gen("defense_stars", defender) def_stat = random_star_gen("defense_stars", defender)
if -1.5 <= hitnum and hitnum < -0.5: #poorly hit groundouts if -1.5 <= roll["hitnum"] and roll["hitnum"] < -0.5: #poorly hit groundouts
outcome["text"] = appearance_outcomes.fielderschoice outcome["text"] = appearance_outcomes.fielderschoice
outcome["defender"] = "" outcome["defender"] = ""
if 2.5 <= hitnum and self.outs < 2: #well hit flyouts can lead to sacrifice flies/advanced runners if 2.5 <= roll["hitnum"] and self.outs < 2: #well hit flyouts can lead to sacrifice flies/advanced runners
if self.bases[2] is not None or self.bases[3] is not None: if self.bases[2] is not None or self.bases[3] is not None:
outcome["advance"] = True outcome["advance"] = True
else: else:
outcome["ishit"] = True outcome["ishit"] = True
if hitnum < 1: if roll["hitnum"] < 1:
outcome["text"] = appearance_outcomes.single outcome["text"] = appearance_outcomes.single
elif hitnum < 2.85 or "error" in outcome.keys(): elif roll["hitnum"] < 2.85 or "error" in outcome.keys():
outcome["text"] = appearance_outcomes.double outcome["text"] = appearance_outcomes.double
elif hitnum < 3.1: elif roll["hitnum"] < 3.1:
outcome["text"] = appearance_outcomes.triple outcome["text"] = appearance_outcomes.triple
else: else:
if self.bases[1] is not None and self.bases[2] is not None and self.bases[3] is not None: if self.bases[1] is not None and self.bases[2] is not None and self.bases[3] is not None:
@ -339,13 +335,16 @@ class game(object):
if self.bases[base+1] is None: #if there's somewhere to go if self.bases[base+1] is None: #if there's somewhere to go
thieves.append((self.bases[base], base)) thieves.append((self.bases[base], base))
for baserunner, start_base in thieves: for baserunner, start_base in thieves:
run_stars = random_star_gen("baserunning_stars", baserunner)*config()["stolen_base_chance_mod"] stats = {
if self.weather.name == "Midnight": "run_stars": random_star_gen("baserunning_stars", baserunner)*config()["stolen_base_chance_mod"],
run_stars = run_stars*2 "def_stars": random_star_gen("defense_stars", self.get_pitcher())
def_stars = random_star_gen("defense_stars", self.get_pitcher()) }
if run_stars >= (def_stars - 1.5): #if baserunner isn't worse than pitcher
self.weather.modify_steal_stats(stats)
if stats["run_stars"] >= (stats["def_stars"] - 1.5): #if baserunner isn't worse than pitcher
roll = random.random() roll = random.random()
if roll >= (-(((run_stars+1)/14)**2)+1): #plug it into desmos or something, you'll see if roll >= (-(((stats["run_stars"]+1)/14)**2)+1): #plug it into desmos or something, you'll see
attempts.append((baserunner, start_base)) attempts.append((baserunner, start_base))
if len(attempts) == 0: if len(attempts) == 0:

View file

@ -3,6 +3,7 @@ from leagues import league_structure
from league_storage import league_exists from league_storage import league_exists
from flask import Flask, url_for, Response, render_template, request, jsonify, send_from_directory, abort from flask import Flask, url_for, Response, render_template, request, jsonify, send_from_directory, abort
from flask_socketio import SocketIO, emit from flask_socketio import SocketIO, emit
from gametext import base_string
import database as db import database as db
app = Flask("the-prestige", static_folder='simmadome/build') app = Flask("the-prestige", static_folder='simmadome/build')
@ -156,7 +157,7 @@ def update_loop():
state["display_inning"] -= 1 state["display_inning"] -= 1
state["display_top_of_inning"] = False state["display_top_of_inning"] = False
if state["update_pause"] == 1: if state["update_pause"] == 1: #generate the top of the inning message before displaying the at bat result
state["update_emoji"] = "🍿" state["update_emoji"] = "🍿"
if this_game.over: if this_game.over:
state["display_inning"] -= 1 state["display_inning"] -= 1
@ -222,8 +223,8 @@ def update_loop():
if "fc_out" in this_game.last_update[0].keys(): if "fc_out" in this_game.last_update[0].keys():
name, base_string = this_game.last_update[0]['fc_out'] name, out_at_base_string = this_game.last_update[0]['fc_out']
updatestring = f"{this_game.last_update[0]['batter']} {this_game.last_update[0]['text'].value.format(name, base_string)} {this_game.last_update[0]['defender']}{punc}" updatestring = f"{this_game.last_update[0]['batter']} {this_game.last_update[0]['text'].value.format(name, out_at_base_string)} {this_game.last_update[0]['defender']}{punc}"
else: else:
updatestring = f"{this_game.last_update[0]['batter']} {this_game.last_update[0]['text'].value} {this_game.last_update[0]['defender']}{punc}" updatestring = f"{this_game.last_update[0]['batter']} {this_game.last_update[0]['text'].value} {this_game.last_update[0]['defender']}{punc}"
if this_game.last_update[1] > 0: if this_game.last_update[1] > 0:
@ -234,7 +235,7 @@ def update_loop():
if "veil" in this_game.last_update[0].keys(): if "veil" in this_game.last_update[0].keys():
state["update_emoji"] = "🌌" state["update_emoji"] = "🌌"
state["update_text"] += f" {this_game.last_update[0]['batter']}'s will manifests on {gametext.base_string(this_game.last_update[1])} base." state["update_text"] += f" {this_game.last_update[0]['batter']}'s will manifests on {base_string(this_game.last_update[1])} base."
elif "error" in this_game.last_update[0].keys(): elif "error" in this_game.last_update[0].keys():
state["update_emoji"] = "👻" state["update_emoji"] = "👻"
state["update_text"] = f"{this_game.last_update[0]['batter']}'s hit goes ethereal, and {this_game.last_update[0]['defender']} can't catch it! {this_game.last_update[0]['batter']} reaches base safely." state["update_text"] = f"{this_game.last_update[0]['batter']}'s hit goes ethereal, and {this_game.last_update[0]['defender']} can't catch it! {this_game.last_update[0]['batter']} reaches base safely."

View file

@ -1398,7 +1398,7 @@ async def watch_game(channel, newgame, user = None, league = None):
def prepare_game(newgame, league = None, weather_name = None): def prepare_game(newgame, league = None, weather_name = None):
if weather_name is None: if weather_name is None:
weathers = weather.all_weathers() weathers = weather.all_weathers()
newgame.weather = weathers[random.choice(list(weathers.keys()))]() newgame.weather = weathers[random.choice(list(weathers.keys()))](newgame)
state_init = { state_init = {
"away_name" : newgame.teams['away'].name, "away_name" : newgame.teams['away'].name,
@ -1418,9 +1418,6 @@ def prepare_game(newgame, league = None, weather_name = None):
else: else:
state_init["is_league"] = True state_init["is_league"] = True
if newgame.weather.name == "Heavy Snow":
newgame.weather.counter_away = random.randint(0,len(newgame.teams['away'].lineup)-1)
newgame.weather.counter_home = random.randint(0,len(newgame.teams['home'].lineup)-1)
return newgame, state_init return newgame, state_init
async def start_tournament_round(channel, tourney, seeding = None): async def start_tournament_round(channel, tourney, seeding = None):

View file

@ -1,12 +1,11 @@
import random import random
import math
from gametext import appearance_outcomes from gametext import appearance_outcomes
class Weather: class Weather:
def __init__(self): def __init__(self, game):
self.name = "Sunny" self.name = "Sunny"
self.emoji = "🌞" + "\uFE00" self.emoji = "🌞" + "\uFE00"
self.counter_away = 0
self.counter_home = 0
def __str__(self): def __str__(self):
return f"{self.emoji} {self.name}" return f"{self.emoji} {self.name}"
@ -15,43 +14,44 @@ class Weather:
# activates after the batter calculation. modify result, or just return another thing # activates after the batter calculation. modify result, or just return another thing
pass pass
def modify_stats_preroll(self, bat_stat, pitch_stat): # ugly
# Activates before batting and pitch
return bat_stat, pitch_stat
def on_flip_inning(self, game): def on_flip_inning(self, game):
pass pass
def on_choose_next_batter(self, game): def on_choose_next_batter(self, game):
pass pass
def modify_steal_stats(self, roll):
pass
def modify_atbat_stats(self, player_rolls):
# Activates before batting
pass
def modify_atbat_roll(self, outcome, roll, defender):
pass
class Supernova(Weather): # todo class Supernova(Weather): # todo
def __init__(self): def __init__(self, game):
super().__init__()
self.name = "Supernova" self.name = "Supernova"
self.emoji = "🌟" + "\uFE00" self.emoji = "🌟" + "\uFE00"
def activate(self, game, result):
pass
def modify_stats_preroll(self, bat_stat, pitch_stat): def modify_atbat_stats(self, roll):
if self.weather.name == "Supernova": roll["pitch_stat"] *= 0.9
pitch_stat = pitch_stat * 0.9
class Midnight(Weather): # todo class Midnight(Weather): # todo
def __init__(self): def __init__(self, game):
super().__init__()
self.name = "Midnight" self.name = "Midnight"
self.emoji = "🕶" + "\uFE00" self.emoji = "🕶" + "\uFE00"
def activate(self, game, result):
pass def modify_steal_stats(self, roll):
roll["run_stars"] *= 2
class SlightTailwind(Weather): class SlightTailwind(Weather):
def __init__(self): def __init__(self, game):
super().__init__()
self.name = "Slight Tailwind" self.name = "Slight Tailwind"
self.emoji = "🏌️‍♀️" + "\uFE00" self.emoji = "🏌️‍♀️" + "\uFE00"
def activate(self, game, result): def activate(self, game, result):
if game.top_of_inning: if game.top_of_inning:
offense_team = game.teams["away"] offense_team = game.teams["away"]
weather_count = self.counter_away weather_count = self.counter_away
@ -67,10 +67,11 @@ class SlightTailwind(Weather):
result["mulligan"] = True result["mulligan"] = True
class HeavySnow(Weather): class HeavySnow(Weather):
def __init__(self): def __init__(self, game):
super().__init__()
self.name = "Heavy Snow" self.name = "Heavy Snow"
self.emoji = "" + "\uFE00" self.emoji = "" + "\uFE00"
self.counter_away = random.randint(0,len(game.teams['away'].lineup)-1)
self.counter_home = random.randint(0,len(game.teams['home'].lineup)-1)
def activate(self, game, result): def activate(self, game, result):
if game.top_of_inning: if game.top_of_inning:
@ -107,16 +108,23 @@ class HeavySnow(Weather):
game.current_batter = bat_team.pitcher game.current_batter = bat_team.pitcher
class Twilight(Weather): class Twilight(Weather):
def __init__(self): def __init__(self,game):
super().__init__()
self.name = "Twilight" self.name = "Twilight"
self.emoji = "👻" + "\uFE00" self.emoji = "👻" + "\uFE00"
def activate(self, game, result): def activate(self, game, result):
pass pass
def modify_atbat_roll(self, outcome, roll, defender):
error_line = - (math.log(defender.stlats["defense_stars"] + 1)/50) + 1
error_roll = random.random()
if error_roll > error_line:
outcome["error"] = True
outcome["defender"] = defender
roll["pb_system_stat"] = 0.1
class ThinnedVeil(Weather): class ThinnedVeil(Weather):
def __init__(self): def __init__(self,game):
super().__init__()
self.name = "Thinned Veil" self.name = "Thinned Veil"
self.emoji = "🌌" + "\uFE00" self.emoji = "🌌" + "\uFE00"
@ -126,22 +134,21 @@ class ThinnedVeil(Weather):
result["veil"] = True result["veil"] = True
class HeatWave(Weather): class HeatWave(Weather):
def __init__(self): def __init__(self,game):
super().__init__()
self.name = "Heat Wave" self.name = "Heat Wave"
self.emoji = "🌄" + "\uFE00" self.emoji = "🌄" + "\uFE00"
self.counter_away = random.randint(2,4) self.counter_away = -1# random.randint(2,4)
self.counter_home = random.randint(2,4) self.counter_home = -1 # random.randint(2,4)
def on_flip_inning(self, game): def on_flip_inning(self, game):
current_pitcher = game.get_pitcher() current_pitcher = game.get_pitcher()
if game.top_of_inning: if game.top_of_inning:
bat_team = game.teams["away"]
counter = self.counter_away
else:
bat_team = game.teams["home"] bat_team = game.teams["home"]
counter = self.counter_home counter = self.counter_home
else:
bat_team = game.teams["away"]
counter = self.counter_away
should_change_pitcher = False should_change_pitcher = False
if game.inning >= counter: if game.inning >= counter:
@ -158,8 +165,7 @@ class HeatWave(Weather):
tries += 1 tries += 1
class Drizzle(Weather): class Drizzle(Weather):
def __init__(self): def __init__(self,game):
super().__init__()
self.name = "Drizzle" self.name = "Drizzle"
self.emoji = "🌧" self.emoji = "🌧"
@ -173,9 +179,10 @@ class Drizzle(Weather):
game.bases[2] = lineup[(game.teams[next_team].lineup_position-1) % len(lineup)] game.bases[2] = lineup[(game.teams[next_team].lineup_position-1) % len(lineup)]
class Sun2(Weather): class Sun2(Weather):
def __init__(self): def __init__(self, game):
super().__init__()
self.name = "Sun 2" self.name = "Sun 2"
def activate(self, game): def activate(self, game):
for teamtype in game.teams: for teamtype in game.teams:
team = game.teams[teamtype] team = game.teams[teamtype]
@ -184,15 +191,15 @@ class Sun2(Weather):
# no win counting yet :( # no win counting yet :(
result.clear() result.clear()
result.update({ result.update({
"text": "The {} collect 10! Sun 2 smiles.".format(team.name), "text": "The {} collect 10! Sun 2 smiles.".format(team.name),
"text_only": True, "text_only": True,
}) })
class NameSwappyWeather(Weather): class NameSwappyWeather(Weather):
def __init__(self): def __init__(self, game):
super().__init__()
self.name = "Literacy" self.name = "Literacy"
self.activation_chance = 0.01 self.activation_chance = 0.01
def activate(self, game): def activate(self, game):
if random.random() < self.activation_chance: if random.random() < self.activation_chance:
teamtype = random.choice(["away","home"]) teamtype = random.choice(["away","home"])
@ -220,11 +227,11 @@ class NameSwappyWeather(Weather):
}) })
class Feedback(Weather): class Feedback(Weather):
def __init__(self): def __init__(self, game):
super().__init__()
self.name = "Feedback" self.name = "Feedback"
self.activation_chance = 0.01 self.activation_chance = 0.01
self.swap_batter_vs_pitcher_chance = 0.8 self.swap_batter_vs_pitcher_chance = 0.8
def activate(self, game, result): def activate(self, game, result):
if random.random() < self.activation_chance: if random.random() < self.activation_chance:
# feedback time # feedback time
@ -261,8 +268,8 @@ def all_weathers():
#"Midnight": Midnight, #"Midnight": Midnight,
#"Slight Tailwind": SlightTailwind, #"Slight Tailwind": SlightTailwind,
"Heavy Snow": HeavySnow, "Heavy Snow": HeavySnow,
# "Twilight" : Twilight, # "Twilight" : Twilight, # works
# "Thinned Veil" : ThinnedVeil, # "Thinned Veil" : ThinnedVeil, # works
"Heat Wave" : HeatWave, "Heat Wave" : HeatWave,
"Drizzle" : Drizzle, # works "Drizzle" : Drizzle, # works
# Sun2, # Sun2,