Compare commits
3 Commits
35a70fddd7
...
4a898a321f
Author | SHA1 | Date |
---|---|---|
Charles Reid | 4a898a321f | 3 years ago |
Charles Reid | ee86bf307a | 3 years ago |
Charles Reid | ffe67789c9 | 3 years ago |
8 changed files with 173 additions and 46 deletions
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
import logging |
||||
|
||||
|
||||
# Set basic universal log options |
||||
# (level should be WARNING INFO DEBUG) |
||||
loglevel = logging.DEBUG |
||||
logging.basicConfig(format='', level=logging.WARNING) |
||||
|
||||
root_logger = logging.getLogger() |
||||
root_logger.handlers = [] |
||||
|
||||
# Create gp logger and add handlers |
||||
### logger = logging.Logger('gp') |
||||
logger = logging.getLogger('gp') |
||||
logger.setLevel(loglevel) |
||||
|
||||
fh = logging.FileHandler('output.log') |
||||
fh.setLevel(loglevel) |
||||
logger.addHandler(fh) |
||||
|
||||
sh = logging.StreamHandler() |
||||
sh.setLevel(loglevel) |
||||
logger.addHandler(sh) |
@ -1,14 +1,127 @@
@@ -1,14 +1,127 @@
|
||||
import numpy as np |
||||
import random |
||||
import logging |
||||
from scipy.stats import beta |
||||
|
||||
|
||||
logger = logging.getLogger('gp') |
||||
|
||||
|
||||
class Roll(object): |
||||
""" |
||||
Provides class methods to perform various rolls using players and gators. |
||||
Uses beta functions under the hood to generate random outcomes. |
||||
""" |
||||
|
||||
@classmethod |
||||
def random_sample_beta_inv_cdf(cls, E, a): |
||||
""" |
||||
Sample a beta inverse CDF with expectation E and alpha param a. |
||||
The values of E and alpha will fix the value of beta. |
||||
""" |
||||
y_in = random.random() |
||||
b = a * (1.0/E - 1.0) |
||||
# Use the percent point function - inverse CDF |
||||
x_out = beta.ppf(y_in, a, b) |
||||
x = y_in # This is the input random number, uniform between 0-1 |
||||
y = x_out # This is the output weighted random number |
||||
return (x, y) |
||||
|
||||
@classmethod |
||||
def attr_roll(cls, attr_lab, player, gator): |
||||
player_attr = player.attr[attr_lab] |
||||
gator_attr = gator.attr[attr_lab] |
||||
""" |
||||
Use player/gator attributes to construct a beta function, and sample it randomly. |
||||
Return the player and gator rolls (bounded between 0-1 inclusive). |
||||
""" |
||||
nstars = 5 |
||||
|
||||
# Map star ratings to new spaces |
||||
# Expected outcome |
||||
player_attr_min = 0.25 |
||||
player_attr_max = 0.75 |
||||
player_attr_space = np.linspace(player_attr_min, player_attr_max, nstars) |
||||
# Consistency (alpha param of beta distribution) |
||||
player_con_space = np.logspace(-0.5, 0.5, nstars) |
||||
|
||||
# Expected outcome |
||||
gator_attr_min = 0.25 |
||||
gator_attr_max = 0.75 |
||||
gator_attr_space = np.linspace(gator_attr_min, gator_attr_min, nstars) |
||||
# Consistency |
||||
gator_con_space = np.logspace(-0.5, 0.5, nstars) |
||||
|
||||
# Get attribute |
||||
pa = player.attr[attr_lab] |
||||
ga = gator.attr[attr_lab] |
||||
|
||||
# Get consistency |
||||
pc = player.attr['con'] |
||||
gc = gator.attr['con'] |
||||
|
||||
# Transform to get beta function parameters (expectation E, alpha) |
||||
p_E = player_attr_space[pa-1] |
||||
g_E = gator_attr_space[ga-1] |
||||
p_alpha = player_con_space[pc-1] |
||||
g_alpha = gator_con_space[gc-1] |
||||
|
||||
_, p_outcome = cls.random_sample_beta_inv_cdf(p_E, p_alpha) |
||||
_, g_outcome = cls.random_sample_beta_inv_cdf(g_E, g_alpha) |
||||
|
||||
return (p_outcome, g_outcome) |
||||
|
||||
@classmethod |
||||
def roll(cls, player, gator): |
||||
outcomes = [-3, -2, -1, 0, 1, 4, 6] |
||||
return random.choice(outcomes) |
||||
""" |
||||
Given a player and a gator, run the various rolls and find an outcome. |
||||
""" |
||||
# First roll requires gator or player wins both aggressiveness and reach rolls |
||||
agg = cls.attr_roll('agg', player, gator) |
||||
rea = cls.attr_roll('rea', player, gator) |
||||
rxn = cls.attr_roll('rxn', player, gator) |
||||
|
||||
agg_diff = agg[0] - agg[1] |
||||
rea_diff = rea[0] - rea[1] |
||||
rxn_diff = rxn[0] - rxn[1] |
||||
|
||||
if agg_diff > 0 and rea_diff > 0: |
||||
# Player won |
||||
if rxn_diff < 0: |
||||
# Player won but gator got reversal |
||||
logger.debug(f"Player flinched!") |
||||
return 0 |
||||
else: |
||||
# Outcome: runs |
||||
diff = rxn[0] - rxn[1] |
||||
if diff > 0.8: |
||||
logger.debug(f"Gator got slapped!") |
||||
return 6 |
||||
elif diff > 0.5: |
||||
logger.debug(f"Gator got booped in the snoot!") |
||||
return 4 |
||||
else: |
||||
logger.debug(f"Gator got poked!") |
||||
return 1 |
||||
|
||||
elif agg_diff < 0 and rea_diff < 0: |
||||
# Gator won |
||||
if rxn_diff > 0: |
||||
# Gator won but player got reversal |
||||
logger.debug(f"Gator flinched!") |
||||
return 0 |
||||
else: |
||||
# Outcome: wickets |
||||
if abs(rxn_diff) > 0.8: |
||||
logger.debug(f"Player was eaten by gator!") |
||||
return -3 |
||||
elif abs(rxn_diff) > 0.5: |
||||
logger.debug(f"Player's arm got chomped by the gator!") |
||||
return -2 |
||||
elif abs(rxn_diff) > 0.2: |
||||
logger.debug(f"Player's finger got chomped by the gator!") |
||||
return -1 |
||||
else: |
||||
logger.debug(f"Player escaped!") |
||||
return 0 |
||||
else: |
||||
logger.debug(f"Nothing happened!") |
||||
return 0 |
||||
|
Loading…
Reference in new issue