\n",
"\n",
"# Dice Baseball\n",
"\n",
- "The [March 22, 2019 Riddler](https://fivethirtyeight.com/features/can-you-turn-americas-pastime-into-a-game-of-yahtzee/) asks us to simulate baseball using probabilities from a 19th century dice game. The simulation is pretty straightforward. (Note that I chose not to implement a strike as an event, but rather to count the probability of getting 3 strikes in a row, and calling that an event.)"
+ "The [March 22, 2019 Riddler](https://fivethirtyeight.com/features/can-you-turn-americas-pastime-into-a-game-of-yahtzee/) asks us to simulate baseball using probabilities from a 19th century dice game. There were some choices to make that were left unspecified in the rules; these are my choices (your choices may differ):\n",
+ "\n",
+ "* On a `b`-base hit, runners advance `b` bases, except that a runner on second scores on a 1-base hit.\n",
+ "* On an \"out at first\", all runners advance one base.\n",
+ "* On a double play, the runner on first is out if there is one, otherwise a runner on second, otherwise a runner on third, otherwise it is only a single out.\n",
+ "* On a fly out, a runner on third scores; other runners do not advance.\n",
+ "* On an error all runners advance one base. (*Note: in an earlier version, I treated an error as a single, meaning that a runner would score from second on an error which seems wrong. Under that interpretation, teams score about 0.1 runs more per game.*)\n",
+ "\n",
+ "I also made some choices about the implementation:\n",
+ "- I wanted to have one event per batter, so I don't allow \"strike\" as an event. Rather I compute the probability of a strikeout event (i.e. getting three \"strike\" outcomes in a row before getting another event) as `(7/36)**3 = 0.007351680384`, and check for that.\n",
+ "- Note that a die roll such as (1, 1) is a 1/36 event, whereas (1, 2) is a 2/36 event.\n",
+ "- I'll represent events with the following one letter codes:\n",
+ " - `K`, `O`, `o`, `f`, `D`: strikeout, foul out, out at first, fly out, double play\n",
+ " - `1`, `2`, `3`, `4`: single, double, triple, home run\n",
+ " - `E`, `B`: error, base on balls\n",
+ "- I'll keep track of runners with a list of occupied bases; `runners = [1, 2]` means runners on first and second.\n",
+ "- A runner who advances to base 4 or higher has scored a run (unless there are already 3 outs).\n",
+ "- The function `inning` simulates a (half) inning and returns the number of runs scored.\n",
+ "- I'll run the simulation 1 million times and store the resulting scores in `innings`.\n",
+ "- To simulate a game I just sample 9 elements of `innings`."
]
},
{
@@ -19,8 +38,6 @@
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
- "from collections import Counter\n",
- "from statistics import mean\n",
"import random"
]
},
@@ -30,23 +47,16 @@
"metadata": {},
"outputs": [],
"source": [
- "def inning(events='2111111EEBBOOooooooofffffD334', strikes=7*'s', verbose=False):\n",
- " \"Play a random inning and return number of runs scored.\"\n",
- " assert len(events) + len(strikes) == 6 * 6\n",
- " K = (len(strikes) / len(strikes+events)) ** 3 # The probability of a strikeout\n",
- " events = events.replace('E', '1') # An error is the same as a single\n",
- " outs = runs = 0\n",
- " runners = [] # A list of runners; [1, 2, 3] means bases loaded\n",
+ "def inning(events='2111111EEBBOOooooooofffffD334', strikes=7, verbose=False):\n",
+ " \"Simulate a random inning and return number of runs scored.\"\n",
+ " E = len(events) + strikes # With 2 dice, E = 36\n",
+ " PK = (strikes / E) ** 3 # The probability of a strikeout\n",
+ " outs = runs = 0 # Inning starts with no outs and no runs,\n",
+ " runners = [] # ... and with nobody on base\n",
" while True:\n",
- " x = 'K' if random.random() <= K else random.choice(events)\n",
- " if verbose: \n",
- " print('{} outs; {} runs; runners on {}; result is {}'\n",
- " .format(outs, runs, runners, x))\n",
- " if x in '1234': # single, double, triple, homer\n",
- " runners = [r + int(x) + (r == 2) for r in runners + [0]]\n",
- " elif x == 'B': # base on balls\n",
- " runners = [(r+1 if r==1 or r-1 in runners else r) for r in runners] + [1]\n",
- " elif x in 'KOofD': # srikeout, foul out, out at first, fly out, double play\n",
+ " x = 'K' if random.random() <= PK else random.choice(events)\n",
+ " if verbose: print(f'outs: {outs}, runs: {runs}, runners: {runners}, event: {x}')\n",
+ " if x in 'KOofD': # batter is out: strikeout, foul out, out at first, fly out, double play\n",
" outs += 1\n",
" if x == 'D' and runners: # double play\n",
" runners.remove(min(runners))\n",
@@ -56,8 +66,14 @@
" elif x == 'f' and 3 in runners: # fly out; runner on 3rd scores\n",
" runs += 1\n",
" runners.remove(3)\n",
- " else:\n",
- " raise ValueError('unknown events: ' + x)\n",
+ " else: # batter reaches base safely\n",
+ " runners.append(0)\n",
+ " if x in '1234': # single, double, triple, homer\n",
+ " runners = [r + int(x) + (r == 2) for r in runners]\n",
+ " elif x == 'E': # error\n",
+ " runners = [r + 1 for r in runners]\n",
+ " elif x == 'B': # base on balls\n",
+ " runners = [(r+1 if r==0 or r-1 in runners else r) for r in runners]\n",
" if outs >= 3:\n",
" return runs\n",
" else: # See if anybody scored\n",
@@ -81,17 +97,18 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "0 outs; 0 runs; runners on []; result is o\n",
- "1 outs; 0 runs; runners on []; result is o\n",
- "2 outs; 0 runs; runners on []; result is 1\n",
- "2 outs; 0 runs; runners on [1]; result is 1\n",
- "2 outs; 0 runs; runners on [2, 1]; result is O\n"
+ "outs: 0, runs: 0, runners: [], event: E\n",
+ "outs: 0, runs: 0, runners: [1], event: o\n",
+ "outs: 1, runs: 0, runners: [2], event: 4\n",
+ "outs: 1, runs: 2, runners: [], event: O\n",
+ "outs: 2, runs: 2, runners: [], event: 1\n",
+ "outs: 2, runs: 2, runners: [1], event: f\n"
]
},
{
"data": {
"text/plain": [
- "0"
+ "2"
]
},
"execution_count": 3,
@@ -112,13 +129,12 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "0 outs; 0 runs; runners on []; result is 3\n",
- "0 outs; 0 runs; runners on [3]; result is f\n",
- "1 outs; 1 runs; runners on []; result is 1\n",
- "1 outs; 1 runs; runners on [1]; result is o\n",
- "2 outs; 1 runs; runners on [2]; result is 1\n",
- "2 outs; 2 runs; runners on [1]; result is 1\n",
- "2 outs; 2 runs; runners on [2, 1]; result is K\n"
+ "outs: 0, runs: 0, runners: [], event: o\n",
+ "outs: 1, runs: 0, runners: [], event: O\n",
+ "outs: 2, runs: 0, runners: [], event: B\n",
+ "outs: 2, runs: 0, runners: [1], event: 4\n",
+ "outs: 2, runs: 2, runners: [], event: B\n",
+ "outs: 2, runs: 2, runners: [1], event: o\n"
]
},
{
@@ -145,15 +161,22 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "0 outs; 0 runs; runners on []; result is o\n",
- "1 outs; 0 runs; runners on []; result is 3\n",
- "1 outs; 0 runs; runners on [3]; result is D\n"
+ "outs: 0, runs: 0, runners: [], event: 2\n",
+ "outs: 0, runs: 0, runners: [2], event: 1\n",
+ "outs: 0, runs: 1, runners: [1], event: o\n",
+ "outs: 1, runs: 1, runners: [2], event: O\n",
+ "outs: 2, runs: 1, runners: [2], event: 1\n",
+ "outs: 2, runs: 2, runners: [1], event: B\n",
+ "outs: 2, runs: 2, runners: [2, 1], event: E\n",
+ "outs: 2, runs: 2, runners: [3, 2, 1], event: B\n",
+ "outs: 2, runs: 3, runners: [3, 2, 1], event: 4\n",
+ "outs: 2, runs: 7, runners: [], event: O\n"
]
},
{
"data": {
"text/plain": [
- "0"
+ "7"
]
},
"execution_count": 5,
@@ -171,28 +194,25 @@
"source": [
"That looks good.\n",
"\n",
- "Now, simulate a million innings, use them to simulate a million games, and show a histogram of runs scored per team per game:"
+ "Now, simulate a million innings, and then sample from them to simulate a million nine-inning games:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 20.7 s, sys: 73.7 ms, total: 20.8 s\n",
- "Wall time: 20.9 s\n"
- ]
- }
- ],
+ "outputs": [],
"source": [
- "%%time\n",
"N = 1000000\n",
"innings = [inning() for _ in range(N)]\n",
- "games = [sum(random.choice(innings) for i in range(9)) for g in range(N)]"
+ "games = [sum(random.sample(innings, 9)) for _ in range(N)]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Finally, display a histogram and the mean number of runs scored per team per nine-inning game:"
]
},
{
@@ -203,7 +223,7 @@
{
"data": {
"text/plain": [
- "(15.106058, 15.10542)"
+ "14.960244"
]
},
"execution_count": 7,
@@ -212,7 +232,7 @@
},
{
"data": {
- "image/png": "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\n",
+ "image/png": "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\n",
"text/plain": [
""
]
@@ -225,7 +245,7 @@
],
"source": [
"plt.hist(games, ec='black', bins=max(games)-min(games)+1)\n",
- "mean(games), mean(innings) * 9"
+ "sum(games) / N"
]
}
],
@@ -245,7 +265,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.5.3"
+ "version": "3.7.2"
}
},
"nbformat": 4,