Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Conway's Game of Life\n",
"\n",
"This is a 2D grid of cells, which can be on or off, 'living' or 'dead'. This grid changes over a series of generations.\n",
"\n",
"Each cell has 8 neighbours (up, down, left, right and the diagonals). The number of neighbours of each cell determines whether it will live in the next generation:\n",
"\n",
"* Cells with less than two neighbours will die\n",
"* Cells with two neighbours will stay alive if already alive\n",
"* Cells with three neighbours will come to life\n",
"* Cells with four or more neighbours will die"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, run the `import`s below that we'll need for the exercise."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib import animation, rc\n",
"from IPython.display import HTML\n",
"import random"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Starting out\n",
"\n",
"Have a quick look through the rest of the worksheet to familiarise yourself. All of the code you need to edit is in the cells labelled:\n",
"\n",
"```python\n",
"### Update the grid\n",
"```\n",
"\n",
"and\n",
"\n",
"```python\n",
"### Starting conditions\n",
"```\n",
"\n",
"The eventual goal is that the function `update_cell()` will apply the Life rules as above. `update_grid` will run these rules on the whole grid, and return a new grid (the next generation of the cellular automaton).\n",
"\n",
"Let's do something simpler first. In the section `### Update the grid`, edit `update_grid()` so that it:\n",
"\n",
"* Creates a new grid the same shape as the one passed to it.\n",
"* Calls `update_cell` for each position in the grid, and puts the result in the same position in the new grid.\n",
"* Returns the new grid.\n",
"\n",
"Once that's done, you'll be ready to edit `update_cell()` to apply the rules, and return a `0` if the cell is dead in the next generation, and `1` if it's alive.\n",
"\n",
"First we should test the code though, and make sure everything works! So for now let's get `update_cell` to return a random `0` or `1`:\n",
"\n",
"```python\n",
"def update_cell(x, y, grid):\n",
" return random.choice([0, 1])\n",
"```\n",
"\n",
"Run all of the rest of the cells to the end of the worksheet. When you get to the one marked ```### VIDEO```, after a short wait, you should see video of a randomly changing grid.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A simple rule\n",
"\n",
"Rather than going straight to the Life rules, let's try something simpler.\n",
"\n",
"Change `update_cell` so that each cell is alive in the next generation if the cell to the left of it is alive.\n",
"\n",
"Re-run the rest of the worksheet and look at the result."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A less simple rule\n",
"\n",
"Now change `update_cell` so that a cell is alive if two cells adjacent to it (up, down, left, right) are alive.\n",
"\n",
"You'll have to work around the limits of the grid. If you like, for now you could just ignore the edges. (I.e., just update up to the second-last row and second-last column, and ignore the last row and last column)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Life!\n",
"\n",
"Now it's time to implement the Game of Life rules. As before, if you want you can ignore the last row and last column, to make things easier around the edges of the grid."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\\downarrow$ The code below will need to be filled out for the Game of Life to run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"### Update the grid\n",
"\n",
"def update_cell(x, y, grid):\n",
"def update_grid(grid):\n",
" \n"
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\\downarrow$ This code sets up the starting conditions."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"### Starting conditions\n",
"\n",
"# random grid\n",
"start_grid = np.random.randint(2,size=(100,100))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\\downarrow$ This code sets up the plot where we'll display the grid -- you don't need to edit it."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"fig = plt.figure()\n",
"ax = plt.axes()\n",
"image = plt.imshow(start_grid, interpolation='none')\n",
"plt.set_cmap(\"Greys\")\n",
"plt.tick_params(axis='x',which='both',bottom='off',top='off',labelbottom='off')\n",
"plt.tick_params(axis='y',which='both',left='off',right='off',labelleft='off')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\\downarrow$ The next three code cells are setup for the animation -- you don't need to edit them."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"### Code to animate the grid -- do not modify\n",
"def init():\n",
" return (image,)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"### Code to animate the grid -- do not modify\n",
"def animate(_):\n",
" global grid\n",
" grid = update_grid(grid)\n",
" image.set_data(grid)\n",
" return (image,)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"global grid\n",
"grid = start_grid\n",
"anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=500, blit=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\\downarrow$ This cell creates a video of the generations of the grid."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"HTML(anim.to_jshtml())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"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",