Created
August 11, 2024 12:45
-
-
Save alonsosilvaallende/89faf10fb19368fb4d81460bb72cbdd2 to your computer and use it in GitHub Desktop.
DealCards.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"provenance": [], | |
"authorship_tag": "ABX9TyO+HdCLvMF2wkwj1KLNJIdg", | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
}, | |
"language_info": { | |
"name": "python" | |
}, | |
"widgets": { | |
"application/vnd.jupyter.widget-state+json": { | |
"a1feb1d39b4a4c2a8657fecadd3e997d": { | |
"model_module": "anywidget", | |
"model_name": "AnyModel", | |
"model_module_version": "~0.9.*", | |
"state": { | |
"_anywidget_id": "dealcards.Widget", | |
"_css": ".ipymario > div > svg {\n height: 400px;\n width: 400px;\n background-color: green;\n}\n\ntext {\n font-size: 8px;\n}\n\n.mybutton { background-color: #ea580c; padding:10px 30px;}\n\n.back {\n fill: white;\n}\n .♣ {\n color: green;\n fill: green;\n}\n\n.♦ {\n color: orange;\n fill: orange;\n}\n\n.♥ {\n color: red;\n fill: red;\n}\n\n.♠ {\n color: blue;\n fill: blue;\n}", | |
"_dom_classes": [], | |
"_esm": "const HEIGHTS = ['2', '3', '4', '5', '6', '7', '8', '9', 'X', 'J', 'Q', 'K', 'A']\n\nconst SUITS = ['♣', '♦', '♥', '♠']\n \nclass Card {\n constructor(height, suit) {\n this.index = 13 * suit + height\n this.height = HEIGHTS[height]\n this.suit = SUITS[suit]\n }\n\n static compare(card1, card2) {\n return card1.index - card2.index\n }\n}\n \nconst DECK = []\nfor (let suit = 0; suit < 4; suit++) {\n for (let height = 0; height < 13; height++) {\n DECK.push(new Card(height, suit))\n }\n}\n\nconst SEPARATED_DECK = [\n DECK.slice(0, 13),\n DECK.slice(13, 26),\n DECK.slice(26, 39),\n DECK.slice(39, 52),\n]\n\nfunction generateShuffledDeck() {\n // Brutal shuffle\n return DECK\n .map(card => [Math.random(), card])\n .sort()\n .map(card => card[1])\n}\n\nfunction generateRandomHands(value) {\n const cards = generateShuffledDeck()\n return [\n cards.slice(0*value, 1*value).sort(Card.compare),\n cards.slice(1*value, 2*value).sort(Card.compare),\n cards.slice(2*value, 3*value).sort(Card.compare),\n cards.slice(3*value, 4*value).sort(Card.compare),\n ]\n}\n\nfunction toName(input) {\n if (Array.isArray(input)) {\n return input.map(e => toName(e))\n } else {\n return input.name\n }\n}\n\nfunction randInt(max) {\n return Math.floor(Math.random() * max)\n}\n\nfunction playRandomly(value) {\n const hands = generateRandomHands(value)\n\n const game = [\n [\n [...hands[0]],\n [...hands[1]],\n [...hands[2]],\n [...hands[3]],\n ]\n ]\n\n for (let i = 0; i < value; i++) {\n const cardsLeft = value - i\n\n hands[0].splice(randInt(cardsLeft), 1)\n hands[1].splice(randInt(cardsLeft), 1)\n hands[2].splice(randInt(cardsLeft), 1)\n hands[3].splice(randInt(cardsLeft), 1)\n\n game.push([\n [...hands[0]],\n [...hands[1]],\n [...hands[2]],\n [...hands[3]],\n ])\n }\n\n return game\n}\n\nimport * as d3 from \"https://esm.sh/d3@7\";\nfunction render({ model, el }) {\n el.classList.add(\"ipymario\");\n let btn = document.createElement(\"button\");\n let count = model.get(\"value\");\n btn.innerText=`Deal the cards`\n btn.addEventListener(\"click\", () => {\n myfunction(count);\n });\n model.on(\"msg:custom\", (msg) => {\n if (msg?.type === \"click\") btn.click();\n });\n model.on(\"change:value\", () => {\n count = model.get(\"value\");\n });\n btn.classList.add(\"mybutton\");\n el.appendChild(btn);\n\n\nconst svg = d3.select(el) // Move this out as we only do it once\n .append('div')\n .append('svg')\n .attr('viewBox', \"-100 -100 200 200\")\n\nfunction myfunction(value) {\n function enter(parent) {\n const g = parent.append('g')\n .attr('class', d => d.suit)\n .attr('transform', () => `translate(0 -80)`)\n .style('opacity', '0') // Fix the initial value\n\n /* ... */\n }\n\n /* ... */\n\nfunction enter(parent) {\n const g = parent.append('g')\n .attr('class', d => d.suit) // Might as well move this here as well\n .attr('transform', () => `translate(0 -80)`)\n .style('opacity', '1') // Fix the initial value\n\n g.append('rect')\n .attr('x', -4.5)\n .attr('y', -7)\n .attr('width', 9)\n .attr('height', 14)\n .classed('back', true)\n\n g.append('text')\n .attr('y', -1)\n .attr('text-anchor', 'middle')\n .text(d => d.suit)\n\n g.append('text')\n .attr('y', 6)\n .attr('text-anchor', 'middle')\n .text(d => d.height)\n\n return g\n}\n\nfunction update(element) {\n return element\n}\n\nfunction exit(element) {\n return element\n .transition().duration(500)\n .attr('transform', () => `translate(0 -50)`)\n .transition().duration(500) // Notice the chaining of transitions\n .style('opacity', 0)\n .remove()\n}\n \nfunction updateGame(data) {\n svg\n .selectChildren('g')\n .data(data, (_, i) => i)\n .join('g')\n .attr('transform', (_, i) => `rotate(${90 * i}) translate(0 80)`)\n .selectChildren('g')\n .data(d => d, d => d.index)\n.join(enter, update, exit)\n .transition().duration(500)\n .attr('transform', (_, i, n) => `translate(${10 * (i - (n.length - 1) / 2)} 0)`)\n .style('opacity', '1') // Fix the \"normal\" value\n}\n\nconst game = playRandomly(value)\ngame.forEach((hands, i) => setTimeout(() => updateGame(hands), 1000 * (i+1)))\n }\n}\n export default { render };\n \n", | |
"_model_module": "anywidget", | |
"_model_module_version": "~0.9.*", | |
"_model_name": "AnyModel", | |
"_view_count": null, | |
"_view_module": "anywidget", | |
"_view_module_version": "~0.9.*", | |
"_view_name": "AnyView", | |
"layout": "IPY_MODEL_c4ab048bcde64bcc9fbc66f2475e5239", | |
"value": 5 | |
} | |
}, | |
"c4ab048bcde64bcc9fbc66f2475e5239": { | |
"model_module": "@jupyter-widgets/base", | |
"model_name": "LayoutModel", | |
"model_module_version": "1.2.0", | |
"state": { | |
"_model_module": "@jupyter-widgets/base", | |
"_model_module_version": "1.2.0", | |
"_model_name": "LayoutModel", | |
"_view_count": null, | |
"_view_module": "@jupyter-widgets/base", | |
"_view_module_version": "1.2.0", | |
"_view_name": "LayoutView", | |
"align_content": null, | |
"align_items": null, | |
"align_self": null, | |
"border": null, | |
"bottom": null, | |
"display": null, | |
"flex": null, | |
"flex_flow": null, | |
"grid_area": null, | |
"grid_auto_columns": null, | |
"grid_auto_flow": null, | |
"grid_auto_rows": null, | |
"grid_column": null, | |
"grid_gap": null, | |
"grid_row": null, | |
"grid_template_areas": null, | |
"grid_template_columns": null, | |
"grid_template_rows": null, | |
"height": null, | |
"justify_content": null, | |
"justify_items": null, | |
"left": null, | |
"margin": null, | |
"max_height": null, | |
"max_width": null, | |
"min_height": null, | |
"min_width": null, | |
"object_fit": null, | |
"object_position": null, | |
"order": null, | |
"overflow": null, | |
"overflow_x": null, | |
"overflow_y": null, | |
"padding": null, | |
"right": null, | |
"top": null, | |
"visibility": null, | |
"width": null | |
} | |
} | |
} | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/alonsosilvaallende/89faf10fb19368fb4d81460bb72cbdd2/dealcards.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"id": "jB_NoqH8cdPP" | |
}, | |
"outputs": [], | |
"source": [ | |
"%pip install --upgrade --quiet dealcards" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"import dealcards\n", | |
"\n", | |
"w = dealcards.Widget()\n", | |
"w" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 459, | |
"referenced_widgets": [ | |
"a1feb1d39b4a4c2a8657fecadd3e997d", | |
"c4ab048bcde64bcc9fbc66f2475e5239" | |
] | |
}, | |
"id": "AjrOCJqccfnT", | |
"outputId": "482208ea-f967-45f8-e07b-d62a61a4c332" | |
}, | |
"execution_count": 2, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": [ | |
"Widget()" | |
], | |
"application/vnd.jupyter.widget-view+json": { | |
"version_major": 2, | |
"version_minor": 0, | |
"model_id": "a1feb1d39b4a4c2a8657fecadd3e997d" | |
} | |
}, | |
"metadata": { | |
"application/vnd.jupyter.widget-view+json": { | |
"colab": { | |
"custom_widget_manager": { | |
"url": "https://ssl.gstatic.com/colaboratory-static/widgets/colab-cdn-widget-manager/2b70e893a8ba7c0f/manager.min.js" | |
} | |
} | |
} | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"w.click()" | |
], | |
"metadata": { | |
"id": "LGEuxRWYct_D" | |
}, | |
"execution_count": 3, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"w.value = 5\n", | |
"w.click()" | |
], | |
"metadata": { | |
"id": "cDYcCBQ2dDkI" | |
}, | |
"execution_count": 4, | |
"outputs": [] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment