559 lines
24 KiB
YAML
559 lines
24 KiB
YAML
schema: 1
|
|
id: pure-snake
|
|
title: Pure Snake
|
|
pitch: Build Snake as pure functions, then wire it to the world with IO and event streams, in JavaScript, Scala 3 or F#.
|
|
visibility: public
|
|
root: /home/user/functional-programming-course
|
|
tracks:
|
|
- { id: js, label: JavaScript }
|
|
- { id: scala, label: Scala 3 }
|
|
- { id: fsharp, label: F# }
|
|
mentor: MENTOR.md
|
|
source: { kind: authored }
|
|
modules:
|
|
- id: m00
|
|
title: "Setup and how to use this course"
|
|
lessons:
|
|
- { id: m00-text, title: "Setup and how to use this course", type: text, file: "course/00-setup.md" }
|
|
- id: m00-ex-green-lights
|
|
title: "Exercise 0.1 — Green lights"
|
|
type: exercise
|
|
file: "course/00-setup.md"
|
|
anchor: exercise-01--green-lights
|
|
hints: { file: "course/00-setup.md", match: "Exercise 0.1" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m00-*.test.js\""
|
|
scala: "cd scala && ./test.sh M00"
|
|
fsharp: "cd fsharp && ./test.sh M00"
|
|
- id: m00-ex-read-a-red-test
|
|
title: "Exercise 0.2 — Read a red test"
|
|
type: exercise
|
|
file: "course/00-setup.md"
|
|
anchor: exercise-02--read-a-red-test
|
|
hints: { file: "course/00-setup.md", match: "Exercise 0.2" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m00-*.test.js\""
|
|
scala: "cd scala && ./test.sh M00"
|
|
fsharp: "cd fsharp && ./test.sh M00"
|
|
- id: m00-ex-break-the-purity-audit-on-purpose
|
|
title: "Exercise 0.3 — Break the purity audit on purpose"
|
|
type: exercise
|
|
file: "course/00-setup.md"
|
|
anchor: exercise-03--break-the-purity-audit-on-purpose
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m00-*.test.js\""
|
|
scala: "cd scala && ./test.sh M00"
|
|
fsharp: "cd fsharp && ./test.sh M00"
|
|
- id: m01
|
|
title: "Purity and immutability"
|
|
lessons:
|
|
- { id: m01-text, title: "Purity and immutability", type: text, file: "course/01-purity-and-immutability.md" }
|
|
- id: m01-ex-range
|
|
title: "Exercise 1.1 — `range`"
|
|
type: exercise
|
|
file: "course/01-purity-and-immutability.md"
|
|
anchor: exercise-11--range
|
|
hints: { file: "course/01-purity-and-immutability.md", match: "Exercise 1.1 (range)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m01-*.test.js\""
|
|
scala: "cd scala && ./test.sh M01"
|
|
fsharp: "cd fsharp && ./test.sh M01"
|
|
- id: m01-ex-droplast
|
|
title: "Exercise 1.2 — `dropLast`"
|
|
type: exercise
|
|
file: "course/01-purity-and-immutability.md"
|
|
anchor: exercise-12--droplast
|
|
hints: { file: "course/01-purity-and-immutability.md", match: "Exercise 1.2 (dropLast)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m01-*.test.js\""
|
|
scala: "cd scala && ./test.sh M01"
|
|
fsharp: "cd fsharp && ./test.sh M01"
|
|
- id: m01-ex-contains
|
|
title: "Exercise 1.3 — `contains`"
|
|
type: exercise
|
|
file: "course/01-purity-and-immutability.md"
|
|
anchor: exercise-13--contains
|
|
hints: { file: "course/01-purity-and-immutability.md", match: "Exercise 1.3 (contains)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m01-*.test.js\""
|
|
scala: "cd scala && ./test.sh M01"
|
|
fsharp: "cd fsharp && ./test.sh M01"
|
|
- id: m01-ex-pipe
|
|
title: "Exercise 1.4 — `pipe` (JS only)"
|
|
type: exercise
|
|
file: "course/01-purity-and-immutability.md"
|
|
anchor: exercise-14--pipe-js-only
|
|
hints: { file: "course/01-purity-and-immutability.md", match: "Exercise 1.4 (pipe)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m01-*.test.js\""
|
|
scala: "cd scala && ./test.sh M01"
|
|
fsharp: "cd fsharp && ./test.sh M01"
|
|
- id: m01-ex-compose
|
|
title: "Exercise 1.5 — `compose` (JS only)"
|
|
type: exercise
|
|
file: "course/01-purity-and-immutability.md"
|
|
anchor: exercise-15--compose-js-only
|
|
hints: { file: "course/01-purity-and-immutability.md", match: "Exercise 1.5 (compose)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m01-*.test.js\""
|
|
scala: "cd scala && ./test.sh M01"
|
|
fsharp: "cd fsharp && ./test.sh M01"
|
|
- id: m01-ex-deepfreeze
|
|
title: "Exercise 1.6 — `deepFreeze` (JS only)"
|
|
type: exercise
|
|
file: "course/01-purity-and-immutability.md"
|
|
anchor: exercise-16--deepfreeze-js-only
|
|
hints: { file: "course/01-purity-and-immutability.md", match: "Exercise 1.6 (deepFreeze)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m01-*.test.js\""
|
|
scala: "cd scala && ./test.sh M01"
|
|
fsharp: "cd fsharp && ./test.sh M01"
|
|
- id: m02
|
|
title: "The game as data"
|
|
lessons:
|
|
- { id: m02-text, title: "The game as data", type: text, file: "course/02-the-game-as-data.md" }
|
|
- id: m02-ex-your-own-design
|
|
title: "Exercise 2.0 — Your own design (paper)"
|
|
type: exercise
|
|
file: "course/02-the-game-as-data.md"
|
|
anchor: exercise-20--your-own-design-paper
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m02-*.test.js\""
|
|
scala: "cd scala && ./test.sh M02"
|
|
fsharp: "cd fsharp && ./test.sh M02"
|
|
- id: m02-ex-point
|
|
title: "Exercise 2.1 — `point` and `pointEquals` (JS)"
|
|
type: exercise
|
|
file: "course/02-the-game-as-data.md"
|
|
anchor: exercise-21--point-and-pointequals-js
|
|
hints: { file: "course/02-the-game-as-data.md", match: "Exercise 2.1 (pointEquals)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m02-*.test.js\""
|
|
scala: "cd scala && ./test.sh M02"
|
|
fsharp: "cd fsharp && ./test.sh M02"
|
|
- id: m02-ex-delta
|
|
title: "Exercise 2.2 — `delta`"
|
|
type: exercise
|
|
file: "course/02-the-game-as-data.md"
|
|
anchor: exercise-22--delta
|
|
hints: { file: "course/02-the-game-as-data.md", match: "Exercises 2.2 and 2.3 (delta, opposite)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m02-*.test.js\""
|
|
scala: "cd scala && ./test.sh M02"
|
|
fsharp: "cd fsharp && ./test.sh M02"
|
|
- id: m02-ex-opposite
|
|
title: "Exercise 2.3 — `opposite`"
|
|
type: exercise
|
|
file: "course/02-the-game-as-data.md"
|
|
anchor: exercise-23--opposite
|
|
hints: { file: "course/02-the-game-as-data.md", match: "Exercises 2.2 and 2.3 (delta, opposite)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m02-*.test.js\""
|
|
scala: "cd scala && ./test.sh M02"
|
|
fsharp: "cd fsharp && ./test.sh M02"
|
|
- id: m02-ex-action
|
|
title: "Exercise 2.4 — `Action` (JS)"
|
|
type: exercise
|
|
file: "course/02-the-game-as-data.md"
|
|
anchor: exercise-24--action-js
|
|
hints: { file: "course/02-the-game-as-data.md", match: "Exercise 2.4 (Action)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m02-*.test.js\""
|
|
scala: "cd scala && ./test.sh M02"
|
|
fsharp: "cd fsharp && ./test.sh M02"
|
|
- id: m02-ex-initialstate
|
|
title: "Exercise 2.5 — `initialState`"
|
|
type: exercise
|
|
file: "course/02-the-game-as-data.md"
|
|
anchor: exercise-25--initialstate
|
|
hints: { file: "course/02-the-game-as-data.md", match: "Exercise 2.5 (initialState)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m02-*.test.js\""
|
|
scala: "cd scala && ./test.sh M02"
|
|
fsharp: "cd fsharp && ./test.sh M02"
|
|
- id: m03
|
|
title: "Pure game rules"
|
|
lessons:
|
|
- { id: m03-text, title: "Pure game rules", type: text, file: "course/03-pure-game-rules.md" }
|
|
- id: m03-ex-move
|
|
title: "Exercise 3.1 — `move`"
|
|
type: exercise
|
|
file: "course/03-pure-game-rules.md"
|
|
anchor: exercise-31--move
|
|
hints: { file: "course/03-pure-game-rules.md", match: "Exercise 3.1 (move)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m03-*.test.js\""
|
|
scala: "cd scala && ./test.sh M03"
|
|
fsharp: "cd fsharp && ./test.sh M03"
|
|
- id: m03-ex-inbounds
|
|
title: "Exercise 3.2 — `inBounds`"
|
|
type: exercise
|
|
file: "course/03-pure-game-rules.md"
|
|
anchor: exercise-32--inbounds
|
|
hints: { file: "course/03-pure-game-rules.md", match: "Exercise 3.2 (inBounds)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m03-*.test.js\""
|
|
scala: "cd scala && ./test.sh M03"
|
|
fsharp: "cd fsharp && ./test.sh M03"
|
|
- id: m03-ex-turn
|
|
title: "Exercise 3.3 — `turn`"
|
|
type: exercise
|
|
file: "course/03-pure-game-rules.md"
|
|
anchor: exercise-33--turn
|
|
hints: { file: "course/03-pure-game-rules.md", match: "Exercise 3.3 (turn)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m03-*.test.js\""
|
|
scala: "cd scala && ./test.sh M03"
|
|
fsharp: "cd fsharp && ./test.sh M03"
|
|
- id: m03-ex-advance
|
|
title: "Exercise 3.4 — `advance`"
|
|
type: exercise
|
|
file: "course/03-pure-game-rules.md"
|
|
anchor: exercise-34--advance
|
|
hints: { file: "course/03-pure-game-rules.md", match: "Exercise 3.4 (advance)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m03-*.test.js\""
|
|
scala: "cd scala && ./test.sh M03"
|
|
fsharp: "cd fsharp && ./test.sh M03"
|
|
- id: m04
|
|
title: "Randomness without side effects"
|
|
lessons:
|
|
- { id: m04-text, title: "Randomness without side effects", type: text, file: "course/04-randomness-without-side-effects.md" }
|
|
- id: m04-ex-nextuint32
|
|
title: "Exercise 4.1 — `nextUint32`"
|
|
type: exercise
|
|
file: "course/04-randomness-without-side-effects.md"
|
|
anchor: exercise-41--nextuint32
|
|
hints: { file: "course/04-randomness-without-side-effects.md", match: "Exercise 4.1 (nextUint32)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m04-*.test.js\""
|
|
scala: "cd scala && ./test.sh M04"
|
|
fsharp: "cd fsharp && ./test.sh M04"
|
|
- id: m04-ex-pure
|
|
title: "Exercise 4.2 — `pure`, `map`, `flatMap`, `run`"
|
|
type: exercise
|
|
file: "course/04-randomness-without-side-effects.md"
|
|
anchor: exercise-42--pure-map-flatmap-run
|
|
hints: { file: "course/04-randomness-without-side-effects.md", match: "Exercise 4.2 (pure, map, flatMap, run)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m04-*.test.js\""
|
|
scala: "cd scala && ./test.sh M04"
|
|
fsharp: "cd fsharp && ./test.sh M04"
|
|
- id: m04-ex-intbelow
|
|
title: "Exercise 4.3 — `intBelow`"
|
|
type: exercise
|
|
file: "course/04-randomness-without-side-effects.md"
|
|
anchor: exercise-43--intbelow
|
|
hints: { file: "course/04-randomness-without-side-effects.md", match: "Exercise 4.3 (intBelow)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m04-*.test.js\""
|
|
scala: "cd scala && ./test.sh M04"
|
|
fsharp: "cd fsharp && ./test.sh M04"
|
|
- id: m04-ex-freecells
|
|
title: "Exercise 4.4 — `freeCells`"
|
|
type: exercise
|
|
file: "course/04-randomness-without-side-effects.md"
|
|
anchor: exercise-44--freecells
|
|
hints: { file: "course/04-randomness-without-side-effects.md", match: "Exercise 4.4 (freeCells)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m04-*.test.js\""
|
|
scala: "cd scala && ./test.sh M04"
|
|
fsharp: "cd fsharp && ./test.sh M04"
|
|
- id: m04-ex-spawnapple
|
|
title: "Exercise 4.5 — `spawnApple`"
|
|
type: exercise
|
|
file: "course/04-randomness-without-side-effects.md"
|
|
anchor: exercise-45--spawnapple
|
|
hints: { file: "course/04-randomness-without-side-effects.md", match: "Exercise 4.5 (spawnApple)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m04-*.test.js\""
|
|
scala: "cd scala && ./test.sh M04"
|
|
fsharp: "cd fsharp && ./test.sh M04"
|
|
- id: m04-ex-tick
|
|
title: "Exercise 4.6 — `tick` and `newGame`"
|
|
type: exercise
|
|
file: "course/04-randomness-without-side-effects.md"
|
|
anchor: exercise-46--tick-and-newgame
|
|
hints: { file: "course/04-randomness-without-side-effects.md", match: "Exercise 4.6 (tick, newGame)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m04-*.test.js\""
|
|
scala: "cd scala && ./test.sh M04"
|
|
fsharp: "cd fsharp && ./test.sh M04"
|
|
- id: m05
|
|
title: "Folding time"
|
|
lessons:
|
|
- { id: m05-text, title: "Folding time", type: text, file: "course/05-folding-time.md" }
|
|
- id: m05-ex-update
|
|
title: "Exercise 5.1 — `update`"
|
|
type: exercise
|
|
file: "course/05-folding-time.md"
|
|
anchor: exercise-51--update
|
|
hints: { file: "course/05-folding-time.md", match: "Exercise 5.1 (update)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m05-*.test.js\""
|
|
scala: "cd scala && ./test.sh M05"
|
|
fsharp: "cd fsharp && ./test.sh M05"
|
|
- id: m05-ex-replay
|
|
title: "Exercise 5.2 — `replay`"
|
|
type: exercise
|
|
file: "course/05-folding-time.md"
|
|
anchor: exercise-52--replay
|
|
hints: { file: "course/05-folding-time.md", match: "Exercise 5.2 (replay)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m05-*.test.js\""
|
|
scala: "cd scala && ./test.sh M05"
|
|
fsharp: "cd fsharp && ./test.sh M05"
|
|
- id: m05-ex-history
|
|
title: "Exercise 5.3 — `history`"
|
|
type: exercise
|
|
file: "course/05-folding-time.md"
|
|
anchor: exercise-53--history
|
|
hints: { file: "course/05-folding-time.md", match: "Exercise 5.3 (history)" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m05-*.test.js\""
|
|
scala: "cd scala && ./test.sh M05"
|
|
fsharp: "cd fsharp && ./test.sh M05"
|
|
- id: m06
|
|
title: "Rendering as data"
|
|
lessons:
|
|
- { id: m06-text, title: "Rendering as data", type: text, file: "course/06-rendering-as-data.md" }
|
|
- id: m06-ex-view
|
|
title: "Exercise 6.1 — `view`"
|
|
type: exercise
|
|
file: "course/06-rendering-as-data.md"
|
|
anchor: exercise-61--view
|
|
hints: { file: "course/06-rendering-as-data.md", match: "Exercise 6.1" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m06-*.test.js\""
|
|
scala: "cd scala && ./test.sh M06"
|
|
fsharp: "cd fsharp && ./test.sh M06"
|
|
- id: m06-ex-a-second-interpreter
|
|
title: "Exercise 6.2 (optional, untested) — a second interpreter"
|
|
type: exercise
|
|
file: "course/06-rendering-as-data.md"
|
|
anchor: exercise-62-optional-untested--a-second-interpreter
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m06-*.test.js\""
|
|
scala: "cd scala && ./test.sh M06"
|
|
fsharp: "cd fsharp && ./test.sh M06"
|
|
- id: m07
|
|
title: "The IO type"
|
|
lessons:
|
|
- { id: m07-text, title: "The IO type", type: text, file: "course/07-the-io-type.md" }
|
|
- id: m07-ex-pure
|
|
title: "Exercise 7.1 — `pure` and `effect`"
|
|
type: exercise
|
|
file: "course/07-the-io-type.md"
|
|
anchor: exercise-71--pure-and-effect
|
|
hints: { file: "course/07-the-io-type.md", match: "Exercise 7.1" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m07-*.test.js\""
|
|
scala: "cd scala && ./test.sh M07"
|
|
fsharp: "cd fsharp && ./test.sh M07"
|
|
- id: m07-ex-map
|
|
title: "Exercise 7.2 — `map` and `flatMap`"
|
|
type: exercise
|
|
file: "course/07-the-io-type.md"
|
|
anchor: exercise-72--map-and-flatmap
|
|
hints: { file: "course/07-the-io-type.md", match: "Exercise 7.2" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m07-*.test.js\""
|
|
scala: "cd scala && ./test.sh M07"
|
|
fsharp: "cd fsharp && ./test.sh M07"
|
|
- id: m07-ex-sequence
|
|
title: "Exercise 7.3 — `sequence`, `draw`, `randomSeed`, `drawScene`"
|
|
type: exercise
|
|
file: "course/07-the-io-type.md"
|
|
anchor: exercise-73--sequence-draw-randomseed-drawscene
|
|
hints: { file: "course/07-the-io-type.md", match: "Exercise 7.3" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m07-*.test.js\""
|
|
scala: "cd scala && ./test.sh M07"
|
|
fsharp: "cd fsharp && ./test.sh M07"
|
|
- id: m07-ex-trace
|
|
title: "Exercise 7.4 — `trace`, the pure interpreter"
|
|
type: exercise
|
|
file: "course/07-the-io-type.md"
|
|
anchor: exercise-74--trace-the-pure-interpreter
|
|
hints: { file: "course/07-the-io-type.md", match: "Exercise 7.4" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m07-*.test.js\""
|
|
scala: "cd scala && ./test.sh M07"
|
|
fsharp: "cd fsharp && ./test.sh M07"
|
|
- id: m08
|
|
title: "Event streams"
|
|
lessons:
|
|
- { id: m08-text, title: "Event streams", type: text, file: "course/08-event-streams.md" }
|
|
- id: m08-ex-run
|
|
title: "Exercise 8.1 — `run`"
|
|
type: exercise
|
|
file: "course/08-event-streams.md"
|
|
anchor: exercise-81--run
|
|
hints: { file: "course/08-event-streams.md", match: "Exercise 8.1" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m08-*.test.js\""
|
|
scala: "cd scala && ./test.sh M08"
|
|
fsharp: "cd fsharp && ./test.sh M08"
|
|
- id: m08-ex-keydowns
|
|
title: "Exercise 8.2 — sources: `keyDowns`, `keyUps`, `interval`"
|
|
type: exercise
|
|
file: "course/08-event-streams.md"
|
|
anchor: exercise-82--sources-keydowns-keyups-interval
|
|
hints: { file: "course/08-event-streams.md", match: "Exercise 8.2" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m08-*.test.js\""
|
|
scala: "cd scala && ./test.sh M08"
|
|
fsharp: "cd fsharp && ./test.sh M08"
|
|
- id: m08-ex-map
|
|
title: "Exercise 8.3 — `map`, `filter`, `filterMap`"
|
|
type: exercise
|
|
file: "course/08-event-streams.md"
|
|
anchor: exercise-83--map-filter-filtermap
|
|
hints: { file: "course/08-event-streams.md", match: "Exercise 8.3 / 8.4" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m08-*.test.js\""
|
|
scala: "cd scala && ./test.sh M08"
|
|
fsharp: "cd fsharp && ./test.sh M08"
|
|
- id: m08-ex-merge
|
|
title: "Exercise 8.4 — `merge`, `scan`, `startWith`"
|
|
type: exercise
|
|
file: "course/08-event-streams.md"
|
|
anchor: exercise-84--merge-scan-startwith
|
|
hints: { file: "course/08-event-streams.md", match: "Exercise 8.4" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m08-*.test.js\""
|
|
scala: "cd scala && ./test.sh M08"
|
|
fsharp: "cd fsharp && ./test.sh M08"
|
|
- id: m09
|
|
title: "Wiring it together"
|
|
lessons:
|
|
- { id: m09-text, title: "Wiring it together", type: text, file: "course/09-wiring-it-together.md" }
|
|
- id: m09-ex-keytoaction
|
|
title: "Exercise 9.1 — `keyToAction`"
|
|
type: exercise
|
|
file: "course/09-wiring-it-together.md"
|
|
anchor: exercise-91--keytoaction
|
|
hints: { file: "course/09-wiring-it-together.md", match: "Exercise 9.1" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m09-*.test.js\""
|
|
scala: "cd scala && ./test.sh M09"
|
|
fsharp: "cd fsharp && ./test.sh M09"
|
|
- id: m09-ex-classicactions
|
|
title: "Exercise 9.2 — the app: `classicActions`, `states`, `render`, `main`"
|
|
type: exercise
|
|
file: "course/09-wiring-it-together.md"
|
|
anchor: exercise-92--the-app-classicactions-states-render-main
|
|
hints: { file: "course/09-wiring-it-together.md", match: "Exercise 9.2" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m09-*.test.js\""
|
|
scala: "cd scala && ./test.sh M09"
|
|
fsharp: "cd fsharp && ./test.sh M09"
|
|
- id: m09-ex-runio
|
|
title: "Exercise 9.3 — the runtime: `runIO` and `runApp`"
|
|
type: exercise
|
|
file: "course/09-wiring-it-together.md"
|
|
anchor: exercise-93--the-runtime-runio-and-runapp
|
|
hints: { file: "course/09-wiring-it-together.md", match: "Exercise 9.3" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m09-*.test.js\""
|
|
scala: "cd scala && ./test.sh M09"
|
|
fsharp: "cd fsharp && ./test.sh M09"
|
|
- id: m09-ex-browserplatform
|
|
title: "Exercise 9.4 (JS only) — `browserPlatform`"
|
|
type: exercise
|
|
file: "course/09-wiring-it-together.md"
|
|
anchor: exercise-94-js-only--browserplatform
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m09-*.test.js\""
|
|
scala: "cd scala && ./test.sh M09"
|
|
fsharp: "cd fsharp && ./test.sh M09"
|
|
- id: m10
|
|
title: "Extensions, all pure"
|
|
lessons:
|
|
- { id: m10-text, title: "Extensions, all pure", type: text, file: "course/10-extensions.md" }
|
|
- id: m10-ex-movesevery
|
|
title: "Exercise 10.1 — `movesEvery`"
|
|
type: exercise
|
|
file: "course/10-extensions.md"
|
|
anchor: exercise-101--movesevery
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m10-*.test.js\""
|
|
scala: "cd scala && ./test.sh M10"
|
|
fsharp: "cd fsharp && ./test.sh M10"
|
|
- id: m10-ex-update
|
|
title: "Exercise 10.2 — `update`: `TogglePause`, `Restart`, `Frame`"
|
|
type: exercise
|
|
file: "course/10-extensions.md"
|
|
anchor: exercise-102--update-togglepause-restart-frame
|
|
hints: { file: "course/10-extensions.md", match: "Exercise 10.2" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m10-*.test.js\""
|
|
scala: "cd scala && ./test.sh M10"
|
|
fsharp: "cd fsharp && ./test.sh M10"
|
|
- id: m10-ex-two-more-keys
|
|
title: "Exercise 10.3 — two more keys"
|
|
type: exercise
|
|
file: "course/10-extensions.md"
|
|
anchor: exercise-103--two-more-keys
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m10-*.test.js\""
|
|
scala: "cd scala && ./test.sh M10"
|
|
fsharp: "cd fsharp && ./test.sh M10"
|
|
- id: m10-ex-the-frame-clock
|
|
title: "Exercise 10.4 — the frame clock"
|
|
type: exercise
|
|
file: "course/10-extensions.md"
|
|
anchor: exercise-104--the-frame-clock
|
|
hints: { file: "course/10-extensions.md", match: "Exercise 10.4" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m10-*.test.js\""
|
|
scala: "cd scala && ./test.sh M10"
|
|
fsharp: "cd fsharp && ./test.sh M10"
|
|
- id: m11
|
|
title: "Capstone: Pong, by the method"
|
|
lessons:
|
|
- { id: m11-text, title: "Capstone: Pong, by the method", type: text, file: "course/11-capstone-pong.md" }
|
|
- id: m11-ex-model
|
|
title: "Exercise 11.1 — model"
|
|
type: exercise
|
|
file: "course/11-capstone-pong.md"
|
|
anchor: exercise-111--model
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m11-*.test.js\""
|
|
scala: "cd scala && ./test.sh M11"
|
|
fsharp: "cd fsharp && ./test.sh M11"
|
|
- id: m11-ex-rules
|
|
title: "Exercise 11.2 — rules"
|
|
type: exercise
|
|
file: "course/11-capstone-pong.md"
|
|
anchor: exercise-112--rules
|
|
hints: { file: "course/11-capstone-pong.md", match: "Exercise 11.2" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m11-*.test.js\""
|
|
scala: "cd scala && ./test.sh M11"
|
|
fsharp: "cd fsharp && ./test.sh M11"
|
|
- id: m11-ex-view
|
|
title: "Exercise 11.3 — view"
|
|
type: exercise
|
|
file: "course/11-capstone-pong.md"
|
|
anchor: exercise-113--view
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m11-*.test.js\""
|
|
scala: "cd scala && ./test.sh M11"
|
|
fsharp: "cd fsharp && ./test.sh M11"
|
|
- id: m11-ex-keys-and-wiring
|
|
title: "Exercise 11.4 — keys and wiring"
|
|
type: exercise
|
|
file: "course/11-capstone-pong.md"
|
|
anchor: exercise-114--keys-and-wiring
|
|
hints: { file: "course/11-capstone-pong.md", match: "Exercise 11.4" }
|
|
localCommand:
|
|
js: "cd js && node --test \"test/m11-*.test.js\""
|
|
scala: "cd scala && ./test.sh M11"
|
|
fsharp: "cd fsharp && ./test.sh M11"
|
|
- id: ref
|
|
title: "Method and reference"
|
|
lessons:
|
|
- { id: ref-method, title: "The method", type: text, file: course/method.md }
|
|
- { id: ref-reference, title: "Reference", type: text, file: course/reference.md }
|