Skip to content

Commit

Permalink
Adds a code tour for the Game of Life exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
remarcmij committed Feb 23, 2021
1 parent dfaa3fa commit c2d2c34
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 1 deletion.
254 changes: 254 additions & 0 deletions .tours/game-of-life.tour
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
{
"$schema": "https://aka.ms/codetour-schema",
"title": "5. game of life",
"steps": [
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The program starts when the browser has completed loading the page. When that happens the function **main** is called.",
"line": 145,
"title": "start"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The HTML page contains a \\<canvas> element in which the game cells \"live\". Here, we set the **width** and **height** (in pixels) of the canvas to the desired values.",
"line": 133,
"selection": {
"start": {
"line": 128,
"character": 1
},
"end": {
"line": 134,
"character": 1
}
},
"title": "set canvas size"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The width and height of each cell is 10 pixels, i.e. two times the radius of circle that can be drawn inside a cell. ",
"line": 7,
"selection": {
"start": {
"line": 6,
"character": 1
},
"end": {
"line": 8,
"character": 1
}
},
"title": "cell size"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **context** variable will hold a reference to a 2D context of the canvas that we can use to draw on it.",
"line": 134,
"title": "get 2D context"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **createGame()** function creates the game \"engine\", taking the **context**, number of rows (**numRows**) and number of columns (**numColums**) as arguments and returns two functions, **renderGrid()** and **gameLoop()**.\n\nBasically, the state of the game at each point in time is maintained in an array called **grid**, where each element of the array represent a \"cell\". Each cell can either be alive or dead.\n\n- The **renderGrid()** function takes the **grid** array and renders the grid as a visual presentation using the canvas context.\n- The **gameLoop()** function computes the next state of each cell in the **grid**, using the rules of the Game Of Life.\n\nThe sequence of **renderGrid** and **gameLoop** is repeated indefinitely every 200ms: this is the Game Of Life.",
"line": 136,
"title": "create game"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "Here is the function declaration for the **createGame()** function. The parameters **context**, **numRows**, **numColumns** and the variable **grid** are referenced by inner functions of **createGame()** and as such are captured in a **closure**: they remain in existence even after the **createGame()** function has finished execution.",
"line": 43,
"selection": {
"start": {
"line": 42,
"character": 1
},
"end": {
"line": 44,
"character": 1
}
},
"title": "createGame function declaration"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **createGrid()** inner function is used to create the initial grid. It loops through each row and column to create the individual cells by calling the **createCell()** function, passing the **x** and **y** coordinates of the current cell.",
"line": 51,
"selection": {
"start": {
"line": 45,
"character": 1
},
"end": {
"line": 52,
"character": 1
}
},
"title": "createGrid function"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **createCell()** function creates a JavaScript object that represents an individual cell. The object has **x** and **y** properties, representing the coordinates of the cell, and a boolean property **alive** that is randomly set to **true** or **false**. Thus, each cell is either alive or dead when first created.",
"line": 17,
"selection": {
"start": {
"line": 10,
"character": 1
},
"end": {
"line": 18,
"character": 1
}
},
"title": "createCell function"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "This helper (arrow) function takes an **x** and **y** coordinate and computes an index into the **grid** array that corresponds to the passed coordinates. This is needed because the chosen one-dimensional array form for the **grid** turned out to be more convenient to handle than a two-dimensional one. An arrow function was chosen (as opposed to a traditional function declaration) because it can concisely be expressed a single line.",
"line": 53,
"title": "gridToIndex arrow function"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **isAlive()** function returns **true** or **false**, indicating whether a cell at the given **x** and **y** coordinates is alive. Note that the passed values of **x** and/or **y** may actually be off-grid. Off-grid cells are considered dead. Otherwise, we return the value of the boolean **alive** property of the cell at the given coordinates.",
"line": 62,
"selection": {
"start": {
"line": 55,
"character": 1
},
"end": {
"line": 63,
"character": 1
}
},
"title": "isAlive function"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **countLivingNeighbors()** function counts the number of living cells neighboring a cell. For a cell at the edges of the grid the neighbors may include off-grid (dead) cells. The **isAlive()** function discussed in the previous step caters for that.",
"line": 77,
"title": "countLivingNeighbors function",
"selection": {
"start": {
"line": 65,
"character": 1
},
"end": {
"line": 78,
"character": 1
}
}
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **updateGrid()** function loops through the **grid** array and computes for each cell its next state: alive or dead. It does so by following the rules of the Game Of Life:\n\nFrom Wikipedia's **Conway's Game of Life**:\n\n1. Any live cell with two or three live neighbours survives.\n2. Any dead cell with three live neighbours becomes a live cell.\n3. All other live cells die in the next generation. Similarly, all other dead cells stay dead.",
"line": 101,
"selection": {
"start": {
"line": 79,
"character": 1
},
"end": {
"line": 102,
"character": 1
}
},
"title": "updateGrid function"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **renderGrid()** function loops through the **grid** array and draws each cell (alive or dead) on the 2D canvas.",
"line": 106,
"selection": {
"start": {
"line": 103,
"character": 1
},
"end": {
"line": 107,
"character": 1
}
},
"title": "renderGrid function"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **draw()** function draws a cell onto the 2D canvas. First, it start by drawing a rectangular background.",
"line": 26,
"selection": {
"start": {
"line": 19,
"character": 1
},
"end": {
"line": 27,
"character": 1
}
},
"title": "draw cell background"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "If the cell is alive, it draws a circular cell using a foreground color.",
"line": 39,
"selection": {
"start": {
"line": 28,
"character": 1
},
"end": {
"line": 40,
"character": 1
}
},
"title": "draw alive cell"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "The **gameLoop()** function indefinitely repeats the cycle of **updateGrid()** and **renderGrid()**, rescheduling itself after 200ms using **setTimeout**.",
"line": 119,
"selection": {
"start": {
"line": 108,
"character": 1
},
"end": {
"line": 120,
"character": 1
}
},
"title": "gameLoop function"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "All previously discussed inner functions within **createGame()** were just function declarations. Nothing was executed yet. But here we call the inner function **createGrid()** to create the initial grid with which the game starts. Finally, we return the functions **renderGrid** and **gameLoop** as the function's return value.",
"line": 125,
"selection": {
"start": {
"line": 122,
"character": 1
},
"end": {
"line": 124,
"character": 35
}
},
"title": "finalise createGame"
},
{
"file": "2-Browsers/Week1/homework/ex6-gameOfLife/index.js",
"description": "Upon return from the **createGame()** function, we render the initial grid and kick-start the **gameLoop()** function.\n\nThis concludes to Code Tour.",
"line": 143,
"selection": {
"start": {
"line": 138,
"character": 1
},
"end": {
"line": 143,
"character": 1
}
},
"title": "kick-start game"
}
]
}
12 changes: 11 additions & 1 deletion 2-Browsers/Week1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,17 @@ From Wikipedia:
As illustrated in the picture below, the game is a two-dimensional grid where cells come alive and die, depending on certain rules. Every 200ms, a new generation of cells replaces the previous one.

![Game of Life](../../assets/game-of-life.gif)
> ![Game of Life](../../assets/game-of-life.gif)
### Code Tour

The code for this exercise is non-trivial and may look overwhelming and intimidating at first glance. In our experience, beginners often do not know where to start reading and how to methodically walk through the code. To help you with this, we have provided a Code Tour that guides you in this process.

You will need to install the [CodeTour VSCode extension](https://marketplace.visualstudio.com/items?itemName=vsls-contrib.codetour) (press the link for more info). Once you have done that, you can see an additional item in the bottom of the left-hand panel of VSCode as shown in the picture below. There are a number of code tours listed there, most of them intended for mentors involved in the maintenance of the Homework repo. The CodeTour for this exercise is titled **5. game of life**. To start the tour, press the green play button to the right of the title.

> ![CodeTour](../../assets/code-tour.png)
### Exercise

In the supplied JavaScript code the color of all living cells is a single shade of blue. This is in contrast to the illustration above where living cells have different shades of blue, depending on their life time. Your job is to add a life time property to cells and let the `opacity` of each cell depend on its value, as specified in this table:

Expand Down
Binary file added assets/code-tour.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c2d2c34

Please sign in to comment.