diff --git a/docs/index.rst b/docs/index.rst index 042a43a..3bf2a5e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -70,6 +70,13 @@ Quick Example print(market.consumer_surplus) print(market.producer_surplus) +**Output:** + +.. code-block:: text + + Market(price=5.0, quantity=10.0) + 25.0 + 37.5 The plot shows the supply and demand curves with the equilibrium point clearly marked, and the consumer and producer surplus areas shaded: @@ -91,6 +98,12 @@ and the consumer and producer surplus areas shaded: games tutorials/quickstart +.. toctree:: + :maxdepth: 1 + :caption: Tutorials + + tutorials/prisoners_dilemma + Indices and tables diff --git a/docs/notebooks/prisoners_dilemma.ipynb b/docs/notebooks/prisoners_dilemma.ipynb new file mode 100644 index 0000000..bd42b73 --- /dev/null +++ b/docs/notebooks/prisoners_dilemma.ipynb @@ -0,0 +1,154 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The Prisoner's Dilemma\n", + "\n", + "This tutorial demonstrates how to model and analyze the classic Prisoner's Dilemma using FreeRide.\n", + "\n", + "## Setup\n", + "\n", + "First, install FreeRide (if running in Colab):" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: freeride in /Users/alexanderclark/Documents/GitHub/FreeRide (0.0.7)\n", + "Requirement already satisfied: matplotlib in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from freeride) (3.7.2)\n", + "Requirement already satisfied: numpy in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from freeride) (1.24.3)\n", + "Requirement already satisfied: papermill in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from freeride) (2.6.0)\n", + "Requirement already satisfied: IPython in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from freeride) (8.15.0)\n", + "Requirement already satisfied: bokeh in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from freeride) (3.3.4)\n", + "Requirement already satisfied: Jinja2>=2.9 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from bokeh->freeride) (3.1.2)\n", + "Requirement already satisfied: contourpy>=1 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from bokeh->freeride) (1.0.5)\n", + "Requirement already satisfied: packaging>=16.8 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from bokeh->freeride) (23.1)\n", + "Requirement already satisfied: pandas>=1.2 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from bokeh->freeride) (2.0.3)\n", + "Requirement already satisfied: pillow>=7.1.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from bokeh->freeride) (10.0.1)\n", + "Requirement already satisfied: PyYAML>=3.10 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from bokeh->freeride) (6.0)\n", + "Requirement already satisfied: tornado>=5.1 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from bokeh->freeride) (6.3.2)\n", + "Requirement already satisfied: xyzservices>=2021.09.1 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from bokeh->freeride) (2022.9.0)\n", + "Requirement already satisfied: backcall in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (0.2.0)\n", + "Requirement already satisfied: decorator in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (5.1.1)\n", + "Requirement already satisfied: jedi>=0.16 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (0.18.1)\n", + "Requirement already satisfied: matplotlib-inline in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (0.1.6)\n", + "Requirement already satisfied: pickleshare in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (0.7.5)\n", + "Requirement already satisfied: prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (3.0.36)\n", + "Requirement already satisfied: pygments>=2.4.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (2.18.0)\n", + "Requirement already satisfied: stack-data in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (0.2.0)\n", + "Requirement already satisfied: traitlets>=5 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (5.7.1)\n", + "Requirement already satisfied: pexpect>4.3 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (4.8.0)\n", + "Requirement already satisfied: appnope in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from IPython->freeride) (0.1.2)\n", + "Requirement already satisfied: cycler>=0.10 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from matplotlib->freeride) (0.11.0)\n", + "Requirement already satisfied: fonttools>=4.22.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from matplotlib->freeride) (4.25.0)\n", + "Requirement already satisfied: kiwisolver>=1.0.1 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from matplotlib->freeride) (1.4.4)\n", + "Requirement already satisfied: pyparsing<3.1,>=2.3.1 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from matplotlib->freeride) (3.0.9)\n", + "Requirement already satisfied: python-dateutil>=2.7 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from matplotlib->freeride) (2.8.2)\n", + "Requirement already satisfied: click in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from papermill->freeride) (8.0.4)\n", + "Requirement already satisfied: nbformat>=5.2.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from papermill->freeride) (5.9.2)\n", + "Requirement already satisfied: nbclient>=0.2.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from papermill->freeride) (0.5.13)\n", + "Requirement already satisfied: tqdm>=4.32.2 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from papermill->freeride) (4.65.0)\n", + "Requirement already satisfied: requests in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from papermill->freeride) (2.31.0)\n", + "Requirement already satisfied: entrypoints in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from papermill->freeride) (0.4)\n", + "Requirement already satisfied: tenacity>=5.0.2 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from papermill->freeride) (8.2.2)\n", + "Requirement already satisfied: ansicolors in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from papermill->freeride) (1.1.8)\n", + "Requirement already satisfied: parso<0.9.0,>=0.8.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from jedi>=0.16->IPython->freeride) (0.8.3)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from Jinja2>=2.9->bokeh->freeride) (2.1.1)\n", + "Requirement already satisfied: jupyter-client>=6.1.5 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from nbclient>=0.2.0->papermill->freeride) (7.4.9)\n", + "Requirement already satisfied: nest-asyncio in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from nbclient>=0.2.0->papermill->freeride) (1.5.6)\n", + "Requirement already satisfied: fastjsonschema in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from nbformat>=5.2.0->papermill->freeride) (2.16.2)\n", + "Requirement already satisfied: jsonschema>=2.6 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from nbformat>=5.2.0->papermill->freeride) (4.17.3)\n", + "Requirement already satisfied: jupyter-core in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from nbformat>=5.2.0->papermill->freeride) (5.3.0)\n", + "Requirement already satisfied: pytz>=2020.1 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from pandas>=1.2->bokeh->freeride) (2023.3.post1)\n", + "Requirement already satisfied: tzdata>=2022.1 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from pandas>=1.2->bokeh->freeride) (2023.3)\n", + "Requirement already satisfied: ptyprocess>=0.5 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from pexpect>4.3->IPython->freeride) (0.7.0)\n", + "Requirement already satisfied: wcwidth in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30->IPython->freeride) (0.2.5)\n", + "Requirement already satisfied: six>=1.5 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from python-dateutil>=2.7->matplotlib->freeride) (1.16.0)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from requests->papermill->freeride) (2.0.4)\n", + "Requirement already satisfied: idna<4,>=2.5 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from requests->papermill->freeride) (3.4)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from requests->papermill->freeride) (1.26.16)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from requests->papermill->freeride) (2023.11.17)\n", + "Requirement already satisfied: executing in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from stack-data->IPython->freeride) (0.8.3)\n", + "Requirement already satisfied: asttokens in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from stack-data->IPython->freeride) (2.0.5)\n", + "Requirement already satisfied: pure-eval in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from stack-data->IPython->freeride) (0.2.2)\n", + "Requirement already satisfied: attrs>=17.4.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from jsonschema>=2.6->nbformat>=5.2.0->papermill->freeride) (22.1.0)\n", + "Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from jsonschema>=2.6->nbformat>=5.2.0->papermill->freeride) (0.18.0)\n", + "Requirement already satisfied: pyzmq>=23.0 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from jupyter-client>=6.1.5->nbclient>=0.2.0->papermill->freeride) (23.2.0)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: platformdirs>=2.5 in /Users/alexanderclark/anaconda3/lib/python3.11/site-packages (from jupyter-core->nbformat>=5.2.0->papermill->freeride) (3.10.0)\r\n" + ] + } + ], + "source": [ + "!pip install freeride" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(1, 1)]\n" + ] + }, + { + "data": { + "image/png": "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kdRYZEREJDUWGRERSY1FRkREUmORERGR1FhkREQkNRYZERFJjUVGRERSY5EREZHU9J53wQcPHiA8PBx//fUXevToAQsLi9LMRUREVCzPtUX28ccfw97eHn5+fhgyZAhu3boFAOjatSs+/fTTUg1IRERUlBIX2erVqzF//nyMGDEC+/btgxBCO61Xr17Yt29fqQYkIiIqSol3La5cuRJTp07FkiVLkJubm29aw4YNce3atVILR0RE9Cwl3iK7efMmfHx8CpxmamqK1NTUF81ERERUbCUuMnNzc9y9e7fAaTExMbCxsXnhUERERMVV4iLr2rUrlixZgvT0dO2YoijIycnB119/XejWGhERUVko8TGyBQsWoHXr1nB3d0ffvn2hKApWrlyJ8+fPIy4uDtu3by+LnERERAUq8RZZgwYNcOLECbi5uWH16tUQQmDjxo2oWbMmjh07Bicnp7LISUREVKDn+kK0u7s7goODkZ2djeTkZFhYWMDY2Li0sxERET3Tc1/ZAwAMDQ1hb29fWlmIiIhKrMS7FqdOnYq33367wGmDBw/G+++//8KhiIiIiqvERbZnzx54e3sXOM3b2xs///zzC4ciIiIqrhIXWUJCAurWrVvgtDp16iA+Pv5FMxERERVbiYusevXq+PPPPwucFhcXByMjoxcORUREVFwlLjIvLy8sXboUT548yTf+5MkTfPHFF2jfvn2phSMiInqWEp+1OHv2bLz22mto0qQJRowYAQcHB8THx2P9+vWIjY3FmjVryiInERFRgRTx9/uwFNOBAwcwbtw43Lx5UztWv359rFq1qtATQSoaAwMD7VZllSq8UTbJRaPRaP+uKIqKSYhKLq929PX18fjx4xd+vOcqsjzXrl3DvXv3YG1tjYYNG75wmPJUtWrVfL8MiGRjbGwEQ0MDtWMQPZfs7MfIysould/DL1RkMsvbIqtSpQrs7OzUjkNUIgkJCahRwwyLFs1A3bqOaschKpGYmD/x4YdLkJaWoXO+xfMo1jGyo0ePokWLFjAxMcHRo0efOf9rr732wsHKmo2NDRISEmBnZ8evDJB08naH163rCD+/riqnISqZoKAQAIClpWWpPF6xiqxTp04IDw9HmzZt0KlTp0L3yQshoCiKzp2jiYiIykqxiiwsLAzu7u7avxMREVUUxSqyjh07Fvh3IiIitfG8cyIiklqxtsgWLFhQ7AdUFAUfffTRcwciIiIqiWIV2bx584r9gCwyIiIqT8UqspJ8YS0pKem5wxAREZVUqRwjE0Jg//79eOONN+Dk5FQaD0lERFQsJb5o8N/duHED69evR2BgIBITE2FgYIB+/fqVVjYiIqJnKnGRZWVlYceOHVi3bh2OHTum/RL01KlTMXPmTFhZWZVFTiIiogIVe9fimTNnMHr0aNja2mLYsGE4d+4chg0bhr1790IIgd69e7PEiIio3BVri8zT0xOXL18G8PTGmsOHD8eAAQNQvXp1PHjwoEwDEhERFaVYRRYREQFFUdCzZ098+umn2stVERERqa1YuxaXL18OT09P7N27Fx4eHvDy8sJ3332HR48elXU+IiKiIhWryCZOnIjz58/j9OnTGDVqFK5cuYJRo0bBzs4Oo0aNgqIovEstERGpokTfI2vVqhW+/vprJCYmIjAwEK1atcKPP/4IIQRGjBiBpUuXIjk5uayyEhER6XiuL0QbGRnhnXfeweHDh3H16lXMnDkTGRkZeP/99+HoyLvVEhFR+XnhK3vUr18fixYtQlxcHPbs2QNfX9/SyEVERFQsL3Rlj7+rUqUKevXqhV69epXWQxIRET0T70dGRERSY5EREZHUWGRERCQ1FhkREUmNRUZERFJjkRERkdRYZEREJDUWGRERSY1FRkREUmORERGR1FhkREQkNRYZERFJjUVGRERSY5EREZHUWGRERCQ1FhkREUmNRUZERFJjkRERkdRYZEREJDUWGRERSY1FRkREUmORERGR1FhkREQkNRYZERFJjUVGRERSY5EREZHUWGRERCQ1FhkREUmNRUZERFJjkRERkdRYZEREJDUWGRERSY1FRkREUmORERGR1FhkREQkNRYZERFJjUVGRERSY5EREZHUWGRERCQ1FhkREUmNRUZERFJjkRERkdRYZEREJDUWGRERSY1FRkREUmORERGR1FhkREQkNRYZERFJjUVGRERSY5EREZHUWGRERCQ16YpswYIFyMjI0BnPzMzEggULVEhERERqkq7I5s+fj7S0NJ3xjIwMzJ8/X4VERESkJj21A5SUEAKKouiM//HHH7C0tFQhUdmL/OuR2hGKzb2mqdoRqIKJ/Ev3/2tF5V5TFDotPPNyOSYpnnbGjdWOUCFIU2QWFhZQFAWKosDFxSVfmeXm5iItLQ2jR49WMSEREalBmiJbvnw5hBAYPnw45s+fD3Nzc+00AwMD1K1bF15eXiomJCIiNUhTZEOHDgUAODs7o0OHDtDTkyY6ERGVIelO9khPT0dISIjO+IEDBxAUFKRCIiIiUpN0RTZz5kzk5ubqjAshMHPmTBUSERGRmqQrsmvXrsHd3V1n3NXVFdevX1chkbpOnziGxtZmBf754/fTz1w++d49fDh+NDo0qouWTrUwyK8rwo8eLvvg/5CWlobJkyfD3t4eRkZGaNasGbZt21asZZOSkjBs2DDUrFkT1apVg5eXV4Fb7VQxpael4fP5n2Bk/4F4xdUDja0dsGrJ0mIvn3zvL3w4fjI6NGqClk71McivN8KPHivDxLrSH2Vgpf93mNR7Fvyc3oRXNR9898mmYi+fkpSKj0d9Dl/H/uhk1QcjO03GmbDzZZi4cpGuyMzNzXHz5k2d8evXr6N69eoqJKoYJvvPxZagQ/n+NHDVLfy/e5ydjRFv9MapY0cwa+FifLVxK6ysbfDegH44c+J4OSV/ql+/fggMDMTcuXMRFBSE1q1bY+DAgdiyZUuRy2VnZ6Nr164ICQnBihUr8PPPP6NWrVrw9fXFkSNHyik9vYjUlPv4ceNmPM5+jC5+viVa9ul7eABOHTuOWQsX4KuNG2BlbY33BgzGmRO/lVFiXQ9THuLn9fvxOPsJXutVspPOHmc/xoSeH+D3sPOY8tkYLNk+F5Y2NTDldX+cO3axjBJXLtKdMdGnTx9MnjwZu3fvRv369QE8LbFp06ahT58+KqdTj1O9+mjaqk2Jltm5eSOuRUVi8/5f0ax1WwBAm1deQ79O7bF0wUfYdiCsLKLq2L9/P3799Vds2bIFAwcOBAB07twZsbGxeP/99zFgwABUrVq1wGXXrVuHiIgInDx5UnvWaufOndG0aVPMmDEDp06dKpd1oOdn71gbv12PhKIouJ+cgp3fF/3h5e92bt6Ka1FXsHn/z2jWuhUAoM0r7dGvU3csXbAQ2w7sLavY+dg61cLB2zuhKApS/3qAPQHBxV72l4ADuHk5BmvDvoBH26cfPlt0bIYhbUdjlf93WHf0y7KKXWlIt0X22WefoXr16nB1dYWzszOcnZ3h5uYGKysrfP7552rHk0rI/r1wbtBQW2IAoKenh97/NwCXzp3F3cTb5ZJj9+7dMDExQf/+/fONv/vuu7h9+3aRZbR79240atQo31cv9PT0MHjwYJw+fRoJCQlllptKR973Q59HyP5gODeory0xIO893A+Xzp3H3cTE0opZpBdZhyO/nICTS21tiQGAnl5V+LzVFZG/RyMp4a/SillpSVdk5ubmOHnyJPbt24exY8di2rRpCAkJQWhoKGrUqKF2PNUsnDkNnrYWaOPsgJH9/4Wz4c/erXItKhIu7k10xl3cn14t4PqVqFLPWZCIiAi4ubnpfKXC09NTO72oZfPmK2jZy5cr3tUYqPRci4qGi7ubznje2PUrV8s7UondvByLBk2cdcbzxm5FxZZ3JOlIt2sRePrpx9vbG6+99hoMDQ2f+5NQZWBqaobBo8agTYdXUcPCEnG3bmL9qhV49189sHrLDrzSpVuhy6beT4G5hYXOeN5Y6v2UMsv9d8nJyahXr57OeN4lx5KTk4tctqBLkxVnWZJf6v37MLeooTOeN5Z6/375BnoOD1IewsxC99JuZpam2ulUNOm2yDQaDT7++GM4ODjAxMQEt27dAgB89NFHWLduncrpyp+bZ1PMWrgYXXv0Qkuv9ug7aDA27/8V1rVssXTBnGcuX9SHgPL8gPAiOSrKOpA6KsPrXxnWQU3SFdknn3yCgIAALFmyBAYGBtpxDw8PfPfddyomqzjMzGugo7cvrl6OQFZmZqHz1bCwRGqK7lbXg/9+ijWvobu1VhasrKwK3HJK+W+2oi4G/SLLkvxqWFggNUV3q+vB/VQAgLkEhxvMLc0K3Op6mPL0YuEFba1RftIV2caNG7F27Vq8/fbb+c5k8/T0xJUrV1RMVrEI8fQq3kV9mnNxd8e1KN1jSFejIgEADd2KPn2/tHh4eCAqKgo5OTn5xi9dugQAaNJE9zje35fNm6+ky5L8XNxdcS1K9//91f+ONXRrVN6RSqx+k7q4cTlGZzxvrJ573XLNIyPpiiwhIQENGjTQGddoNHjy5IkKiSqeB6n3ceRgMFybeMLQyKjQ+br26I2b167i4tkz2rGcnBzs/fEHeLZsBRtbu/KIi759+yItLQ07d+7MNx4YGAh7e3u0bdu2kCWfLnvlypV8Zzbm5OTg+++/R9u2bWFvb19muUl9XXv44ua167h49px27Ol7eBc8WzaHja2tiumKp2Pv9oiN/hOXT/+vkHNycnFgWwgat3aFtb2ViunkIF2RNW7cGMeO6X5rf8eOHWjevLkKidT1/nvDsWzBXBzY8xNOnziGHZsC8LZfNyTfS8L0eR9r5/to0jh42lrg9p9x2rF+g95BA1c3TBkxFHt3bsdvR8Iw7d9DEXP9GqZ+lP9u26uWLEJjazOcPlH6V0zw8/ND9+7dMWbMGHz77bcICwvDqFGjEBwcjCVLlmi3vEeMGAE9PT3Exv7vLK7hw4ejcePG6N+/P7Zs2YJDhw7hzTffRHR0NBYvXlzqWalsHDsUigN79uLwgV8BADeir+LAnr04sGcvMjOe7h7/aNI0eNo64faf8drl+g16Cw1cG2HKiPewd+du/HbkKKb9ezRirt/A1I/88z3HqiVL0djaAadPnCyTdfjtwBmE7j6G4/vDAQC3rsQidPcxhO4+hqyMLADAwtHL8IqpHxLj7mqX6zXUB/Xc68B/8Cc48EMoToeew+zBCxF7NR5jPxlRJlkrG+nOWpw7dy7eeecdJCQkQKPRYNeuXYiOjsbGjRuxd2/5fPmxInFxb4Lgn3Zhe+B6ZKSnwdzCAi3aeuE/q9fCo3lL7Xy5ubnIzc3V7nIEAANDQ6zb+QuWzv8Ii2a9j6zMTLg28cCabTvRusMr+Z4nIz0diqKgpk2tMlmPXbt2wd/fH3PmzEFKSgpcXV2xdetWvPXWW0Wug6GhIUJCQjBjxgxMmDABGRkZaNasGYKCgtCxY8cyyUqlb8GMWfkKKq/EAODg2XA4ODkW8R7+AUvnf4JFs2YjKzMLrk3csWbbJrTukP8KG/97D9uUyTosmfQV7vytoEJ3HUPorqcf/HZFBcKuji00Gg1yczVAvnUwwFf7FmPl7O+wbNpqZGVkw8WzPpb99AlavKr71RLSpYi/vyskceDAASxatAhnz56FRqNBixYtMGfOHHh7exf7MWrXro2EhAQ4ODggPj7+2QuoqCLcIXqAdyfY13bCF+s3Fjkf7xBdPqpUqQJzc1Ns2fIV/Py6qh2nSBXlDtEDvHvCvrYDvli/ttB5eIfo8hEUFIJBgybAwMAId+/effYCzyDFFtmXX36JUaNGwcjICHFxcfD29oaPj4/asV4aaY8eIvpyBBat/EbtKETPJe3RI0RfjsSilcvVjkJlQIpjZFOnTsXDh09PT3V2dsa9e/dUTvRyMTE1w4WEv1DfpeKfAUZUEBNTU1xIuIX6Lg3VjkJlQIotMnt7e+zcuRM9evSAEALx8fHIysoqcF4nJ6dyTkdERGqSoshmz56NCRMmYPz48VAUBa1bt9aZRwgBRVEKvOkmERFVXlIU2ahRozBw4EDExsbC09MThw4dgpUVv1tBRESSFBkAmJqaokmTJtiwYQM6dOgAQ0NDtSMREVEFIMXJHn83dOhQZGZm4rvvvsOsWbO019Q7d+4c7z1FRPQSkmaLLM/FixfRrVs3mJubIyYmBiNHjoSlpSV2796N2NhYbNxY9PecZMTvZpHMivpulkxk/c7Wy0C6LbIpU6Zg2LBhuHbtGoz+dh1BPz8/HD16VMVkRESkBum2yH7//XesXav7zXwHBwfcuXNHhURERKQm6bbIjIyMtF+O/rvo6GhYW1urkIiIiNQkXZG9/vrrWLBggfaWLYqiIC4uDjNnzsQbb7yhcjoiIipv0hXZ559/jnv37sHGxgaZmZno2LEjGjRoAFNTUyxcuFDteEREVM6kO0ZmZmaG48ePIywsLN/V77t166Z2NCIiUoFURabRaBAQEIBdu3YhJiYGiqLA2dkZtra22ktUERHRy0WaXYtCCPTp0wf//ve/kZCQAA8PDzRu3BixsbEYNmwY+vbtq3ZEIiJSgTRbZAEBATh69ChCQkLQuXPnfNNCQ0Pxr3/9Cxs3bsSQIUNUSkhERGqQZots69at+PDDD3VKDAC6dOmCmTNnYvPmzSokIyIiNUlTZBcvXoSvr2+h0/38/PDHH3+UYyIiIqoIpCmylJQU1KpVq9DptWrVwv3798sxERERVQTSFFlubi709Ao/pFe1alXk5OSUYyIiIqoIpDnZQwiBYcOGFXofsuzs7HJOREREFYE0RTZ06NBnzsMzFomIXj7SFNmGDRvUjkBERBWQNMfIiIiICsIiIyIiqbHIiIhIaiwyIiKSGouMiIikxiIjIiKpsciIiEhqLDIiIpIai4yIiKTGIiMiIqmxyIiISGosMiIikhqLjIiIpMYiIyIiqbHIiIhIaiwyIiKSGouMiIikxiIjIiKpsciIiEhqLDIiIpIai4yIiKTGIiMiIqmxyIiISGosMiIikhqLjIiIpMYiIyIiqbHIiIhIaiwyIiKSGouMiIikxiIjIiKpsciIiEhqLDIiIpIai4yIiKTGIiMiIqmxyIiISGosMiIikhqLjIiIpMYiIyIiqbHIiIhIaiwyIiKSGouMiIikxiIjIiKpsciIiEhqLDIiIpIai4yIiKTGIiMiIqmxyIiISGosMiIikhqLjIiIpMYiIyIiqbHIiIhIaiwyIiKSGouMiIikxiIjIiKpsciIiEhqLDIiIpIai4yIiKSmp3YAtSUmJqJ27dpqxyAqESEEACAm5k8EBYWonIaoZGJi/izVx1NE3v+Il0zt2rWRkJCgdgyi52ZsbARDQwO1YxA9l+zsxzA3r4HExMQXfqyXdovM1tZW7QhEzy0pKQlZWdl48iQHlpaWaschKjEjo2pwcHAolcd6abfIiIiocuDJHkREJDUWGRERSY1FRkREUmORERGR1FhkREQkNRYZERFJjUVGRERSY5EREZHUWGRERCQ1FhkREUmNRUZERFJjkRERkdRYZEREJDUWGRERSY1FRkREUmORERGR1P4fGoIUDoOJjsIAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from freeride.games import Game\n", + "\n", + "game = Game.prisoners_dilemma()\n", + "ax = game.table()\n", + "print(game.nash())" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/tutorials/prisoners_dilemma.rst b/docs/tutorials/prisoners_dilemma.rst new file mode 100644 index 0000000..9647038 --- /dev/null +++ b/docs/tutorials/prisoners_dilemma.rst @@ -0,0 +1,71 @@ +The Prisoner's Dilemma +====================== + +.. raw:: html + +
+ + Open In Colab + + + Download Notebook + +
+ +The Prisoner's Dilemma is one of the most famous examples in game theory. It illustrates why two +rational individuals might not cooperate even when it would be in their best interest to do so. + +The Scenario +------------ + +Two prisoners are arrested and held in separate cells. They cannot communicate with each other. +Each has two options: + +- **Cooperate** (remain silent) +- **Defect** (betray the other) + +The payoffs represent utility (higher numbers are better): + +- If both cooperate: Both get utility of 3 (mutual cooperation reward) +- If both defect: Both get utility of 1 (mutual punishment) +- If one cooperates and one defects: The cooperator gets 0 (sucker's payoff), the defector gets 5 (temptation payoff) + +Modeling with FreeRide +---------------------- + +Let's model this game using FreeRide's game theory tools: + +.. code-block:: python + + from freeride.games import Game + + game = Game.prisoners_dilemma() + ax = game.table() + print(game.nash()) + +**Expected Output:** + +.. code-block:: text + + [(1, 1)] + +The visual game table will also be displayed, and the Nash equilibrium `[(1, 1)]` corresponds to +(Defect, Defect) - both players choosing their second action (index 1). + +Analysis +-------- + +The Nash equilibrium is **(Defect, Defect)** even though **(Cooperate, Cooperate)** would give +both players a better outcome. + + +Try It Yourself +--------------- + +Click the **"Open in Colab"** button above to run this example interactively! You can: + +1. Modify the payoff values to see how they affect the equilibrium +2. Try different scenarios (what if cooperation paid more?) +3. Explore other classic games available in FreeRide + +**Next:** Explore more economics concepts with FreeRide! \ No newline at end of file diff --git a/freeride/__pycache__/equilibrium.cpython-311.pyc b/freeride/__pycache__/equilibrium.cpython-311.pyc index c66fb90..9f1d4c1 100644 Binary files a/freeride/__pycache__/equilibrium.cpython-311.pyc and b/freeride/__pycache__/equilibrium.cpython-311.pyc differ