Skip to content

Instantly share code, notes, and snippets.

@quantumjim
Last active April 3, 2020 12:23
Show Gist options
  • Save quantumjim/0717496e471200c20e35314dfbbfe157 to your computer and use it in GitHub Desktop.
Save quantumjim/0717496e471200c20e35314dfbbfe157 to your computer and use it in GitHub Desktop.
Game engine with jupyter widgets
from ipywidgets import widgets
from ipywidgets import Layout, HBox, VBox
from IPython.display import display
class jupyter_widget_engine():
def __init__(self,start,next_frame,parameters):
self.next_frame = next_frame
self.parameters = parameters
L = 8
layout = Layout(width='50px', height='50px')
screen = {}
for X in range(L):
for Y in range(L):
screen[X,Y] = widgets.ToggleButton(description='',button_style='',layout=layout,disabled=True)
controller = {}
controller['blank'] = widgets.ToggleButton(description='',button_style='',layout=layout)
controller['up'] = widgets.ToggleButton(description='▲',button_style='',layout=layout)
controller['down'] = widgets.ToggleButton(description='▼',button_style='',layout=layout)
controller['left'] = widgets.ToggleButton(description='◀︎',button_style='',layout=layout)
controller['right'] = widgets.ToggleButton(description='►',button_style='',layout=layout)
controller['O'] = widgets.ToggleButton(description='O',button_style='',layout=layout)
controller['X'] = widgets.ToggleButton(description='X',button_style='',layout=layout)
controller['continue'] = widgets.ToggleButton(description='Continue',button_style='',layout=Layout(width='320px', height='50px'))
[b,u,d,l,r,o,x,c] = [controller['blank'],
controller['up'],
controller['down'],
controller['left'],
controller['right'],
controller['O'],
controller['X'],
controller['continue']]
interface = []
interface.append( widgets.HBox([screen[X,0] for X in range(L)]+[b,u,b,b,b,o]) )
interface.append( widgets.HBox([screen[X,1] for X in range(L)]+[l,b,r,b,x,b]) )
interface.append( widgets.HBox([screen[X,2] for X in range(L)]+[b,d,b,b,b,b]) )
interface.append( widgets.HBox([screen[X,3] for X in range(L)]+[c]) )
for Y in range(4,L):
interface.append( widgets.HBox([screen[X,Y] for X in range(L)]) )
self.screen = screen
self.controller = controller
start(self)
display(widgets.VBox(interface))
b.observe(self.given_b)
self.controller['continue'].observe(self._next_frame)
def given_b(self,obs_b):
if self.controller['blank'].value:
self.controller['blank'].value = False
def _next_frame(self,obs_n):
self.next_frame(self)
for button in self.controller.values():
button.value = False
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can make simple games with Jupyter widgets. Whether we *should* is another matter entirely. But we can, so let's do it.\n",
"\n",
"Just import some stuff I wrote. Don't look at it. It is ~~hacky nonsense~~ such a masterpeice of coding that it will blow your minds."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"from jupyter_widget_engine import jupyter_widget_engine"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This gives us the ability to make games for an 8x8 pixel screen, controlled by a D-pad and two buttons. There is also a 'continue' button, which needs to be pressed to move act on the given inputs and move on to the next frame.\n",
"\n",
"To make a game, you have to define the function that is called when this button is pressed. Here is a simple example."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from jupyter_widget_engine import jupyter_widget_engine\n",
"\n",
"def next_frame (self):\n",
" \n",
" text = self.parameters['text']\n",
"\n",
" if self.controller['X'].value:\n",
" if self.screen[0,0].button_style=='':\n",
" self.screen[0,0].button_style = 'danger'\n",
" elif self.screen[0,0].button_style=='danger':\n",
" self.screen[0,0].button_style = 'warning'\n",
" else:\n",
" self.screen[0,0].button_style = ''\n",
" \n",
" if self.controller['O'].value:\n",
" if self.screen[0,0].description=='':\n",
" self.screen[0,0].description = text[0]\n",
" elif self.screen[0,0].description==text[0]:\n",
" self.screen[0,0].description = text[1]\n",
" else:\n",
" self.screen[0,0].button_style = ''\n",
" \n",
" if self.controller['up'].value:\n",
" self.screen[0,0].value = not self.screen[0,0].value"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Similarly, you must define a function that sets up the initial screen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def start(self):\n",
" \n",
" self.screen[3,3].description = ':)'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These functions address the pixels using `self.screen`, and accesses whether the controller buttons have been pressed using `self.controller`. It also uses `self.parameters`, which are you supply yourself.\n",
"\n",
"The pixels have on and off states, which can be set using the `value` attribute (`True` or `False`).\n",
"\n",
"They also have three possible colours, grey, red and orange, which can be set using the `button_style` attribute (`''`, `'danger'` and `'warning'`, respectively).\n",
"\n",
"You can also set text to the pixels using the `description` attribute.\n",
"\n",
"The parameters used in these functions must all be contained in the `parameters` dictionary. Here's what is used in the `next_frame` function above."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"text = ['0','1']\n",
"parameters = {'text':text}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The game is started by initiating the `jupyter_widget_engine` object with this function and these parameters."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d573d47ed7a34475911a29f23a6d531f",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(HBox(children=(ToggleButton(value=False, disabled=True, layout=Layout(height='50px', width='50p…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"engine = jupyter_widget_engine(start,next_frame,parameters)"
]
},
{
"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.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Copyright IBM - Research 2020
Apache 2.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment