Skip to content

Commit

Permalink
winning drinking games
Browse files Browse the repository at this point in the history
  • Loading branch information
geohot committed Feb 8, 2020
1 parent 19a6074 commit 5da3dbd
Showing 1 changed file with 206 additions and 0 deletions.
206 changes: 206 additions & 0 deletions montecarlo_ftd.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 157,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"# see https://www.beerfestboots.com/fuck-the-dealer-rules\n",
"%pylab inline\n",
"import random\n",
"\n",
"def multimode(x):\n",
" if len(x) == 0:\n",
" return []\n",
" mx = max(x)\n",
" return list(filter(lambda i: x[i] == mx, range(len(x))))"
]
},
{
"cell_type": "code",
"execution_count": 190,
"metadata": {},
"outputs": [],
"source": [
"# return a pivot, a high, and a low\n",
"def get_player_move(remain):\n",
" # guess the median for the pivot\n",
" cc = []\n",
" for i,r in enumerate(remain):\n",
" if r != 0:\n",
" cc += [i]*r\n",
" p = sorted(cc)[len(cc)//2]\n",
" \n",
" cl = multimode(remain[0:p])\n",
" ch = [x+p+1 for x in multimode(remain[p+1:])]\n",
" if len(cl) == 0:\n",
" cl = [None]\n",
" if len(ch) == 0:\n",
" ch = [None]\n",
" #print(cl, ch)\n",
" \n",
" return p, random.choice(cl), random.choice(ch)"
]
},
{
"cell_type": "code",
"execution_count": 191,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"([19, 6, 19, 5, 11, 12, 11, 23, 7, 9, 7, 7], 7, 7)"
]
},
"execution_count": 191,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"NUM_PLAYERS = 12\n",
"\n",
"def simulate():\n",
" deck = []\n",
" for suits in range(4):\n",
" for cards in range(13):\n",
" # suits don't matter\n",
" deck.append(cards)\n",
" random.shuffle(deck)\n",
"\n",
" # initial\n",
" dealer_num = 0\n",
" dealer_count = 0\n",
" player_num = 1\n",
"\n",
" remain = [4]*13\n",
" drinks = [0]*NUM_PLAYERS\n",
"\n",
" last_correct = 0\n",
"\n",
" while len(deck) != 0:\n",
" mc = deck.pop()\n",
"\n",
" # player strategy in that function\n",
" p,l,h = get_player_move(remain)\n",
" pg = l if mc < p else h\n",
" if mc == p:\n",
" drinks[dealer_num] += 4\n",
" last_correct = 0\n",
" elif mc == pg:\n",
" # lower\n",
" drinks[dealer_num] += 2\n",
" last_correct = 0\n",
" else:\n",
" # miss\n",
" drinks[player_num] += abs(pg - mc)\n",
" last_correct += 1\n",
"\n",
" if last_correct == 3:\n",
" # dealer advance\n",
" dealer_num += 1\n",
" dealer_num %= NUM_PLAYERS\n",
" last_correct = 0\n",
" dealer_count += 1\n",
"\n",
" # advance player\n",
" player_num += 1\n",
" if player_num == dealer_num:\n",
" player_num += 1\n",
" player_num %= NUM_PLAYERS\n",
"\n",
" remain[mc] -= 1\n",
" \n",
" return drinks, dealer_num, dealer_count\n",
"\n",
"simulate()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"adn = []\n",
"add = [0]*NUM_PLAYERS\n",
"for i in range(10000):\n",
" drinks, dealer_num, dealer_count = simulate()\n",
" adn.append(dealer_count)\n",
" add[dealer_num] += 1"
]
},
{
"cell_type": "code",
"execution_count": 195,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"6.029"
]
},
"execution_count": 195,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 864x864 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"figsize(12,12)\n",
"plt.bar(range(len(add)), add)\n",
"np.mean(adn)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit 5da3dbd

Please sign in to comment.