Skip to content

Instantly share code, notes, and snippets.

@alonsosilvaallende
Created August 11, 2024 12:45
Show Gist options
  • Save alonsosilvaallende/89faf10fb19368fb4d81460bb72cbdd2 to your computer and use it in GitHub Desktop.
Save alonsosilvaallende/89faf10fb19368fb4d81460bb72cbdd2 to your computer and use it in GitHub Desktop.
DealCards.ipynb
Display the source blob
Display the rendered blob
Raw
{
"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