The game is complete. This page provides the question file, runs the tester, and shows what a full game looks like from start to finish.
questions.txt
Fifteen questions spanning the curriculum — terminal, git, C, 6502, and game history.
Copy this exactly. The tester's expected output depends on the field order and the answer indices.
Which command lists files and directories in a Unix terminal?|ls|dir|list|show|0|The answer is A: ls.
What does git add prepare a file for?|Deletion from the repository|The next commit|A remote push|Branch creation|1|The answer is B: the next commit.
In C, what keyword exits a loop immediately?|exit|return|break|stop|2|The answer is C: break.
What C header provides printf?|<stdlib.h>|<string.h>|<math.h>|<stdio.h>|3|The answer is D: <stdio.h>.
What does tci_printf use to determine where to write output?|A FILE * pointer|A file descriptor|A buffer size|A format string|1|The answer is B: a file descriptor.
What Unix file descriptor number is stderr?|0|1|2|3|2|The answer is C: 2.
What does git log --oneline display?|The most recent commit only|All commits, one line each|Staged changes|The diff of the last commit|1|The answer is B: all commits, one line each.
On the 6502, which instruction loads an immediate value into the accumulator?|MOV A, #|LD A|LDA|LOAD|2|The answer is C: LDA.
What does tci_getline return when EOF is reached?|An empty string|0|-1|NULL|3|The answer is D: NULL.
What is the fourth argument to qsort?|An element index|The array size|A comparison function|A sort key|2|The answer is C: a comparison function.
Which id Software game released in 1993 popularised BSP trees for real-time rendering?|Quake|Duke Nukem 3D|Heretic|DOOM|3|The answer is D: DOOM.
What does fork() return in the child process on success?|The parent's PID|A negative number|0|1|2|The answer is C: 0.
What flag tells gcc to include debugging symbols?|-Wall|-g|-O2|-std=c99|1|The answer is B: -g.
On the 6502, how many cycles does INC $00 (zero-page increment) take?|2|3|4|5|3|The answer is D: 5 cycles.
In C99, what is the behaviour when comparing two pointers to unrelated objects?|The result is zero|The result is implementation-defined|The behaviour is undefined|The compiler rejects it|2|The answer is C: undefined behaviour.The companion repo ships a 30-question bank so each run draws from a larger pool. The 15 questions above cover every safe level exactly once in the correct order — use this file for the tester.
Build and run
make re
./game questions.txtThe prize ladder appears with level 1 highlighted in yellow. Answer correctly through all 15 questions to reach the win screen.
A losing run — answer B on the first question (which is wrong):
Wrong answer.
You leave with £0.A walk away at level 6 after passing the first safe level:
You walk away with £2,000.Wait — level 6 displays £2,000. Walk away at level 6 means the player
has already answered 5 correctly. display_walkaway(level) computes
PRIZES[level - 1], and level is 5 (0-indexed) when the player
walks at the level-6 prompt. PRIZES[4] is "£1,000".
That is the correct banked amount — the last answered question's prize, not the current question's prize.
If the output says £2,000 instead of £1,000 here, re-read the
display_walkaway call in game_loop. The player has not yet answered
level 6 — walking away at a prompt means the previous level was the
last correct answer.
Run the tester
bash test.shFour test cases run sequentially:
- Full win — correct answers to all 15 questions; expects the win screen.
- Early loss — wrong answer on question 3; expects
£0(before the first safe level). - 50:50 lifeline — uses lifeline on question 8, then answers correctly.
- Walk away — walks at question 11 (after passing £32,000 safe
level); expects
£32,000as the banked amount.
All four should pass. If the walk-away test fails, trace the
safe_level update in game_loop — it should be set at the
beginning of the level, before the question is shown.
What comes next
The game works. It runs in any Linux terminal, loads questions from a plain text file, and uses nothing beyond what the first three c-tier chapters built. Two revisions follow — each one adds a layer that requires a chapter not yet reached.
Music. The original show used a dramatic score that changed at
each safe level — quiet at the start, increasingly tense through the
middle, different again after £32,000. Implementing that requires
spawning a background process to play audio while the game loop
continues in the foreground. That is fork() and exec() — the
tools in c05.
g01c picks up here. It adds a music.c module with two functions
— start_music and stop_music — and a royalty-free soundtrack
sourced from Freesound. The game becomes noticeably more dramatic.
The code change is small. The effect is not.
Graphics. The terminal is a capable renderer for text, but not
for backgrounds, bitmap fonts, or the visual atmosphere that made the
TV show distinct. Once c04
introduces SDL2 — window, renderer, textures, the event loop — it
becomes possible to replace the tci_printf display layer entirely.
g01b picks that up. It loads a background bitmap, renders the
prize ladder and question text through a bitmap font sprite sheet, and
draws every screen that display_* currently prints. The game logic
— questions, lifelines, safe levels, walk away — is unchanged. The
read(0, &c, 1) input becomes an SDL2 keyboard event. The output
becomes a window. Everything you built here survives; only the
presentation changes.