paper-dynasty-database/app/card_creation.py
2023-10-22 13:53:27 -05:00

3080 lines
224 KiB
Python

import copy
import logging
import math
import re
import pandas as pd
import pydantic
from .db_engine import model_to_dict
from decimal import Decimal
from pydantic import validator
from typing import Literal, Optional
chance_df = pd.DataFrame(
{
'd20-1': [0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.25, 0.2, 0.15, 0.1, 0.05],
'd20-2': [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1],
'd20-3': [0.15, 0.3, 0.45, 0.6, 0.75, 0.9, 0.75, 0.6, 0.45, 0.3, 0.15],
'd20-4': [0.2, 0.4, 0.6, 0.8, 1, 1.2, 1, 0.8, 0.6, 0.4, 0.2],
'd20-5': [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.25, 1, 0.75, 0.5, 0.25],
'd20-6': [0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 1.5, 1.2, 0.9, 0.6, 0.3],
'd20-7': [0.35, 0.7, 1.05, 1.4, 1.75, 2.1, 1.75, 1.4, 1.05, 0.7, 0.35],
'd20-8': [0.4, 0.8, 1.2, 1.6, 2, 2.4, 2, 1.6, 1.2, 0.8, 0.4],
'd20-9': [0.45, 0.9, 1.35, 1.8, 2.25, 2.7, 2.25, 1.8, 1.35, 0.9, 0.45],
'd20-10': [0.5, 1, 1.5, 2, 2.5, 3, 2.5, 2, 1.5, 1, 0.5],
'd20-11': [0.55, 1.1, 1.65, 2.2, 2.75, 3.3, 2.75, 2.2, 1.65, 1.1, 0.55],
'd20-12': [0.6, 1.2, 1.8, 2.4, 3, 3.6, 3, 2.4, 1.8, 1.2, 0.6],
'd20-13': [0.65, 1.3, 1.95, 2.6, 3.25, 3.9, 3.25, 2.6, 1.95, 1.3, 0.65],
'd20-14': [0.7, 1.4, 2.1, 2.8, 3.5, 4.2, 3.5, 2.8, 2.1, 1.4, 0.7],
'd20-15': [0.75, 1.5, 2.25, 3, 3.75, 4.5, 3.75, 3, 2.25, 1.5, 0.75],
'd20-16': [0.8, 1.6, 2.4, 3.2, 4, 4.8, 4, 3.2, 2.4, 1.6, 0.8],
'd20-17': [0.85, 1.7, 2.55, 3.4, 4.25, 5.1, 4.25, 3.4, 2.55, 1.7, 0.85],
'd20-18': [0.9, 1.8, 2.7, 3.6, 4.5, 5.4, 4.5, 3.6, 2.7, 1.8, 0.9],
'd20-19': [0.95, 1.9, 2.85, 3.8, 4.75, 5.7, 4.75, 3.8, 2.85, 1.9, 0.95],
'd20-20': [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]
},
index=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
)
encoded_images = {
'Hall of Fame': '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',
'MVP': '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',
'All-Star': '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',
'Starter': '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',
'Reserve': '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',
'Replacement': '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'
}
EXACT_CHANCES = [
Decimal('5.7'), Decimal('5.4'), Decimal('5.1'), Decimal('4.8'), Decimal('4.75'), Decimal('4.5'), Decimal('4.25'),
Decimal('4.2'), Decimal('3.9'), Decimal('3.8'), Decimal('3.75'), Decimal('3.6'), Decimal('3.5'), Decimal('3.4'),
Decimal('3.3'), Decimal('3.25'), Decimal('3.2'), Decimal('2.85'), Decimal('2.8'), Decimal('2.75'), Decimal('2.7'),
Decimal('2.6'), Decimal('2.55'), Decimal('2.5'), Decimal('2.4'), Decimal('2.25'), Decimal('2.2'), Decimal('2.1'),
Decimal('1.95'), Decimal('1.9'), Decimal('1.8'), Decimal('1.75'), Decimal('1.7'), Decimal('1.65'), Decimal('1.6'),
Decimal('1.5'), Decimal('1.4'), Decimal('1.35'), Decimal('1.3'), Decimal('1.25'), Decimal('1.2'), Decimal('1.1'),
Decimal('1.05')
]
class PlayResult(pydantic.BaseModel):
full_name: str
short_name: str
is_offense: bool = True
@validator("is_offense", always=True)
def offense_validator(cls, v, values, **kwargs):
return values['short_name'][:2] in ['HR', 'TR', 'DO', 'SI', 'WA', 'HB', '◆B']
PLAY_RESULTS = {
'hr': PlayResult(full_name='HOMERUN', short_name='HR'),
'bp-hr': PlayResult(full_name='◆BP-HR', short_name='◆BP-HR'),
'tr': PlayResult(full_name='TRIPLE', short_name='TR'),
'do-lf': PlayResult(full_name=f'DOUBLE (lf)', short_name=f'DO (lf)'),
'do-cf': PlayResult(full_name=f'DOUBLE (cf)', short_name=f'DO (cf)'),
'do-rf': PlayResult(full_name=f'DOUBLE (rf)', short_name=f'DO (rf)'),
'do***': PlayResult(full_name=f'DOUBLE***', short_name=f'DO***'),
'do**': PlayResult(full_name=f'DOUBLE**', short_name=f'DO**'),
'si**': PlayResult(full_name='SINGLE**', short_name='SI**'),
'si*': PlayResult(full_name='SINGLE*', short_name='SI*'),
'si-cf': PlayResult(full_name='SINGLE (cf)', short_name='SI (cf)'),
'bp-si': PlayResult(full_name='▼BP-SI', short_name='◆BP-SI'),
'walk': PlayResult(full_name='WALK', short_name='WALK'),
'fly-rf': PlayResult(full_name=f'fly (rf) B', short_name=f'fly (rf) B'),
'fly-lf': PlayResult(full_name=f'fly (lf) B', short_name=f'fly (lf) B'),
'fly-cf': PlayResult(full_name=f'fly (cf) B', short_name=f'fly (cf) B'),
'fly-bq': PlayResult(full_name=f'fly B?', short_name=f'fly B?')
}
class BattingCardRatingsModel(pydantic.BaseModel):
battingcard: int
vs_hand: Literal['R', 'L']
pull_rate: Decimal = Decimal(0.0)
center_rate: Decimal = Decimal(0.0)
slap_rate: Decimal = Decimal(0.0)
homerun: Decimal = Decimal(0.0)
bp_homerun: Decimal = Decimal(0.0)
triple: Decimal = Decimal(0.0)
double_three: Decimal = Decimal(0.0)
double_two: Decimal = Decimal(0.0)
double_pull: Decimal = Decimal(0.0)
single_two: Decimal = Decimal(0.0)
single_one: Decimal = Decimal(0.0)
single_center: Decimal = Decimal(0.0)
bp_single: Decimal = Decimal(0.0)
hbp: Decimal = Decimal(0.0)
walk: Decimal = Decimal(0.0)
strikeout: Decimal = Decimal(0.0)
lineout: Decimal = Decimal(0.0)
popout: Decimal = Decimal(0.0)
flyout_a: Decimal = Decimal(0.0)
flyout_bq: Decimal = Decimal(0.0)
flyout_lf_b: Decimal = Decimal(0.0)
flyout_rf_b: Decimal = Decimal(0.0)
groundout_a: Decimal = Decimal(0.0)
groundout_b: Decimal = Decimal(0.0)
groundout_c: Decimal = Decimal(0.0)
avg: Decimal = Decimal(0.0)
obp: Decimal = Decimal(0.0)
slg: Decimal = Decimal(0.0)
def total_chances(self):
return Decimal(sum([
self.homerun, self.bp_homerun, self.triple, self.double_three, self.double_two, self.double_pull,
self.single_two, self.single_one, self.single_center, self.bp_single, self.hbp, self.walk, self.strikeout,
self.lineout, self.popout, self.flyout_a, self.flyout_bq, self.flyout_lf_b, self.flyout_rf_b,
self.groundout_a, self.groundout_b, self.groundout_c
]))
def update_slash_lines(self):
self.avg = Decimal(
(self.homerun + self.bp_homerun / 2 + self.triple + self.double_three +
self.double_two + self.double_pull + self.single_two + self.single_one +
self.single_center + self.bp_single / 2) / Decimal(108)
)
self.obp = Decimal(((self.hbp + self.walk) / 108) + self.avg)
self.slg = Decimal(
(self.homerun * 4 + self.bp_homerun * 2 + self.triple * 3 + self.double_three * 2 +
self.double_two * 2 + self.double_pull * 2 + self.single_two + self.single_one +
self.single_center + self.bp_single / 2) / 108
)
class PitchingCardRatingsModel(pydantic.BaseModel):
pitchingcard: int
vs_hand: Literal['R', 'L']
homerun: Decimal = Decimal(0.0)
bp_homerun: Decimal = Decimal(0.0)
triple: Decimal = Decimal(0.0)
double_three: Decimal = Decimal(0.0)
double_two: Decimal = Decimal(0.0)
double_cf: Decimal = Decimal(0.0)
single_two: Decimal = Decimal(0.0)
single_one: Decimal = Decimal(0.0)
single_center: Decimal = Decimal(0.0)
bp_single: Decimal = Decimal(0.0)
hbp: Decimal = Decimal(0.0)
walk: Decimal = Decimal(0.0)
strikeout: Decimal = Decimal(0.0)
flyout_lf_b: Decimal = Decimal(0.0)
flyout_cf_b: Decimal = Decimal(0.0)
flyout_rf_b: Decimal = Decimal(0.0)
groundout_a: Decimal = Decimal(0.0)
groundout_b: Decimal = Decimal(0.0)
xcheck_p: Decimal = Decimal(0.0)
xcheck_c: Decimal = Decimal(0.0)
xcheck_1b: Decimal = Decimal(0.0)
xcheck_2b: Decimal = Decimal(0.0)
xcheck_3b: Decimal = Decimal(0.0)
xcheck_ss: Decimal = Decimal(0.0)
xcheck_lf: Decimal = Decimal(0.0)
xcheck_cf: Decimal = Decimal(0.0)
xcheck_rf: Decimal = Decimal(0.0)
avg: Decimal = Decimal(0.0)
obp: Decimal = Decimal(0.0)
slg: Decimal = Decimal(0.0)
def total_chances(self):
return Decimal(sum([
self.homerun, self.bp_homerun, self.triple, self.double_three, self.double_two, self.double_cf,
self.single_two, self.single_one, self.single_center, self.bp_single, self.hbp, self.walk, self.strikeout,
self.flyout_lf_b, self.flyout_cf_b, self.flyout_rf_b, self.groundout_a, self.groundout_b, self.xcheck_p,
self.xcheck_c, self.xcheck_1b, self.xcheck_2b, self.xcheck_3b, self.xcheck_ss, self.xcheck_lf,
self.xcheck_cf, self.xcheck_rf
]))
def update_slash_lines(self):
self.avg = Decimal(
(self.homerun + self.bp_homerun / 2 + self.triple + self.double_three +
self.double_two + self.double_cf + self.single_two + self.single_one +
self.single_center + self.bp_single / 2) / Decimal(108)
)
self.obp = Decimal(((self.hbp + self.walk) / 108) + self.avg)
self.slg = Decimal(
(self.homerun * 4 + self.bp_homerun * 2 + self.triple * 3 + self.double_three * 2 +
self.double_two * 2 + self.double_cf * 2 + self.single_two + self.single_one +
self.single_center + self.bp_single / 2) / 108)
class CardResult(pydantic.BaseModel):
result_one: str = None
result_two: str = None
d20_one: str = None
d20_two: str = None
bold_one: bool = False
bold_two: bool = False
def __str__(self):
res_text = f'Empty'
if self.result_one is not None:
res_text = f'{self.result_one}'
if self.d20_one is not None:
res_text += f' | {self.d20_one}'
if self.result_two is not None:
res_text += f'\n{self.result_two} | {self.d20_two}'
return res_text
def is_full(self):
return self.result_one is not None
def assign_play(self, play: PlayResult, secondary_play: Optional[PlayResult] = None, d20: Optional[int] = None):
if secondary_play is None:
self.result_one = play.full_name
if '++' in play.full_name:
logging.warning(f'Too many plus symbols: {play.full_name}')
self.result_one = re.sub(r'\++', '+', play.full_name)
if play.is_offense:
self.bold_one = True
else:
self.result_one = play.short_name
self.result_two = secondary_play.short_name
self.d20_one = f'1-{d20}'
if d20 == 19:
self.d20_two = f'20'
else:
self.d20_two = f'{d20 + 1}-20'
if play.is_offense:
self.bold_one = True
if secondary_play.is_offense:
self.bold_two = True
logging.debug(f'this result: {self}')
class CardColumn(pydantic.BaseModel):
two: CardResult = CardResult() # 1 chance
three: CardResult = CardResult() # 2 chances
four: CardResult = CardResult() # 3 chances
five: CardResult = CardResult() # 4 chances
six: CardResult = CardResult() # 5 chances
seven: CardResult = CardResult() # 6 chances
eight: CardResult = CardResult() # 5 chances
nine: CardResult = CardResult() # 4 chances
ten: CardResult = CardResult() # 3 chances
eleven: CardResult = CardResult() # 2 chances
twelve: CardResult = CardResult() # 1 chance
num_splits: int = 0
num_lomax: int = 0
num_plusgb: int = 0
def __str__(self):
return f'2-{self.two}\n' \
f'3-{self.three}\n' \
f'4-{self.four}\n' \
f'5-{self.five}\n' \
f'6-{self.six}\n' \
f'7-{self.seven}\n' \
f'8-{self.eight}\n' \
f'9-{self.nine}\n' \
f'10-{self.ten}\n' \
f'11-{self.eleven}\n' \
f'12-{self.twelve}'
def get_text(self):
sixes = f''
results = f''
d20 = f''
def bold(text):
return f'<b>{text}</b>'
def blank():
return f'&nbsp;'
for count, x in enumerate(
[self.two, self.three, self.four, self.five, self.six, self.seven, self.eight, self.nine,
self.ten, self.eleven, self.twelve], start=2):
if x.bold_one:
this_six = bold(f'{count}-')
this_result = bold(x.result_one)
if x.d20_one is not None:
this_d20 = bold(x.d20_one)
else:
this_d20 = blank()
else:
this_six = f'{count}-'
this_result = f'{x.result_one}'
if x.d20_one is not None:
this_d20 = f'{x.d20_one}'
else:
this_d20 = blank()
if x.result_two is not None:
if x.bold_two:
this_six += f'<br>{bold(blank())}'
this_result += f'<br>{bold(x.result_two)}'
this_d20 += f'<br>{bold(x.d20_two)}'
else:
this_six += f'<br>{blank()}'
this_result += f'<br>{x.result_two}'
this_d20 += f'<br>{x.d20_two}'
sixes += f'{this_six}<br>'
results += f'{this_result}<br>'
d20 += f'{this_d20}<br>'
return {
'sixes': sixes,
'results': results,
'd20': d20
}
def is_full(self):
return self.two.is_full() and self.three.is_full() and self.four.is_full() and self.five.is_full() and \
self.six.is_full() and self.seven.is_full() and self.eight.is_full() and self.nine.is_full() and \
self.ten.is_full() and self.eleven.is_full() and self.twelve.is_full()
def add_result(
self, play: PlayResult, alt_direction: int, chances: Decimal, secondary_play: Optional[PlayResult] = None):
if chances > Decimal(6.0):
logging.error(f'Cannot assign more than 6 chances per call\n'
f'Play: {play}\nAlt Direction: {alt_direction}\nChances: {chances}\n'
f'Secondary Play: {secondary_play}')
raise ValueError(f'Cannot assign more than 6 chances per call')
elif math.floor(chances) != chances and secondary_play is None:
if chances > Decimal(1.0):
chances = Decimal(math.floor(chances))
else:
logging.error(f'Must have secondary play for fractional chances; could not round down to an integer\n'
f'Play: {play}\nChances: {chances}\nSecondary Play: {secondary_play}')
return False
# Chances is whole number
if math.floor(chances) == chances:
if chances == Decimal(6):
if not self.seven.is_full():
self.seven.assign_play(play)
return chances, 0
# Plus one
if not self.six.is_full():
if not self.two.is_full():
self.six.assign_play(play)
self.two.assign_play(play)
return chances, 0
elif not self.twelve.is_full():
self.six.assign_play(play)
self.twelve.assign_play(play)
return chances, 0
# Plus one
if not self.eight.is_full():
if not self.two.is_full():
self.eight.assign_play(play)
self.two.assign_play(play)
return chances, 0
elif not self.twelve.is_full():
self.eight.assign_play(play)
self.twelve.assign_play(play)
return chances, 0
# Plus two
if not self.five.is_full():
if not self.three.is_full():
self.five.assign_play(play)
self.three.assign_play(play)
return chances, 0
elif not self.eleven.is_full():
self.five.assign_play(play)
self.eleven.assign_play(play)
return chances, 0
# Bulk 2, 3, 4 and 10, 11, 12
if not self.three.is_full() and not self.two.is_full() and not self.four.is_full():
self.four.assign_play(play)
self.three.assign_play(play)
self.two.assign_play(play)
return chances, 0
if not self.ten.is_full() and not self.eleven.is_full() and not self.twelve.is_full():
self.ten.assign_play(play)
self.eleven.assign_play(play)
self.twelve.assign_play(play)
return chances, 0
if not self.nine.is_full():
if not self.three.is_full():
self.nine.assign_play(play)
self.three.assign_play(play)
return chances, 0
elif not self.eleven.is_full():
self.nine.assign_play(play)
self.eleven.assign_play(play)
return chances, 0
if chances == Decimal(5):
if not self.six.is_full():
self.six.assign_play(play)
return chances, 0
if not self.eight.is_full():
self.eight.assign_play(play)
return chances, 0
# Bulk 3, 4 and 10, 11
if not self.three.is_full() and not self.four.is_full():
self.four.assign_play(play)
self.three.assign_play(play)
return chances, 0
if not self.ten.is_full() and not self.eleven.is_full():
self.ten.assign_play(play)
self.eleven.assign_play(play)
return chances, 0
# Plus one
if not self.five.is_full():
if not self.two.is_full():
self.five.assign_play(play)
self.two.assign_play(play)
return chances, 0
elif not self.twelve.is_full():
self.five.result_one = play.full_name
self.twelve.result_one = play.full_name
return chances, 0
# Plus one
if not self.nine.is_full():
if not self.two.is_full():
self.nine.assign_play(play)
self.two.assign_play(play)
return chances, 0
elif not self.twelve.is_full():
self.nine.assign_play(play)
self.twelve.assign_play(play)
return chances, 0
# Plus two
if not self.four.is_full():
if not self.three.is_full():
self.four.assign_play(play)
self.three.assign_play(play)
return chances, 0
elif not self.eleven.is_full():
self.four.assign_play(play)
self.eleven.assign_play(play)
return chances, 0
# Plus two
if not self.ten.is_full():
if not self.three.is_full():
self.ten.assign_play(play)
self.three.assign_play(play)
return chances, 0
elif not self.eleven.is_full():
self.ten.assign_play(play)
self.eleven.assign_play(play)
return chances, 0
if chances == Decimal(4):
if not self.five.is_full():
self.five.assign_play(play)
return chances, 0
if not self.nine.is_full():
self.nine.assign_play(play)
return chances, 0
# Plus one
if not self.four.is_full():
if not self.two.is_full():
self.four.assign_play(play)
self.two.assign_play(play)
return chances, 0
elif not self.twelve.is_full():
self.four.assign_play(play)
self.twelve.assign_play(play)
return chances, 0
# Plus one
if not self.ten.is_full():
if not self.two.is_full():
self.ten.assign_play(play)
self.two.assign_play(play)
return chances, 0
elif not self.twelve.is_full():
self.ten.assign_play(play)
self.twelve.assign_play(play)
return chances, 0
if not self.three.is_full() and not self.eleven.is_full():
self.three.assign_play(play)
self.eleven.assign_play(play)
return chances, 0
if chances == Decimal(3):
if not self.four.is_full():
self.four.assign_play(play)
return chances, 0
if not self.ten.is_full():
self.ten.assign_play(play)
return chances, 0
# Plus one
if not self.three.is_full():
if not self.two.is_full():
self.three.assign_play(play)
self.two.assign_play(play)
return chances, 0
elif not self.twelve.is_full():
self.three.assign_play(play)
self.twelve.assign_play(play)
return chances, 0
# Plus one
if not self.eleven.is_full():
if not self.twelve.is_full():
self.eleven.assign_play(play)
self.twelve.assign_play(play)
return chances, 0
if not self.two.is_full():
self.eleven.assign_play(play)
self.two.assign_play(play)
return chances, 0
if chances == Decimal(2):
if not self.three.is_full():
self.three.assign_play(play)
return chances, 0
if not self.eleven.is_full():
self.eleven.assign_play(play)
return chances, 0
if not self.two.is_full() and not self.twelve.is_full():
self.two.assign_play(play)
self.twelve.assign_play(play)
return chances, 0
if chances == Decimal(1):
if not self.two.is_full():
self.two.assign_play(play)
return chances, 0
if not self.twelve.is_full():
self.twelve.assign_play(play)
return chances, 0
return False
logging.info(f'Not a whole number | Chances: {chances}')
if chances in EXACT_CHANCES and self.num_splits < 4 and secondary_play is not None:
logging.info(f'In Exact Chances!')
if chances >= 3:
self.num_splits += 1
logging.info(f'Chances is greater than 3')
if chances == Decimal('3.2'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 16)
return chances, Decimal('0.8')
elif not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 16)
return chances, Decimal('0.8')
elif chances == Decimal('3.25'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 13)
return chances, Decimal('1.75')
elif not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 13)
return chances, Decimal('1.75')
elif chances == Decimal('3.3') and not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 11)
return chances, Decimal('2.7')
elif chances == Decimal('3.4'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 17)
return chances, Decimal('0.6')
elif not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 17)
return chances, Decimal('0.6')
elif chances == Decimal('3.5'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 14)
return chances, Decimal('1.5')
elif not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 14)
return chances, Decimal('1.5')
elif chances == Decimal('3.6'):
if not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 18)
return chances, Decimal('0.4')
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 18)
return chances, Decimal('0.4')
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 12)
return chances, Decimal('2.4')
elif chances == Decimal('3.75'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 15)
return chances, Decimal('1.25')
elif not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 15)
return chances, Decimal('1.25')
elif chances == Decimal('3.8'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 19)
return chances, Decimal('0.2')
elif not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 19)
return chances, Decimal('0.2')
elif chances == Decimal('3.9'):
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 13)
return chances, Decimal('2.1')
elif chances == Decimal('4.2'):
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 14)
return chances, Decimal('1.8')
elif chances == Decimal('4.25'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 17)
return chances, Decimal('0.75')
elif not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 17)
return chances, Decimal('0.75')
elif chances == Decimal('4.5'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 18)
return chances, Decimal('0.5')
if not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 18)
return chances, Decimal('0.5')
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 15)
return chances, Decimal('1.5')
elif chances == Decimal('4.75'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 19)
return chances, Decimal('0.25')
elif not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 19)
return chances, Decimal('0.25')
elif chances == Decimal('4.8'):
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 16)
return chances, Decimal('1.2')
elif chances == Decimal('5.1'):
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 17)
return chances, Decimal('0.9')
elif chances == Decimal('5.4'):
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 18)
return chances, Decimal('0.6')
elif chances == Decimal('5.7'):
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 19)
return chances, Decimal('0.3')
elif chances >= 1:
self.num_splits += 1
logging.info(f'Chances is greater than 1')
if chances == Decimal('1.05'):
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 7)
return chances, Decimal('1.95')
elif not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 7)
return chances, Decimal('1.95')
if chances == Decimal('1.1'):
if not self.three.is_full():
self.three.assign_play(play, secondary_play, 11)
return chances, Decimal('0.9')
elif not self.eleven.is_full():
self.eleven.assign_play(play, secondary_play, 11)
return chances, Decimal('0.9')
if chances == Decimal('1.2'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 6)
return chances, Decimal('2.8')
elif not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 6)
return chances, Decimal('2.8')
elif not self.four.is_full():
self.four.assign_play(play, secondary_play, 8)
return chances, Decimal('1.8')
elif not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 8)
return chances, Decimal('1.8')
elif not self.three.is_full():
self.three.assign_play(play, secondary_play, 12)
return chances, Decimal('0.8')
elif not self.eleven.is_full():
self.eleven.assign_play(play, secondary_play, 12)
return chances, Decimal('0.8')
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 4)
return chances, Decimal('4.8')
if chances == Decimal('1.25'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 5)
return chances, Decimal('3.75')
elif not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 5)
return chances, Decimal('3.75')
if chances == Decimal('1.3'):
if not self.three.is_full():
self.three.assign_play(play, secondary_play, 13)
return chances, Decimal('0.7')
elif not self.eleven.is_full():
self.eleven.assign_play(play, secondary_play, 13)
return chances, Decimal('0.7')
if chances == Decimal('1.35'):
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 9)
return chances, Decimal('1.65')
elif not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 9)
return chances, Decimal('1.65')
if chances == Decimal('1.4'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 7)
return chances, Decimal('2.6')
elif not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 7)
return chances, Decimal('2.6')
elif not self.three.is_full():
self.three.assign_play(play, secondary_play, 14)
return chances, Decimal('0.6')
elif not self.eleven.is_full():
self.eleven.assign_play(play, secondary_play, 14)
return chances, Decimal('0.6')
if chances == Decimal('1.5'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 6)
return chances, Decimal('3.5')
elif not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 6)
return chances, Decimal('3.5')
elif not self.four.is_full():
self.four.assign_play(play, secondary_play, 10)
return chances, Decimal('1.5')
elif not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 10)
return chances, Decimal('1.5')
elif not self.three.is_full():
self.three.assign_play(play, secondary_play, 15)
return chances, Decimal('0.5')
elif not self.eleven.is_full():
self.eleven.assign_play(play, secondary_play, 15)
return chances, Decimal('0.5')
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 5)
return chances, Decimal('4.5')
if chances == Decimal('1.6'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 8)
return chances, Decimal('2.4')
elif not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 8)
return chances, Decimal('2.4')
elif not self.three.is_full():
self.three.assign_play(play, secondary_play, 16)
return chances, Decimal('0.4')
elif not self.eleven.is_full():
self.eleven.assign_play(play, secondary_play, 16)
return chances, Decimal('0.4')
if chances == Decimal('1.65'):
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 11)
return chances, Decimal('1.35')
elif not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 11)
return chances, Decimal('1.35')
if chances == Decimal('1.7'):
if not self.three.is_full():
self.three.assign_play(play, secondary_play, 17)
return chances, Decimal('0.3')
elif not self.eleven.is_full():
self.eleven.assign_play(play, secondary_play, 17)
return chances, Decimal('0.3')
if chances == Decimal('1.75'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 7)
return chances, Decimal('3.25')
elif not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 7)
return chances, Decimal('3.25')
if chances == Decimal('1.8'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 9)
return chances, Decimal('2.2')
if not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 9)
return chances, Decimal('2.2')
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 12)
return chances, Decimal('1.2')
if not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 12)
return chances, Decimal('1.2')
if not self.three.is_full():
self.three.assign_play(play, secondary_play, 18)
return chances, Decimal('0.2')
if not self.eleven.is_full():
self.eleven.assign_play(play, secondary_play, 18)
return chances, Decimal('0.2')
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 6)
return chances, Decimal('4.2')
if chances == Decimal('1.9'):
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 13)
return chances, Decimal('1.1')
if not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 13)
return chances, Decimal('1.1')
if not self.three.is_full():
self.three.assign_play(play, secondary_play, 19)
return chances, Decimal('0.1')
if not self.eleven.is_full():
self.eleven.assign_play(play, secondary_play, 19)
return chances, Decimal('0.1')
if chances == Decimal('1.95'):
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 13)
return chances, Decimal('1.05')
elif not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 13)
return chances, Decimal('1.05')
if chances == Decimal('2.1'):
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 14)
return chances, Decimal('0.9')
if not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 14)
return chances, Decimal('0.9')
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 7)
return chances, Decimal('3.9')
if chances == Decimal('2.2'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 11)
return chances, Decimal('1.8')
if not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 11)
return chances, Decimal('1.8')
if chances == Decimal('2.25'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 9)
return chances, Decimal('2.75')
if not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 9)
return chances, Decimal('2.75')
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 15)
return chances, Decimal('0.75')
if not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 15)
return chances, Decimal('0.75')
if chances == Decimal('2.4'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 12)
return chances, Decimal('1.6')
if not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 12)
return chances, Decimal('1.6')
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 16)
return chances, Decimal('0.6')
if not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 16)
return chances, Decimal('0.6')
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 8)
return chances, Decimal('3.6')
if chances == Decimal('2.5'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 10)
return chances, Decimal('2.5')
if not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 10)
return chances, Decimal('2.5')
if chances == Decimal('2.55'):
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 17)
return chances, Decimal('0.45')
if not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 17)
return chances, Decimal('0.45')
if chances == Decimal('2.6'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 13)
return chances, Decimal('1.4')
if not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 13)
return chances, Decimal('1.4')
if chances == Decimal('2.7'):
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 18)
return chances, Decimal('0.3')
if not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 18)
return chances, Decimal('0.3')
if not self.seven.is_full():
self.seven.assign_play(play, secondary_play, 9)
return chances, Decimal('3.3')
if chances == Decimal('2.75'):
if not self.six.is_full():
self.six.assign_play(play, secondary_play, 11)
return chances, Decimal('2.25')
if not self.eight.is_full():
self.eight.assign_play(play, secondary_play, 11)
return chances, Decimal('2.25')
if chances == Decimal('2.8'):
if not self.five.is_full():
self.five.assign_play(play, secondary_play, 14)
return chances, Decimal('1.2')
if not self.nine.is_full():
self.nine.assign_play(play, secondary_play, 14)
return chances, Decimal('1.2')
if chances == Decimal('2.85'):
if not self.four.is_full():
self.four.assign_play(play, secondary_play, 19)
return chances, Decimal('0.15')
if not self.ten.is_full():
self.ten.assign_play(play, secondary_play, 19)
return chances, Decimal('0.15')
else:
logging.info(f'Chances is less than 1')
return False
self.num_splits -= 1
else:
logging.info(f'Not a whole number and not in Exact Chances! Trying to add a subset')
for x in EXACT_CHANCES:
if x < chances and ((chances - x) == round(chances - x)):
logging.info(f'Trying to add {x} chances')
return self.add_result(play, alt_direction, x, secondary_play)
logging.info(f'Could not find a valid match')
return False
def total_chances(self):
total = 0
total += 1 if self.two.is_full() else 0
total += 2 if self.three.is_full() else 0
total += 3 if self.four.is_full() else 0
total += 4 if self.five.is_full() else 0
total += 5 if self.six.is_full() else 0
total += 6 if self.seven.is_full() else 0
total += 5 if self.eight.is_full() else 0
total += 4 if self.nine.is_full() else 0
total += 3 if self.ten.is_full() else 0
total += 2 if self.eleven.is_full() else 0
total += 1 if self.twelve.is_full() else 0
return total
def add_fatigue(self, num_chances: int, k_only: bool = False):
def is_valid_result(this_result: CardResult):
if k_only:
if this_result.result_one == 'strikeout':
return True
else:
return False
else:
if this_result.result_two is None and not this_result.bold_one and 'X' not in this_result.result_one:
return True
return False
if num_chances == 6:
if is_valid_result(self.seven):
self.seven.result_one += ''
return 6
elif num_chances == 5:
if is_valid_result(self.six):
self.six.result_one += ''
return 5
if is_valid_result(self.eight):
self.eight.result_one += ''
return 5
elif num_chances == 4:
if is_valid_result(self.five):
self.five.result_one += ''
return 4
if is_valid_result(self.nine):
self.nine.result_one += ''
return 4
return 0
class FullCard(pydantic.BaseModel):
col_one: CardColumn = CardColumn()
col_two: CardColumn = CardColumn()
col_three: CardColumn = CardColumn()
offense_col: int
alt_direction: int = 1
num_plusgb: int = 0
num_lomax: int = 0
is_batter: bool = False
class Config:
arbitrary_types_allowed = True
def get_columns(self, is_offense: bool):
if is_offense:
if self.offense_col == 1:
first = self.col_one
if self.alt_direction:
second = self.col_two
third = self.col_three
else:
second = self.col_three
third = self.col_two
elif self.offense_col == 2:
first = self.col_two
if self.alt_direction:
second = self.col_three
third = self.col_one
else:
second = self.col_one
third = self.col_three
else:
first = self.col_three
if self.alt_direction:
second = self.col_one
third = self.col_two
else:
second = self.col_two
third = self.col_one
else:
if self.offense_col == 1:
third = self.col_one
if self.alt_direction:
first = self.col_two
second = self.col_three
else:
first = self.col_three
second = self.col_two
elif self.offense_col == 2:
third = self.col_two
if self.alt_direction:
first = self.col_three
second = self.col_one
else:
first = self.col_one
second = self.col_three
else:
third = self.col_three
if self.alt_direction:
first = self.col_one
second = self.col_two
else:
first = self.col_two
second = self.col_one
return first, second, third
def is_complete(self):
return self.col_one.is_full() and self.col_two.is_full() and self.col_three.is_full()
def sample_output(self):
return f'{"" if self.is_complete() else "NOT "}COMPLETE\n' \
f'Column 1\n{self.col_one}\n\n' \
f'Column 2\n{self.col_two}\n\n' \
f'Column 3\n{self.col_three}'
def add_result(self, play: PlayResult, chances: Decimal, secondary_play: Optional[PlayResult] = None):
first, second, third = self.get_columns(is_offense=play.is_offense)
if 'gb' in play.full_name and chances + self.num_plusgb <= 6 and self.is_batter:
play.full_name += '+'
for x in [first, second, third]:
r_data = x.add_result(play, self.alt_direction, chances, secondary_play)
if r_data:
if '+' in play.full_name:
self.num_plusgb += r_data[0]
elif 'max' in play.full_name:
self.num_lomax += r_data[0]
return r_data
return False
def card_fill(self, play: PlayResult):
for x in range(6, 0, -1):
r_data = self.add_result(play, Decimal(x))
if r_data:
return r_data
return 0, 0
def card_output(self):
c1_output = self.col_one.get_text()
c2_output = self.col_two.get_text()
c3_output = self.col_three.get_text()
return {
'one_2d6': c1_output['sixes'],
'one_results': c1_output['results'],
'one_d20': c1_output['d20'],
'two_2d6': c2_output['sixes'],
'two_results': c2_output['results'],
'two_d20': c2_output['d20'],
'three_2d6': c3_output['sixes'],
'three_results': c3_output['results'],
'three_d20': c3_output['d20']
}
def total_chances(self):
return self.col_one.total_chances() + self.col_two.total_chances() + self.col_three.total_chances()
def add_fatigue(self):
first, second, third = self.get_columns(is_offense=False)
total_added = 0
for x in [first, second, third]:
resp = x.add_fatigue(6, k_only=True)
if resp:
total_added += resp
break
if total_added == 0:
for x in [first, second, third]:
resp = x.add_fatigue(6, k_only=False)
if resp:
total_added += resp
break
if total_added == 0:
for x in [first, second, third]:
resp = x.add_fatigue(5, k_only=True)
if resp:
total_added += resp
break
if total_added == 0:
for x in [first, second, third]:
resp = x.add_fatigue(5, k_only=False)
if resp:
total_added += resp
break
if total_added != 10:
for x in [first, second, third]:
resp = x.add_fatigue(10 - total_added, k_only=True)
if resp:
total_added += resp
break
if total_added != 10:
for x in [first, second, third]:
resp = x.add_fatigue(10 - total_added, k_only=False)
if resp:
total_added += resp
break
if total_added != 10:
logging.error(f'FullCard add_fatigue - Could not add all fatigue results / total_added: {total_added}')
class FullBattingCard(FullCard):
ratings: BattingCardRatingsModel
is_batter: bool = True
class FullPitchingCard(FullCard):
ratings: PitchingCardRatingsModel
is_batter: bool = False
def get_pos_data(all_pos, is_pitcher: bool = False) -> dict:
final = ''
arm_added = False
first = True
for x in all_pos:
if not first:
final += ', '
first = False
if is_pitcher:
if x.position == 'P':
final += f'p-{x.range}e{x.error}'
else:
if x.position != 'P':
final += x.position.lower()
if x.position != 'DH':
final += f'-{x.range}'
if x.position in ['LF', 'CF', 'RF', 'C'] and not arm_added:
final += f'({"+" if x.arm >= 0 else ""}{x.arm})'
arm_added = True
final += f'e{x.error}'
if x.position == 'C':
final += f' T-{x.overthrow}(pb {x.pb})'
if len(final) >= 50:
font = 16
margin = 5
elif len(final) >= 46:
font = 18
margin = 3
elif len(final) >= 40:
font = 20
margin = 1
elif len(final) >= 35:
font = 22
margin = -1
elif len(final) >= 30:
font = 24
margin = -2
else:
font = 26
margin = -3
return {'string': final, 'font': font, 'margin': margin}
def full_log(this_ratings, this_card, info=False):
if info:
logging.info(
f'Rating Chances: {this_ratings.total_chances()} / Card Chances: {this_card.total_chances()}\n'
f'{this_card.sample_output()}\n'
)
else:
logging.debug(
f'Rating Chances: {this_ratings.total_chances()} / Card Chances: {this_card.total_chances()}\n'
f'{this_card.sample_output()}\n'
)
def get_chances(total_chances, apply_limits=True):
if total_chances > 12.5 and apply_limits:
return 6
elif total_chances > 10.5 and apply_limits:
return 5
elif total_chances > 8.5 and apply_limits:
return 4
elif total_chances > 5.5 and apply_limits:
return 3
else:
return min(total_chances, 6)
def get_batter_card_data(player, batting_card, ratings_vl, ratings_vr, positions) -> dict:
player_binary = batting_card.player_id % 2
logging.info(f'\n\nRunning Card for {player.p_name}')
steal_string = '-/- (---)'
if batting_card.steal_jump > 0:
jump_chances = round(batting_card.steal_jump * 36)
if jump_chances == 6:
good_jump = 7
elif jump_chances == 5:
good_jump = 6
elif jump_chances == 4:
good_jump = 5
elif jump_chances == 3:
good_jump = 4
elif jump_chances == 2:
good_jump = 3
elif jump_chances == 1:
good_jump = 2
elif jump_chances == 7:
good_jump = '4,5'
elif jump_chances == 8:
good_jump = '4,6'
elif jump_chances == 9:
good_jump = '3-5'
elif jump_chances == 10:
good_jump = '2-5'
elif jump_chances == 11:
good_jump = '6,7'
elif jump_chances == 12:
good_jump = '4-6'
elif jump_chances == 13:
good_jump = '2,4-6'
elif jump_chances == 14:
good_jump = '3-6'
elif jump_chances == 15:
good_jump = '2-6'
elif jump_chances == 16:
good_jump = '2,5-6'
elif jump_chances == 17:
good_jump = '3,5-6'
elif jump_chances == 18:
good_jump = '4-6'
elif jump_chances == 19:
good_jump = '2,4-7'
elif jump_chances == 20:
good_jump = '3-7'
elif jump_chances == 21:
good_jump = '2-7'
elif jump_chances == 22:
good_jump = '2-7,12'
elif jump_chances == 23:
good_jump = '2-7,11'
elif jump_chances == 24:
good_jump = '2,4-8'
elif jump_chances == 25:
good_jump = '3-8'
elif jump_chances == 26:
good_jump = '2-8'
elif jump_chances == 27:
good_jump = '2-8,12'
elif jump_chances == 28:
good_jump = '2-8,11'
elif jump_chances == 29:
good_jump = '3-9'
elif jump_chances == 30:
good_jump = '2-9'
elif jump_chances == 31:
good_jump = '2-9,12'
elif jump_chances == 32:
good_jump = '2-9,11'
elif jump_chances == 33:
good_jump = '2-10'
elif jump_chances == 34:
good_jump = '3-11'
elif jump_chances == 35:
good_jump = '2-11'
else:
good_jump = '2-12'
steal_string = f'{"*" if batting_card.steal_auto else ""}{good_jump}/- ({batting_card.steal_high}-' \
f'{batting_card.steal_low})'
rarity_file = encoded_images[player.rarity.name]
vl_dict = model_to_dict(ratings_vl)
vl_dict['battingcard'] = ratings_vl.battingcard_id
vl_ratings = BattingCardRatingsModel(**vl_dict)
vl = FullBattingCard(
ratings=vl_ratings,
offense_col=batting_card.offense_col,
alt_direction=player_binary
)
vr_dict = model_to_dict(ratings_vr)
vr_dict['battingcard'] = ratings_vr.battingcard_id
vr_ratings = BattingCardRatingsModel(**vr_dict)
vr = FullBattingCard(
ratings=vr_ratings,
offense_col=batting_card.offense_col,
alt_direction=player_binary
)
def assign_bchances(
this_card: FullBattingCard, play: PlayResult, chances: Decimal,
secondary_play: Optional[PlayResult] = None):
logging.info(f'Assign batting chances\n{play}\nChances: {chances}\nBackup: {secondary_play}')
r_data = this_card.add_result(play, chances, secondary_play)
if r_data:
return r_data
else:
logging.warning(f'Could not find valid column trying new values')
for x in EXACT_CHANCES:
if x < math.floor(chances):
logging.warning(f'Using the whole number {math.floor(chances)}')
r_data = this_card.add_result(play, Decimal(math.floor(chances)), secondary_play)
if r_data:
return r_data
else:
logging.error(f'Whole number was no good')
break
if x < chances:
logging.warning(f'Trying {x} chances now')
r_data = this_card.add_result(play, x, secondary_play)
if r_data:
return r_data
else:
logging.warning(f'No good; checking the next value')
logging.error('Could not assign chances\n')
logging.debug(f'vl: {vl.sample_output()}')
logging.debug(f'vr: {vr.sample_output()}')
return 0, 0
def get_pullside_of():
if batting_card.hand == 'L':
return 'rf'
elif batting_card.hand == 'R':
return 'lf'
elif data.vs_hand == 'L':
return 'lf'
else:
return 'rf'
def get_preferred_mif(ratings):
if batting_card.hand == 'L' and ratings.slap_rate > .24:
return 'ss'
elif batting_card.hand == 'L' or (batting_card.hand == 'R' and ratings.slap_rate > .24):
return '2b'
else:
return 'ss'
new_battingratings = []
for card, data, new_ratings in [
(vl, copy.deepcopy(vl_ratings), BattingCardRatingsModel(
battingcard=vl_ratings.battingcard, pull_rate=vl_ratings.pull_rate, center_rate=vl_ratings.center_rate,
slap_rate=vl_ratings.slap_rate, vs_hand='L')),
(vr, copy.deepcopy(vr_ratings), BattingCardRatingsModel(
battingcard=vr_ratings.battingcard, pull_rate=vr_ratings.pull_rate, center_rate=vr_ratings.center_rate,
slap_rate=vr_ratings.slap_rate, vs_hand='R'))]:
logging.info(f'\n\nBeginning v{data.vs_hand}')
pull_of = get_pullside_of()
pref_mif = get_preferred_mif(data)
res_chances = data.bp_homerun
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_bchances(card, PLAY_RESULTS['bp-hr'], ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.bp_homerun += r_val[0]
full_log(new_ratings, card)
retries = 0
res_chances = data.hbp
while res_chances > 0:
if res_chances < 1 or retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_bchances(card, PlayResult(full_name='HBP', short_name='HBP'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.hbp += r_val[0]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.homerun
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.double_pull > 0:
data.double_pull += res_chances
elif data.double_two > 0:
data.double_two += res_chances
elif data.triple > 0:
data.triple += res_chances
elif data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_center > 0:
data.single_center += res_chances
break
ch = get_chances(res_chances)
if data.double_pull > (data.flyout_rf_b + data.flyout_lf_b) and data.double_pull > max(1 - ch, 0):
secondary = PLAY_RESULTS[f'do-{pull_of}']
elif data.flyout_lf_b > data.flyout_rf_b and data.flyout_lf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-lf']
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-rf']
elif data.double_pull > max(1 - ch, 0):
secondary = PLAY_RESULTS[f'do-{pull_of}']
elif data.double_three > max(1 - ch, 0):
secondary = PLAY_RESULTS['do***']
elif data.double_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['do**']
elif data.triple > max(1 - ch, 0):
secondary = PLAY_RESULTS['tr']
else:
secondary = None
r_val = assign_bchances(card, PLAY_RESULTS['hr'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.homerun += r_val[0]
if r_val[1] > 0:
if secondary.short_name[:4] == 'DO (':
data.double_pull -= r_val[1]
new_ratings.double_pull += r_val[1]
elif 'lf' in secondary.short_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'rf' in secondary.short_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif '***' in secondary.short_name:
data.double_three -= r_val[1]
new_ratings.double_three += r_val[1]
elif '**' in secondary.short_name:
data.double_two -= r_val[1]
new_ratings.double_two += r_val[1]
elif 'TR' in secondary.short_name:
data.triple -= r_val[1]
new_ratings.triple += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.triple
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.double_pull > 0:
data.double_pull += res_chances
elif data.double_two > 0:
data.double_two += res_chances
elif data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
break
ch = get_chances(res_chances)
if data.single_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['si**']
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-lf']
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-rf']
elif data.double_pull > max(1 - ch, 0):
secondary = PLAY_RESULTS[f'do-{pull_of}']
elif data.double_three > max(1 - ch, 0):
secondary = PLAY_RESULTS['do***']
elif data.double_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['do**']
else:
secondary = None
r_val = assign_bchances(card, PLAY_RESULTS['tr'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.triple += r_val[0]
if r_val[1] > 0:
if 'DO (' in secondary.short_name:
data.double_pull -= r_val[1]
new_ratings.double_pull += r_val[1]
elif 'lf' in secondary.short_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'rf' in secondary.short_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif '***' in secondary.short_name:
data.double_three -= r_val[1]
new_ratings.double_three += r_val[1]
elif 'SI' in secondary.short_name:
data.single_two -= r_val[1]
new_ratings.single_two += r_val[1]
elif '**' in secondary.short_name:
data.double_two -= r_val[1]
new_ratings.double_two += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.double_three
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.double_pull > 0:
data.double_pull += res_chances
elif data.double_two > 0:
data.double_two += res_chances
elif data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
break
ch = get_chances(res_chances)
if data.single_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['si**']
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-lf']
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-rf']
elif data.double_pull > max(1 - ch, 0):
secondary = PLAY_RESULTS[f'do-{pull_of}']
elif data.double_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['do**']
else:
secondary = None
r_val = assign_bchances(card, PLAY_RESULTS['do***'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.double_three += r_val[0]
if r_val[1] > 0:
if 'DO (' in secondary.short_name:
data.double_pull -= r_val[1]
new_ratings.double_pull += r_val[1]
elif 'lf' in secondary.short_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'rf' in secondary.short_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif 'SI' in secondary.short_name:
data.single_two -= r_val[1]
new_ratings.single_two += r_val[1]
elif '**' in secondary.short_name:
data.double_two -= r_val[1]
new_ratings.double_two += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.double_pull
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.double_two > 0:
data.double_two += res_chances
elif data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
break
ch = get_chances(res_chances)
if data.flyout_lf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (lf) B', short_name=f'fly B')
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (rf) B', short_name=f'fly b')
elif data.single_one > max(1 - ch, 0):
secondary = PLAY_RESULTS['si*']
elif data.single_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['si**']
else:
secondary = None
r_val = assign_bchances(card, PLAY_RESULTS[f'do-{pull_of}'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.double_pull += r_val[0]
if r_val[1] > 0:
if 'lf' in secondary.full_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'rf' in secondary.full_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif '***' in secondary.short_name:
data.double_three -= r_val[1]
new_ratings.double_three += r_val[1]
elif 'SI' in secondary.short_name:
data.single_two -= r_val[1]
new_ratings.single_two += r_val[1]
elif '**' in secondary.short_name:
data.double_two -= r_val[1]
new_ratings.double_two += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.double_two
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
elif data.walk > 0:
data.walk += res_chances
break
ch = get_chances(res_chances)
if data.single_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['si**']
elif data.single_center > max(1 - ch, 0):
secondary = PLAY_RESULTS['si-cf']
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-lf']
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-rf']
else:
secondary = None
r_val = assign_bchances(card, PLAY_RESULTS['do**'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.double_two += r_val[0]
if r_val[1] > 0:
if 'lf' in secondary.full_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'rf' in secondary.full_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif 'SI' in secondary.short_name:
data.single_two -= r_val[1]
new_ratings.single_two += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.single_two
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
elif data.walk > 0:
data.walk += res_chances
break
ch = get_chances(res_chances)
if data.groundout_a > max(1 - ch, 0):
secondary = PlayResult(full_name=f'gb ({pref_mif}) A', short_name=f'gb ({pref_mif}) A')
elif data.groundout_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'gb ({pref_mif}) B', short_name=f'gb ({pref_mif}) B')
elif data.groundout_c > max(1 - ch, 0):
secondary = PlayResult(full_name=f'gb ({pref_mif}) C', short_name=f'gb ({pref_mif}) C')
elif data.lineout > max(1 - ch, 0):
secondary = PlayResult(full_name=f'lo ({pref_mif})', short_name=f'lo ({pref_mif})')
else:
secondary = None
r_val = assign_bchances(card, PLAY_RESULTS['si**'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.single_two += r_val[0]
if r_val[1] > 0:
if 'C' in secondary.short_name:
data.groundout_c -= r_val[1]
new_ratings.groundout_c += r_val[1]
elif 'B' in secondary.short_name:
data.groundout_b -= r_val[1]
new_ratings.groundout_b += r_val[1]
elif 'A' in secondary.short_name:
data.groundout_a -= r_val[1]
new_ratings.groundout_a += r_val[1]
elif 'lo' in secondary.short_name:
data.lineout -= r_val[1]
new_ratings.lineout += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.single_center
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.single_one > 0:
data.single_one += res_chances
elif data.walk > 0:
data.walk += res_chances
break
ch = get_chances(res_chances)
if data.flyout_bq > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly B?', short_name=f'fly B?')
elif data.flyout_lf_b > max(1 - ch, 0) and data.flyout_lf_b > data.flyout_rf_b:
secondary = PlayResult(full_name=f'fly (LF) B', short_name=f'fly B')
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (RF) B', short_name=f'fly B')
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (LF) B', short_name=f'fly B')
elif data.lineout > max(1 - ch, 0):
secondary = PlayResult(full_name=f'lo ({pref_mif})', short_name=f'lo ({pref_mif})')
else:
secondary = None
r_val = assign_bchances(card, PLAY_RESULTS['si-cf'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.single_center += r_val[0]
if r_val[1] > 0:
if '?' in secondary.short_name:
data.flyout_bq -= r_val[1]
new_ratings.flyout_bq += r_val[1]
elif 'LF' in secondary.full_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'RF' in secondary.full_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif 'lo' in secondary.short_name:
data.lineout -= r_val[1]
new_ratings.lineout += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.single_one
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.walk > 0:
data.walk += res_chances
break
ch = get_chances(res_chances)
if data.groundout_c > max(1 - ch, 0):
secondary = PlayResult(full_name=f'gb ({pref_mif}) C', short_name=f'gb ({pref_mif}) C')
elif data.groundout_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'gb ({pref_mif}) B', short_name=f'gb ({pref_mif}) B')
elif data.groundout_a > max(1 - ch, 0):
secondary = PlayResult(full_name=f'gb ({pref_mif}) A', short_name=f'gb ({pref_mif}) A')
elif data.lineout > max(1 - ch, 0):
secondary = PlayResult(full_name=f'lo ({pref_mif})', short_name=f'lo ({pref_mif})')
else:
secondary = None
r_val = assign_bchances(card, PLAY_RESULTS['si*'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.single_one += r_val[0]
if r_val[1] > 0:
if 'C' in secondary.short_name:
data.groundout_c -= r_val[1]
new_ratings.groundout_c += r_val[1]
elif 'B' in secondary.short_name:
data.groundout_b -= r_val[1]
new_ratings.groundout_b += r_val[1]
elif 'A' in secondary.short_name:
data.groundout_a -= r_val[1]
new_ratings.groundout_a += r_val[1]
elif 'lo' in secondary.short_name:
data.lineout -= r_val[1]
new_ratings.lineout += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.walk
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
ch = get_chances(res_chances)
if data.strikeout > max(1 - ch, 0):
secondary = PlayResult(full_name=f'strikeout', short_name=f'so')
else:
secondary = None
r_val = assign_bchances(card, PLAY_RESULTS['walk'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.walk += r_val[0]
if r_val[1] > 0:
data.strikeout -= r_val[1]
new_ratings.strikeout += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card)
retries = 0
res_chances = data.bp_single
while res_chances > 0:
if res_chances < 1 or retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_bchances(card, PLAY_RESULTS['bp-si'], ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.bp_single += r_val[0]
if r_val[0] == 0:
retries += 1
# Special lomax result
full_log(new_ratings, card)
r_val = assign_bchances(
card, PlayResult(full_name=f'lo ({pref_mif}) max', short_name=f'lo ({pref_mif}) max'), Decimal(1))
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
data.lineout -= r_val[0]
new_ratings.lineout += r_val[0]
full_log(new_ratings, card)
retries = 0
res_chances = data.popout
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
ch = get_chances(res_chances)
this_if = '2b' if pref_mif == 'ss' else 'ss'
r_val = assign_bchances(
card,
PlayResult(full_name=f'popout ({this_if})', short_name=f'popout ({this_if})'),
Decimal(math.floor(ch))
)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if r_val[0] == 0:
data.lineout += res_chances
break
else:
res_chances -= r_val[0]
new_ratings.popout += r_val[0]
full_log(new_ratings, card)
retries = 0
res_chances = data.flyout_a
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_bchances(
card, PlayResult(full_name=f'fly (cf) A', short_name=f'fly (cf) A'), Decimal(math.floor(ch)))
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if r_val[0] == 0:
data.strikeout += res_chances if data.strikeout > 2 else 0
break
else:
res_chances -= r_val[0]
new_ratings.flyout_a += r_val[0]
full_log(new_ratings, card)
retries = 0
res_chances = data.flyout_lf_b
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_bchances(
card, PlayResult(full_name=f'fly (lf) B', short_name=f'fly (lf) B'), Decimal(math.floor(ch)))
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if r_val[0] == 0:
data.strikeout += res_chances if data.strikeout > 2 else 0
break
else:
res_chances -= r_val[0]
new_ratings.flyout_lf_b += r_val[0]
full_log(new_ratings, card)
retries = 0
res_chances = data.flyout_rf_b
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_bchances(
card, PlayResult(full_name=f'fly (rf) B', short_name=f'fly (rf) B'), Decimal(math.floor(ch)))
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if r_val[0] == 0:
data.strikeout += res_chances if data.strikeout > 2 else 0
break
else:
res_chances -= r_val[0]
new_ratings.flyout_rf_b += r_val[0]
count_gb = 0
def get_gb_if():
if count_gb % 4 == 1:
return pref_mif
elif count_gb % 4 == 2:
return '2b' if pref_mif == 'ss' else 'ss'
elif count_gb % 4 == 3:
return '1b' if pref_mif == '2b' else 'p'
else:
return '3b' if pref_mif == 'ss' else 'p'
full_log(new_ratings, card)
retries = 0
res_chances = data.groundout_a
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
count_gb += 1
this_if = get_gb_if()
ch = get_chances(res_chances)
r_val = assign_bchances(
card, PlayResult(full_name=f'gb ({this_if}) A', short_name=f'gb ({this_if}) A'),
Decimal(math.floor(ch)))
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if r_val[0] == 0:
data.groundout_b += res_chances
break
else:
res_chances -= r_val[0]
new_ratings.groundout_a += r_val[0]
full_log(new_ratings, card)
retries = 0
res_chances = data.groundout_b
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
count_gb += 1
this_if = get_gb_if()
ch = get_chances(res_chances)
r_val = assign_bchances(
card, PlayResult(full_name=f'gb ({this_if}) B', short_name=f'gb ({this_if}) B'),
Decimal(math.floor(ch)))
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if r_val[0] == 0:
data.groundout_c += res_chances
break
else:
res_chances -= r_val[0]
new_ratings.groundout_b += r_val[0]
full_log(new_ratings, card)
retries = 0
res_chances = data.groundout_c
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
count_gb += 1
this_if = get_gb_if()
ch = get_chances(res_chances)
r_val = assign_bchances(
card, PlayResult(full_name=f'gb ({this_if}) C', short_name=f'gb ({this_if}) C'),
Decimal(math.floor(ch)))
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if r_val[0] == 0:
data.strikeout += res_chances
break
else:
res_chances -= r_val[0]
new_ratings.groundout_c += r_val[0]
full_log(new_ratings, card)
retries = 0
res_chances = data.lineout
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
ch = get_chances(res_chances)
this_if = '3b' if pref_mif == 'ss' else '1b'
r_val = assign_bchances(
card,
PlayResult(full_name=f'lineout ({this_if})', short_name=f'lineout ({this_if})'),
Decimal(math.floor(ch))
)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if r_val[0] == 0:
break
else:
res_chances -= r_val[0]
new_ratings.lineout += r_val[0]
full_log(new_ratings, card)
retries = 0
res_chances = data.strikeout
while res_chances >= 1:
if res_chances < 1 or retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_bchances(
card, PlayResult(full_name=f'strikeout', short_name=f'strikeout'), Decimal(math.floor(ch)))
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if r_val[0] == 0:
break
else:
res_chances -= r_val[0]
new_ratings.strikeout += r_val[0]
log_data = vl.sample_output() if data.vs_hand == 'L' else vr.sample_output()
logging.info(f'Pre-filler total chances: {new_ratings.total_chances()}\n{log_data}')
plays = sorted(
[(data.strikeout, 'so'), (data.lineout, 'lo'), (data.groundout_c, 'gb'), (data.popout, 'po')],
key=lambda z: z[0],
reverse=True
)
count_filler = -1
while not card.is_complete():
count_filler += 1
this_play = plays[count_filler % 4]
if this_play[1] == 'so':
play_res = PlayResult(full_name=f'strikeout', short_name=f'strikeout')
elif this_play[1] == 'lo':
this_if = '3b' if pref_mif == 'ss' else '1b'
play_res = PlayResult(full_name=f'lineout ({this_if})', short_name=f'lineout ({this_if})')
elif this_play[1] == 'gb':
count_gb += 1
this_if = get_gb_if()
play_res = PlayResult(full_name=f'gb ({this_if}) C', short_name=f'gb ({this_if}) C')
else:
play_res = PlayResult(full_name=f'popout (c)', short_name=f'popout (c)')
logging.info(f'Send Card Fill\n{play_res}')
r_val = card.card_fill(play_res)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if this_play[1] == 'so':
new_ratings.strikeout += r_val[0]
elif this_play[1] == 'lo':
new_ratings.lineout += r_val[0]
elif this_play[1] == 'gb':
new_ratings.groundout_c += r_val[0]
else:
new_ratings.popout += r_val[0]
full_log(new_ratings, card)
new_ratings.update_slash_lines()
new_battingratings.append(new_ratings)
vl_output = vl.card_output()
vr_output = vr.card_output()
logging.info(f'vl: {vl.sample_output()}')
logging.info(f'vr: {vr.sample_output()}')
vl_total = new_battingratings[0].total_chances()
vr_total = new_battingratings[1].total_chances()
logging.info(f'New Ratings\nTotal Chances:\n{vl_total}\n{new_battingratings[0]}\n\n'
f'Total Chances: {vr_total}\n{new_battingratings[1]}')
if vl_total + vr_total != Decimal(216):
raise ValueError(f'vl chances: {vl_total} / vr chances: {vr_total}')
pos_data = get_pos_data(positions)
return {
'player': player,
'card_type': 'batter',
# 'vl_one_2d6': '<b>2-</b>',
# 'vl_one_results': '<b>HOMERUN</b>',
# 'vl_one_d20': '<b> </b>',
# 'vl_two_2d6': '2-',
# 'vl_two_results': 'fly (cf) B',
# 'vl_two_d20': '',
# 'vl_three_2d6': '<b>2-</b><br>&nbsp;',
# 'vl_three_results': '<b>HR</b><br>fly (cf) B',
# 'vl_three_d20': '<b>1-16</b><br>17-20',
# 'results_vr_one': 'Light Dongs',
# 'results_vr_two': 'Hefty Dongs',
# 'results_vr_three': 'Obese Dongs',
'vl_one_2d6': vl_output['one_2d6'],
'vl_one_results': vl_output['one_results'],
'vl_one_d20': vl_output['one_d20'],
'vl_two_2d6': vl_output['two_2d6'],
'vl_two_results': vl_output['two_results'],
'vl_two_d20': vl_output['two_d20'],
'vl_three_2d6': vl_output['three_2d6'],
'vl_three_results': vl_output['three_results'],
'vl_three_d20': vl_output['three_d20'],
'vr_one_2d6': vr_output['one_2d6'],
'vr_one_results': vr_output['one_results'],
'vr_one_d20': vr_output['one_d20'],
'vr_two_2d6': vr_output['two_2d6'],
'vr_two_results': vr_output['two_results'],
'vr_two_d20': vr_output['two_d20'],
'vr_three_2d6': vr_output['three_2d6'],
'vr_three_results': vr_output['three_results'],
'vr_three_d20': vr_output['three_d20'],
'hand': batting_card.hand,
'bat_card': batting_card,
'stealing_string': steal_string,
'rarity_file': rarity_file,
'new_ratings_vl': new_battingratings[0],
'new_ratings_vr': new_battingratings[1],
'position_string': pos_data['string'],
'position_font': pos_data['font'],
'position_margin': pos_data['margin']
}
def get_pitcher_card_data(player, pitching_card, ratings_vl, ratings_vr, positions) -> dict:
player_binary = pitching_card.player_id % 2
logging.info(f'\n\nRunning Card for {player.p_name}')
rarity_file = encoded_images[player.rarity.name]
vl_dict = model_to_dict(ratings_vl)
vl_dict['pitchingcard'] = ratings_vl.pitchingcard_id
vl_ratings = PitchingCardRatingsModel(**vl_dict)
vl = FullPitchingCard(
ratings=vl_ratings,
offense_col=pitching_card.offense_col,
alt_direction=player_binary
)
vr_dict = model_to_dict(ratings_vr)
vr_dict['pitchingcard'] = ratings_vr.pitchingcard_id
vr_ratings = PitchingCardRatingsModel(**vr_dict)
vr = FullPitchingCard(
ratings=vr_ratings,
offense_col=pitching_card.offense_col,
alt_direction=player_binary
)
def assign_pchances(
this_card: FullPitchingCard, play: PlayResult, chances: Decimal,
secondary_play: Optional[PlayResult] = None):
logging.info(f'Assign pitching chances\n{play}\nChances: {chances}\nBackup: {secondary_play}')
r_data = this_card.add_result(play, chances, secondary_play)
if r_data:
return r_data
else:
logging.warning(f'Could not find valid column trying new values')
for x in EXACT_CHANCES + [Decimal('0.95')]:
if x < math.floor(chances - Decimal('0.05')):
logging.warning(f'Using the whole number {math.floor(chances)}')
r_data = this_card.add_result(play, Decimal(math.floor(chances)), secondary_play)
if r_data:
return r_data
else:
logging.error(f'Whole number was no good')
break
if x < chances and secondary_play is not None:
logging.warning(f'Trying {x} chances now')
r_data = this_card.add_result(play, x, secondary_play)
if r_data:
return r_data
else:
logging.warning(f'No good; checking the next value')
logging.error('Could not assign chances\n')
logging.debug(f'vl: {vl.sample_output()}')
logging.debug(f'vr: {vr.sample_output()}')
return 0, 0
def get_preferred_mif(ratings):
if pitching_card.hand == 'L' and ratings.vs_hand == 'L':
return 'ss'
elif pitching_card.hand == 'L' or (pitching_card.hand == 'R' and ratings.vs_hand == 'R'):
return '2b'
else:
return 'ss'
new_pitchingratings = []
for card, data, new_ratings in [
(vl, copy.deepcopy(vl_ratings), PitchingCardRatingsModel(
pitchingcard=vl_ratings.pitchingcard, vs_hand='L')),
(vr, copy.deepcopy(vr_ratings), PitchingCardRatingsModel(
pitchingcard=vr_ratings.pitchingcard, vs_hand='R'))]:
logging.info(f'\n\nBeginning v{data.vs_hand}')
res_chances = data.bp_homerun
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PLAY_RESULTS['bp-hr'], ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.bp_homerun += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.hbp
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name='HBP', short_name='HBP'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.hbp += r_val[0]
if r_val[0] == 0:
break
full_log(new_ratings, card, info=True)
res_chances = data.xcheck_p
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'gb (p) X', short_name=f'gb (p) X'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.xcheck_p += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.xcheck_c
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'catch X', short_name=f'catch X'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.xcheck_c += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.xcheck_1b
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'gb (1b) X', short_name=f'gb (1b) X'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.xcheck_1b += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.xcheck_3b
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'gb (3b) X', short_name=f'gb (3b) X'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.xcheck_3b += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.xcheck_rf
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'fly (rf) X', short_name=f'fly (rf) X'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.xcheck_rf += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.xcheck_lf
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'fly (lf) X', short_name=f'fly (lf) X'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.xcheck_lf += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.xcheck_2b
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'gb (2b) X', short_name=f'gb (2b) X'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.xcheck_2b += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.xcheck_cf
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'fly (cf) X', short_name=f'fly (cf) X'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.xcheck_cf += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.xcheck_ss
while res_chances > 0:
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'gb (ss) X', short_name=f'gb (ss) X'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.xcheck_ss += r_val[0]
full_log(new_ratings, card, info=True)
res_chances = data.walk
while res_chances >= 1:
ch = get_chances(res_chances)
if data.strikeout > max(1 - ch, 0):
secondary = PlayResult(full_name=f'strikeout', short_name=f'so')
else:
secondary = None
r_val = assign_pchances(card, PLAY_RESULTS['walk'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.walk += r_val[0]
if r_val[1] > 0:
data.strikeout -= r_val[1]
new_ratings.strikeout += r_val[1]
if r_val[0] == 0:
break
full_log(new_ratings, card, info=True)
res_chances = data.homerun
retries = 0
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.double_cf > 0:
data.double_cf += res_chances
elif data.double_two > 0:
data.double_two += res_chances
elif data.triple > 0:
data.triple += res_chances
elif data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_center > 0:
data.single_center += res_chances
break
ch = get_chances(res_chances)
if data.double_cf > (data.flyout_rf_b + data.flyout_lf_b) and data.double_cf > max(1 - ch, 0):
secondary = PLAY_RESULTS[f'do-cf']
elif data.flyout_cf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-cf']
elif data.flyout_lf_b > data.flyout_rf_b and data.flyout_lf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-lf']
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-rf']
elif data.double_cf > max(1 - ch, 0):
secondary = PLAY_RESULTS[f'do-cf']
elif data.double_three > max(1 - ch, 0):
secondary = PLAY_RESULTS['do***']
elif data.double_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['do**']
elif data.triple > max(1 - ch, 0):
secondary = PLAY_RESULTS['tr']
else:
secondary = None
r_val = assign_pchances(card, PLAY_RESULTS['hr'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.homerun += r_val[0]
if r_val[1] > 0:
if 'DO (' in secondary.short_name:
data.double_cf -= r_val[1]
new_ratings.double_cf += r_val[1]
elif 'lf' in secondary.short_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'cf' in secondary.short_name:
data.flyout_cf_b -= r_val[1]
new_ratings.flyout_cf_b += r_val[1]
elif 'rf' in secondary.short_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif '***' in secondary.short_name:
data.double_three -= r_val[1]
new_ratings.double_three += r_val[1]
elif '**' in secondary.short_name:
data.double_two -= r_val[1]
new_ratings.double_two += r_val[1]
elif 'TR' in secondary.short_name:
data.triple -= r_val[1]
new_ratings.triple += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.triple
retries = 0
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.double_cf > 0:
data.double_cf += res_chances
elif data.double_two > 0:
data.double_two += res_chances
elif data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
break
ch = get_chances(res_chances)
if data.single_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['si**']
elif data.flyout_cf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-cf']
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-lf']
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-rf']
elif data.double_cf > max(1 - ch, 0):
secondary = PLAY_RESULTS[f'do-cf']
elif data.double_three > max(1 - ch, 0):
secondary = PLAY_RESULTS['do***']
elif data.double_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['do**']
else:
secondary = None
r_val = assign_pchances(card, PLAY_RESULTS['tr'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.triple += r_val[0]
if r_val[1] > 0:
if 'DO (' in secondary.short_name:
data.double_cf -= r_val[1]
new_ratings.double_cf += r_val[1]
elif 'lf' in secondary.short_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'cf' in secondary.short_name:
data.flyout_cf_b -= r_val[1]
new_ratings.flyout_cf_b += r_val[1]
elif 'rf' in secondary.short_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif '***' in secondary.short_name:
data.double_three -= r_val[1]
new_ratings.double_three += r_val[1]
elif 'SI' in secondary.short_name:
data.single_two -= r_val[1]
new_ratings.single_two += r_val[1]
elif '**' in secondary.short_name:
data.double_two -= r_val[1]
new_ratings.double_two += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.double_three
retries = 0
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.double_cf > 0:
data.double_cf += res_chances
elif data.double_two > 0:
data.double_two += res_chances
elif data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
break
ch = get_chances(res_chances)
if data.single_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['si**']
elif data.flyout_cf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-cf']
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-lf']
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-rf']
elif data.double_cf > max(1 - ch, 0):
secondary = PLAY_RESULTS[f'do-cf']
elif data.double_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['do**']
else:
secondary = None
r_val = assign_pchances(card, PLAY_RESULTS['do***'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.double_three += r_val[0]
if r_val[1] > 0:
if 'DO (' in secondary.short_name:
data.double_cf -= r_val[1]
new_ratings.double_cf += r_val[1]
elif 'lf' in secondary.short_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'cf' in secondary.short_name:
data.flyout_cf_b -= r_val[1]
new_ratings.flyout_cf_b += r_val[1]
elif 'rf' in secondary.short_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif 'SI' in secondary.short_name:
data.single_two -= r_val[1]
new_ratings.single_two += r_val[1]
elif '**' in secondary.short_name:
data.double_two -= r_val[1]
new_ratings.double_two += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.double_cf
retries = 0
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.double_two > 0:
data.double_two += res_chances
elif data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
break
ch = get_chances(res_chances)
if data.flyout_cf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (cf) B', short_name=f'fly B')
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (lf) B', short_name=f'fly B')
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (rf) B', short_name=f'fly b')
elif data.single_one > max(1 - ch, 0):
secondary = PLAY_RESULTS['si*']
elif data.single_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['si**']
else:
secondary = None
r_val = assign_pchances(card, PLAY_RESULTS[f'do-cf'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.double_cf += r_val[0]
if r_val[1] > 0:
if 'lf' in secondary.full_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'rf' in secondary.full_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif 'cf' in secondary.full_name:
data.flyout_cf_b -= r_val[1]
new_ratings.flyout_cf_b += r_val[1]
elif '***' in secondary.short_name:
data.double_three -= r_val[1]
new_ratings.double_three += r_val[1]
elif 'SI' in secondary.short_name:
data.single_two -= r_val[1]
new_ratings.single_two += r_val[1]
elif '**' in secondary.short_name:
data.double_two -= r_val[1]
new_ratings.double_two += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.double_two
retries = 0
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.single_two > 0:
data.single_two += res_chances
elif data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
elif data.walk > 0:
data.walk += res_chances
break
ch = get_chances(res_chances)
if data.single_two > max(1 - ch, 0):
secondary = PLAY_RESULTS['si**']
elif data.single_center > max(1 - ch, 0):
secondary = PLAY_RESULTS['si-cf']
elif data.flyout_cf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-cf']
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-lf']
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-rf']
else:
secondary = None
r_val = assign_pchances(card, PLAY_RESULTS['do**'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.double_two += r_val[0]
if r_val[1] > 0:
if 'lf' in secondary.full_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'rf' in secondary.full_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif 'cf' in secondary.full_name:
data.flyout_cf_b -= r_val[1]
new_ratings.flyout_cf_b += r_val[1]
elif 'SI' in secondary.short_name:
data.single_two -= r_val[1]
new_ratings.single_two += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.single_two
retries = 0
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.single_center > 0:
data.single_center += res_chances
elif data.single_one > 0:
data.single_one += res_chances
elif data.walk > 0:
data.walk += res_chances
break
pref_mif = get_preferred_mif(new_ratings)
ch = get_chances(res_chances)
if data.groundout_a > max(1 - ch, 0):
temp_mif = get_preferred_mif(new_ratings)
pref_mif = 'ss' if temp_mif == '2b' else '2b'
secondary = PlayResult(full_name=f'gb ({pref_mif}) A', short_name=f'gb ({pref_mif}) A')
elif data.groundout_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'gb ({pref_mif}) B', short_name=f'gb ({pref_mif}) B')
elif data.flyout_cf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-cf']
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-lf']
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PLAY_RESULTS['fly-rf']
else:
secondary = None
r_val = assign_pchances(card, PLAY_RESULTS['si**'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.single_two += r_val[0]
if r_val[1] > 0:
if 'B' in secondary.short_name:
data.groundout_b -= r_val[1]
new_ratings.groundout_b += r_val[1]
elif 'A' in secondary.short_name:
data.groundout_a -= r_val[1]
new_ratings.groundout_a += r_val[1]
elif 'lf' in secondary.full_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'rf' in secondary.full_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
elif 'cf' in secondary.full_name:
data.flyout_cf_b -= r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.single_center
retries = 0
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.single_one > 0:
data.single_one += res_chances
elif data.walk > 0:
data.walk += res_chances
break
ch = get_chances(res_chances)
if data.flyout_cf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (cf) B', short_name=f'fly B')
elif data.flyout_lf_b > max(1 - ch, 0) and data.flyout_lf_b > data.flyout_rf_b:
secondary = PlayResult(full_name=f'fly (lf) B', short_name=f'fly B')
elif data.flyout_rf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (rf) B', short_name=f'fly B')
elif data.flyout_lf_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'fly (lf) B', short_name=f'fly B')
else:
secondary = None
r_val = assign_pchances(card, PLAY_RESULTS['si-cf'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.single_center += r_val[0]
if r_val[1] > 0:
if 'CF' in secondary.short_name:
data.flyout_cf_b -= r_val[1]
new_ratings.flyout_cf_b += r_val[1]
elif 'LF' in secondary.full_name:
data.flyout_lf_b -= r_val[1]
new_ratings.flyout_lf_b += r_val[1]
elif 'RF' in secondary.full_name:
data.flyout_rf_b -= r_val[1]
new_ratings.flyout_rf_b += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.single_one
retries = 0
while res_chances > 0:
if res_chances < 1 or retries > 0:
if data.walk > 0:
data.walk += res_chances
break
pref_mif = get_preferred_mif(new_ratings)
ch = get_chances(res_chances)
if data.groundout_b > max(1 - ch, 0):
secondary = PlayResult(full_name=f'gb ({pref_mif}) B', short_name=f'gb ({pref_mif}) B')
elif data.groundout_a > max(1 - ch, 0):
temp_mif = get_preferred_mif(new_ratings)
pref_mif = 'ss' if temp_mif == '2b' else '2b'
secondary = PlayResult(full_name=f'gb ({pref_mif}) A', short_name=f'gb ({pref_mif}) A')
else:
secondary = None
r_val = assign_pchances(card, PLAY_RESULTS['si*'], ch, secondary)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.single_one += r_val[0]
if r_val[1] > 0:
if 'B' in secondary.short_name:
data.groundout_b -= r_val[1]
new_ratings.groundout_b += r_val[1]
elif 'A' in secondary.short_name:
data.groundout_a -= r_val[1]
new_ratings.groundout_a += r_val[1]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.bp_single
retries = 0
while res_chances > 0:
if retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_pchances(card, PLAY_RESULTS['bp-si'], ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.bp_single += r_val[0]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.strikeout
retries = 0
while res_chances > 0:
if retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_pchances(card, PlayResult(full_name=f'strikeout', short_name=f'so'), ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.strikeout += r_val[0]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.flyout_cf_b
retries = 0
while res_chances > 0:
if retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_pchances(card, PLAY_RESULTS['fly-cf'], ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.flyout_cf_b += r_val[0]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.flyout_lf_b
retries = 0
while res_chances > 0:
if retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_pchances(card, PLAY_RESULTS['fly-lf'], ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.flyout_lf_b += r_val[0]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.flyout_rf_b
retries = 0
while res_chances > 0:
if retries > 0:
break
ch = get_chances(res_chances)
r_val = assign_pchances(card, PLAY_RESULTS['fly-rf'], ch)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.flyout_rf_b += r_val[0]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.groundout_a
retries = 0
while res_chances > 0:
if retries > 0:
break
temp_mif = get_preferred_mif(new_ratings)
pref_mif = 'ss' if temp_mif == '2b' else '2b'
ch = get_chances(res_chances)
r_val = assign_pchances(
card,
PlayResult(full_name=f'gb ({pref_mif}) A', short_name=f'gb ({pref_mif}) A'),
ch
)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.groundout_a += r_val[0]
if r_val[0] == 0:
retries += 1
full_log(new_ratings, card, info=True)
res_chances = data.groundout_b
retries = 0
while res_chances > 0:
if retries > 0:
break
pref_mif = get_preferred_mif(new_ratings)
ch = get_chances(res_chances)
r_val = assign_pchances(
card,
PlayResult(full_name=f'gb ({pref_mif}) B', short_name=f'gb ({pref_mif}) B'),
ch
)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
res_chances -= r_val[0]
new_ratings.groundout_b += r_val[0]
if r_val[0] == 0:
retries += 1
log_data = vl.sample_output() if data.vs_hand == 'L' else vr.sample_output()
logging.info(f'Pre-filler total chances: {new_ratings.total_chances()}\n{log_data}')
plays = sorted(
[(data.strikeout, 'so'), (data.groundout_a, 'gb'), (data.flyout_lf_b, 'lf'), (data.flyout_rf_b, 'rf')],
key=lambda z: z[0],
reverse=True
)
count_filler = -1
pref_mif = get_preferred_mif(new_ratings)
while not card.is_complete():
count_filler += 1
this_play = plays[count_filler % 4]
if this_play[1] == 'so':
play_res = PlayResult(full_name=f'strikeout', short_name=f'strikeout')
elif this_play[1] == 'gb':
this_if = '3b' if pref_mif == 'ss' else '1b'
play_res = PlayResult(full_name=f'gb ({this_if}) A', short_name=f'gb ({this_if}) A')
elif this_play[1] == 'lf':
play_res = PLAY_RESULTS['fly-lf']
else:
play_res = PLAY_RESULTS['fly-rf']
logging.info(f'Send Card Fill\n{play_res}')
r_val = card.card_fill(play_res)
logging.info(f'Returned batting chances: {r_val[0]} / {r_val[1]}\n')
if this_play[1] == 'so':
new_ratings.strikeout += r_val[0]
elif this_play[1] == 'gb':
new_ratings.groundout_a += r_val[0]
elif this_play[1] == 'lf':
new_ratings.flyout_lf_b += r_val[0]
else:
new_ratings.flyout_rf_b += r_val[0]
full_log(new_ratings, card)
card.add_fatigue()
new_ratings.update_slash_lines()
new_pitchingratings.append(new_ratings)
vl_output = vl.card_output()
vr_output = vr.card_output()
logging.info(f'vl: {vl.sample_output()}')
logging.info(f'vr: {vr.sample_output()}')
vl_total = new_pitchingratings[0].total_chances()
vr_total = new_pitchingratings[1].total_chances()
logging.info(f'New Ratings\nTotal Chances:\n{vl_total}\n{new_pitchingratings[0]}\n\n'
f'Total Chances: {vr_total}\n{new_pitchingratings[1]}')
pos_data = get_pos_data(positions, is_pitcher=True)
return {
'player': player,
'card_type': 'pitcher',
# 'vl_one_2d6': '<b>2-</b>',
# 'vl_one_results': '<b>HOMERUN</b>',
# 'vl_one_d20': '<b> </b>',
# 'vl_two_2d6': '2-',
# 'vl_two_results': 'fly (cf) B',
# 'vl_two_d20': '',
# 'vl_three_2d6': '<b>2-</b><br>&nbsp;',
# 'vl_three_results': '<b>HR</b><br>fly (cf) B',
# 'vl_three_d20': '<b>1-16</b><br>17-20',
# 'results_vr_one': 'Light Dongs',
# 'results_vr_two': 'Hefty Dongs',
# 'results_vr_three': 'Obese Dongs',
'vl_one_2d6': vl_output['one_2d6'],
'vl_one_results': vl_output['one_results'],
'vl_one_d20': vl_output['one_d20'],
'vl_two_2d6': vl_output['two_2d6'],
'vl_two_results': vl_output['two_results'],
'vl_two_d20': vl_output['two_d20'],
'vl_three_2d6': vl_output['three_2d6'],
'vl_three_results': vl_output['three_results'],
'vl_three_d20': vl_output['three_d20'],
'vr_one_2d6': vr_output['one_2d6'],
'vr_one_results': vr_output['one_results'],
'vr_one_d20': vr_output['one_d20'],
'vr_two_2d6': vr_output['two_2d6'],
'vr_two_results': vr_output['two_results'],
'vr_two_d20': vr_output['two_d20'],
'vr_three_2d6': vr_output['three_2d6'],
'vr_three_results': vr_output['three_results'],
'vr_three_d20': vr_output['three_d20'],
'hand': pitching_card.hand,
'pit_card': pitching_card,
'rarity_file': rarity_file,
'position_string': pos_data['string'],
'position_font': pos_data['font'],
'position_margin': pos_data['margin'],
'new_ratings_vl': new_pitchingratings[0],
'new_ratings_vr': new_pitchingratings[1],
}