Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
289 changes: 289 additions & 0 deletions CrashV2.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Necessary Libraries and Constants"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#https://www.youtube.com/watch?v=F1HA7e3acSI\n",
"#https://www.bustabit.com/play\n",
"#https://bitcointalk.org/index.php?topic=2807542.0\n",
"#https://jsfiddle.net/Dexon95/2fmuxLza/"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import hashlib\n",
"import random\n",
"import string\n",
"import hmac\n",
"import math\n",
"import codecs\n",
"\n",
"# https://www.blockchain.com/btc/block/0000000000000000004d6ec16dafe9d8370958664c1dc422f452892264c59526\n",
"salt505750 = \"0000000000000000004d6ec16dafe9d8370958664c1dc422f452892264c59526\"\n",
"SALT = salt505750"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Get Result and Get Previous Game Function"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"results = [('319aa8124bbcddac2bae8438cfd5e658aeca56d524736739622dfb0a09942b22', 159.93),\n",
"('c64559640b124fa354eaaee31510eaa0f1a5fdd5aa004363b95693e52d274d28',2.36),\n",
"('c263a30ad8820e8c3d46f9a5db3c34d3b081cd349a11367a9fbd52063f17cd34',1.31),\n",
"('a6bb64e83b8efa52524ba526cd036ae17c3ec00b9fbec49b8cd4dc1321d7b4ce',1.09),\n",
"('17612b37d97f0faf0930762a328ab383bd2e107c5cc5c975cc76405f41a4bbc2',1.43)]\n",
"\n",
"\n",
"def get_prev_game(hash_code):\n",
" m = hashlib.sha256()\n",
" m.update(hash_code.encode(\"utf-8\"))\n",
" return m.hexdigest()\n",
"for i in range(len(results)-1):\n",
" assert get_prev_game(results[i][0]) == results[i+1][0]\n",
"print(\"get_prev_game passed\")\n",
"\n",
"def get_result(seed, salt=SALT):\n",
" salt = salt.encode(\"utf8\")\n",
" seed = codecs.decode(bytes(seed, \"utf8\"), \"hex\") #https://tinyurl.com/2bf4dann\n",
" hm = hmac.new(salt, seed, hashlib.sha256)\n",
" h = hm.hexdigest()\n",
" \n",
" r = int(h[:13], 16) # 52 most significant bits as int\n",
" x = r / 2**52 # [0,1)\n",
" x = 99 / (1-x) # [99.0, 4.458563631096791e+17]\n",
" result = math.floor(x) # [99, 445856363109679104]\n",
" return (max(1, result/100))\n",
" \n",
"for res in results[:]: \n",
" assert getResult(res[0]) == res[1], print(f\"\\n\\n{res}: {getResult(res[0])}\")\n",
"print(\"get_result passed\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def sim(numerator=99):\n",
" results = []\n",
" for x in range(0,1000):\n",
" x = x/1000 # [0,0.999]\n",
" x = numerator/(1-x) # [99, 99/(0.001) 99,000]\n",
" result = math.floor(x) # [99, 99000]\n",
" answer = max(1, result/100) # [1, 990]\n",
" results.append(answer)\n",
" return results\n",
" \n",
"game = sim()\n",
"fair = sim(100)\n",
"\n",
"print(\"game\", min(game), sum(game)/len(game), max(game))\n",
"print(\"fair?\", min(fair), sum(fair)/len(fair), max(fair))\n",
"\n",
"if False:\n",
" for g in game:\n",
" print(g)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Collecting All Game Results"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"game_hash = '4fc2f264ea3e0bbf8405f74f0bf354bef946283d6023352f5f8d441d6aaad861' # 29oct2021 Update to latest game's hash for more results\n",
"first_game = \"86728f5fc3bd99db94d3cdaf105d67788194e9701bf95d049ad0e1ee3d004277\" #https://bitcointalk.org/index.php?topic=2807542.0\n",
"\n",
"results = []\n",
"count = 0\n",
"while game_hash != first_game:\n",
" count += 1\n",
" results.append(get_result(game_hash))\n",
" game_hash = get_prev_game(game_hash)\n",
" \n",
"results = np.array(results)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(count)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Testing Probability Formula"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# What's the analytical EV of this new algorithm? "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Testing Expected Value Formula"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#realized results from start of game to now \n",
"#confirms a 1% house edge\n",
"multiplier = 1.7\n",
"(results < multiplier).mean() * -1 + (multiplier - 1)*(results >= multiplier).mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Visualizations"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import seaborn as sns\n",
"sns.set(rc={'figure.figsize':(11.7,8.27)})\n",
"\n",
"plt.hist(results, range=(0, 25))\n",
"plt.title(\"Histogram of Game Results\", fontsize=20)\n",
"plt.xticks(fontsize=15)\n",
"plt.yticks(fontsize=15)\n",
"plt.ylabel(\"Number of Games\", fontsize=15)\n",
"plt.xlabel(\"Multiplier\", fontsize=15)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def calculate_ev(multiplier):\n",
" # This is for the version 1 algorithm, not the version 2.\n",
" return ((1/33) + (32/33)*(.01 + .99*(1 - 1/(multiplier-.01))))*-1 + (multiplier-1)*(1 - ((1/33) + (32/33)*(.01 + .99*(1 - 1/(multiplier-.01)))))\n",
"\n",
"xs = np.linspace(101, 1001, 901) / 100\n",
"ys = [calculate_ev(x) for x in xs]\n",
"y2s = [(results < x).mean() * -1 + (x - 1)*(results >= x).mean() for x in xs]\n",
"\n",
"plt.plot(xs, ys, linewidth=5)\n",
"plt.xlabel(\"Multiplier\", fontsize=15)\n",
"plt.ylabel(\"Expected Value\", fontsize=15)\n",
"plt.xticks(fontsize=15)\n",
"plt.yticks(fontsize=15)\n",
"plt.ylim(-.045, -.000)\n",
"plt.plot(xs, y2s, linewidth=3)\n",
"plt.title(\"Expected Value by Multiplier\", fontsize=20)\n",
"plt.legend([\"(error) Theoretical Results\", \"Actual Results\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Martingale Test"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"negatives = []\n",
"in_a_row = 0\n",
"for multiplier in results:\n",
" if multiplier < 2:\n",
" in_a_row += 1\n",
" else:\n",
" in_a_row = 0\n",
" negatives.append(in_a_row)\n",
"negatives = np.array(negatives)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for i in range(1, 14):\n",
" print(\"Probability of Losing %d Game(s) in a Row:\"%i, (negatives >= i).mean())"
]
}
],
"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.9.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}