ATAR Year 11 Computer Science - Project 1 Part 1
ATAR Year 11 Computer Science - Project 1 Part 1
Investigation and Design
Name: Arafat Course: Computer Science - ATAR Year 11 Task: Task 1 - Unit 1
1. Problem Outline
The purpose of this project is to design and develop an interactive text-based adventure game using Python, themed around a psychological mystery set in a school environment. The player takes on the role of a student at AIC Kewdale who notices an empty desk in their classroom-someone is missing, but nobody else seems to remember them. The overall objective is to investigate the disappearance, make choices that affect the protagonist’s Memory and Sanity stats, complete classroom minigames, and ultimately reach one of three distinct endings depending on the player’s decisions and stat values.
2. Problem Description
2.1 Objective of the Game
The player must navigate a school day while investigating the mysterious disappearance of a classmate whom nobody else remembers. The core objective is to uncover the truth about the missing person while managing two competing stats: Memory (the ability to remember the truth) and Sanity (mental stability). The game ends with one of three endings determined by the player’s final choice and their stat values.
2.2 Setting and Main Story Scenario
The game is set at AIC Kewdale during a single school day that stretches into the evening. The story follows a student who notices an empty desk in class. When they ask their friend Abdullah about it, nobody remembers the missing person. The player progresses through:
- Chapter 1: The Empty Desk - Classroom scene with minigames (English typing test and Maths quiz)
- The Hallway - Exploration with locker investigation and eavesdropping
- Chapter 2: Suburbia - Walking home with optional detour
- The House - Visiting the missing person’s family home (optional path)
- Night - Final confrontation via a mysterious text message
- Ending - One of three endings based on choices and stats
2.3 Rules of the Game
- The player makes choices by typing the number corresponding to their chosen option (e.g. typing
1,2, or3). - Invalid inputs are rejected with feedback messages that become more intense as Sanity drops.
- Two stats are tracked throughout the game:
- Memory (0-100): Higher Memory allows the player to remember the missing person’s identity. Lower Memory causes text distortion (letters replaced with dots) and name forgetting.
- Sanity (0-100): Higher Sanity keeps the player safe but causes them to forget the missing person. Lower Sanity causes text distortion (word repetition, creepy insertions like “…stop…”) and increasingly hostile error messages.
- Stat changes are displayed to the player with colour-coded HUD indicators (e.g.
[+10 MEMORY],[-5 SANITY]).
2.4 How the Game Is Played (Interaction Model)
The game is played entirely through the terminal/command line. Text is displayed using a typewriter effect (character-by-character printing with variable speed). The player reads narrative text, then selects from numbered options when prompted. During minigame segments, the player types responses directly (sentences for English, numbers for Maths, 5-letter words for Wordle). The game uses ANSI colour codes for visual feedback (green for success, red for errors, yellow for warnings, cyan for stats, dim grey for atmospheric text).
2.5 Scoring and Tracking System
The game tracks two primary stats:
| Stat | Starting Value | Effect When High | Effect When Low |
|---|---|---|---|
| Memory | 100 | Player remembers the truth; text displays the correct name | Text becomes corrupted; letters are replaced with dots; names revert to defaults |
| Sanity | 100 | Player is “safe” but forgets the missing person | Words repeat randomly; “…stop…” is inserted into text; error messages become hostile |
Stats are modified by player choices (e.g. investigating costs Sanity but gains Memory) and minigame performance (e.g. high typing accuracy gains Memory; low scores lose Sanity). Both stats are clamped between 0 and 100.
2.6 How Different Endings Are Reached
There are three endings:
- “Ignorance is Bliss” - Triggered if the player answers NO to the final text message, or if Sanity > 60 and Memory < 40. The player forgets everything and goes to sleep.
- “The Keeper” - Triggered if the player answers YES and Sanity < 40. The player is institutionalised but retains their memories.
- “Equivalent Exchange” - Triggered if the player answers YES with moderate-to-high Sanity. The missing person returns but the player begins to fade from existence.
2.7 Advanced Play Techniques and Strategies
- Name Entry: If the player correctly guesses the missing person’s default name (Husain for boys, Fatima for girls) during the classroom scene, they receive a Memory boost. Entering the name incorrectly still stores it and creates dynamic name-swapping throughout the game.
- Curb Sitting: In Chapter 2, sitting on the curb provides a large Memory boost (+20) at the cost of significant Sanity (-20), but this option can only be used once.
- Wordle Minigame: At the missing person’s house, the player can attempt to hack a phone using a Wordle-style puzzle. If Memory is above 90, the answer is revealed. Successfully completing it unlocks the
knows_truthflag and forces the correct target name. - Easter Eggs: Entering specific names (e.g. “fastmode” enables instant text, entering “Husain” or “Fatima” as the player name triggers alternate character assignments, and the name “abdia” triggers a hidden base64-encoded message).
- Text Distortion System: The game dynamically distorts displayed text based on current stat values, creating a unique reading experience on each playthrough.
3. Requirements
3.1 Functional Requirements
| ID | Requirement | Priority |
|---|---|---|
| FR-01 | The game must display a title screen with ASCII art and a typewriter text effect | Must |
| FR-02 | The game must allow the player to select their gender (Boy/Girl), which determines the default missing person’s name | Must |
| FR-03 | The game must allow the player to enter their character name with input validation (non-empty, not “Abdullah”) | Must |
| FR-04 | The game must track Memory and Sanity stats (integers, clamped 0-100) throughout the entire game | Must |
| FR-05 | The game must display stat changes to the player using colour-coded text indicators | Must |
| FR-06 | The game must present multiple-choice decisions using numbered options and validate the player’s input | Must |
| FR-07 | The game must include a typing accuracy minigame (English class) that displays a sentence, counts down, clears the screen, and scores the player’s attempt | Must |
| FR-08 | The game must include a maths quiz minigame with progressive difficulty (3 rounds) | Must |
| FR-09 | The game must include a Wordle-style minigame with colour-coded feedback (green/yellow/grey) | Must |
| FR-10 | The game must have at least three distinct story paths based on player choices (safe route home, detour to the house, curb sitting) | Must |
| FR-11 | The game must have three significantly different endings based on the final choice and stat values | Must |
| FR-12 | The game must use arrays (lists) to store related data (sentences for typing, startup lines, word lists, error messages) | Must |
| FR-13 | The game must use functions with parameters to structure code (e.g. type_text(text, speed, color), input_choice(options, state), apply_text_effects(text, state)) | Must |
| FR-14 | The game must dynamically distort displayed text based on Memory and Sanity values | Should |
| FR-15 | The game must dynamically swap the missing person’s displayed name based on stats | Should |
| FR-16 | The game must handle KeyboardInterrupt gracefully without crashing | Should |
| FR-17 | The game must include a fast mode toggle (via name entry or command-line argument) | Could |
3.2 Non-Functional Requirements
| ID | Requirement | Priority |
|---|---|---|
| NFR-01 | The game must run in any standard terminal that supports ANSI colour codes | Must |
| NFR-02 | Code must use meaningful variable and function names following Python naming conventions (snake_case) | Must |
| NFR-03 | Code must include comments explaining the purpose of each function and key logic sections | Must |
| NFR-04 | Code must use consistent indentation (4 spaces) and appropriate whitespace | Must |
| NFR-05 | The typewriter text effect must create an engaging, readable pace (adjustable speed parameter) | Should |
| NFR-06 | The game must be completable within 10-15 minutes per playthrough | Should |
| NFR-07 | Input prompts must be clearly visible and distinguishable from narrative text | Should |
| NFR-08 | The game should gracefully handle terminal width variations using shutil.get_terminal_size() | Should |
4. Development Schedule (Gantt Chart)
Note: Create this as a visual Gantt chart using software such as Excel, Google Sheets, or an online Gantt chart tool (e.g. TeamGantt, canva.com). The chart should include the following tasks and phases:
| Phase | Task | Week 1 | Week 2 | Week 3 | Week 4 | Week 5 |
|---|---|---|---|---|---|---|
| Investigate | Research text adventure game mechanics | ████ | ||||
| Investigate | Write problem outline and description | ████ | ||||
| Investigate | Define functional and non-functional requirements | ████ | ||||
| Design | Create structure chart | ████ | ||||
| Design | Create flowcharts | ████ | ||||
| Design | Write pseudocode algorithm | ████ | ||||
| Design | Complete trace tables | ████ | ||||
| Develop | Implement core game engine (GameState, type_text, input_choice) | ████ | ||||
| Develop | Implement story scenes (Chapters 1-2, Hallway, House, Night) | ████ | ████ | |||
| Develop | Implement minigames (typing, math, wordle) | ████ | ||||
| Develop | Implement endings and text distortion effects | ████ | ||||
| Test | Create and execute test plan | ████ | ||||
| Evaluate | Conduct user acceptance testing | ████ | ||||
| Evaluate | Write developer retrospective | ████ |
Milestones:
- End of Week 1: Investigation complete, requirements finalised
- End of Week 2: All design artefacts complete (pseudocode, flowchart, structure chart)
- End of Week 3: Core game engine and first playable prototype working
- End of Week 4: All story scenes, minigames, and endings implemented
- End of Week 5: Testing complete, evaluation written, project submitted
5. Structure Chart
Note: Create this as a visual diagram using software such as draw.io, Lucidchart, or PowerPoint. The hierarchy below describes the structure:
main()
|
┌─────────┬──────┴──────┬──────────┬──────────┐
| | | | |
run_tutorial scene_intro scene_walk scene_ scene_ endings
() _school() _home() parents_ night_ ()
house() text()
|
┌─────────┼──────────┐
| | |
minigame_ minigame_ minigame_
typing() math() wordle()
┌──────────────── Shared Utility Functions ────────────────┐
| |
| type_text() input_choice() apply_text_effects() |
| clear_screen() flush_input() banner() |
| get_width() |
└──────────────────────────────────────────────────────────┘
┌──────────────── GameState Class ─────────────────────────┐
| |
| __init__() |
| set_target_name_by_gender() |
| mod_stats(mem, san) |
| get_missing_name() |
└──────────────────────────────────────────────────────────┘
Module descriptions:
| Module | Purpose | Calls |
|---|---|---|
main() | Entry point; initialises GameState and runs scenes in sequence; handles exceptions | run_tutorial(), scene_intro_school(), scene_walk_home(), scene_parents_house(), scene_night_text(), endings() |
run_tutorial() | Displays title screen, boot sequence, tutorial rules, and collects player name/gender | type_text(), input_choice(), clear_screen(), flush_input() |
scene_intro_school() | Chapter 1: classroom scene, friend interaction, name entry, hallway exploration | type_text(), input_choice(), apply_text_effects(), minigame_typing(), minigame_math() |
scene_walk_home() | Chapter 2: walking home with branching paths (safe, detour, curb) | type_text(), input_choice(), apply_text_effects() |
scene_parents_house() | Optional scene at the missing person’s house with argue/hack/leave choices | type_text(), input_choice(), minigame_wordle() |
scene_night_text() | Final YES/NO choice scene | type_text(), input_choice(), apply_text_effects() |
endings() | Displays one of three endings based on stats and final choice | type_text() |
minigame_typing() | English typing accuracy test with timed sentence display | type_text(), clear_screen(), banner(), flush_input() |
minigame_math() | Progressive difficulty maths quiz (3 rounds) | type_text(), clear_screen(), banner(), flush_input() |
minigame_wordle() | Wordle-style 5-letter word guessing game with coloured feedback | type_text(), clear_screen(), banner(), flush_input() |
type_text() | Typewriter text display with colour, speed, and tenseness parameters | (none) |
input_choice() | Validates player menu input; displays options; returns valid choice | type_text(), flush_input(), get_width() |
apply_text_effects() | Distorts text based on Memory and Sanity stat values | GameState.get_missing_name() |
GameState.mod_stats() | Updates Memory and Sanity values (clamped 0-100) and displays changes | type_text() |
GameState.get_missing_name() | Returns the displayed name for the missing person based on stats | (none) |
6. Flowchart
Note: Create this as a visual flowchart using software such as draw.io, Lucidchart, or PowerPoint. Use standard flowchart symbols (oval for start/end, rectangle for process, diamond for decision, parallelogram for input/output). The logic below describes the main game loop:
Flowchart 1: Main Game Loop
[START]
|
v
[Initialise GameState: memory=100, sanity=100]
|
v
[run_tutorial(): Display title, get gender, get name]
|
v
[scene_intro_school(): Display Chapter 1]
|
v
<Player asked about empty desk>
/ \
"The person "Never mind"
who sits |
there" v
| [Set girl_name_input = target_name]
v [mod_stats(mem=-10, san=+5)]
[Get name input from player] |
| |
v |
<Name matches target_name?> |
/ \ |
YES NO |
| | |
v v |
[mem+5, [mem-5, |
san-5] san+5] |
| | |
v v v
[Run minigame_typing() -> score affects stats]
|
v
[Run minigame_math() -> score affects stats]
|
v
[Display Hallway scene]
|
v
<Hallway choice: Locker / Chatter / Leave>───┐
| | | |
v v v |
[Locker: [Chatter: [Leave: |
san-5, san-5] break] |
mem+5] | | |
| | | |
└──────────┘ | |
| v |
└──── (loop back if not Leave) ────┘
|
v
[scene_walk_home(): Display Chapter 2]
|
v
<Walk choice: Home / Detour / Curb>
/ | \
Home Detour Curb
| | |
v v v
[mem-15, [mem+10, [mem+20,
san+15] san-15, san-20]
parents_ |
house=True] v
| | (loop back)
v v
<parents_house_visited?>
/ \
NO YES
| |
v v
(skip) [scene_parents_house()]
| |
v v
[scene_night_text(): Display final YES/NO prompt]
|
v
<final_choice == "YES"?>
/ \
NO (or san>60 YES
& mem<40) |
| v
v <sanity < 40?>
[ENDING: / \
Ignorance YES NO
is Bliss] | |
v v
[ENDING: [ENDING:
The Equivalent
Keeper] Exchange]
| |
v v
[END] [END]
Flowchart 2: input_choice() Validation Loop
[START: input_choice(options, state)]
|
v
[Display separator line]
|
v
[Display all options with keys]
|
v
[flush_input()]
|
v
[Read user input]
|
v
<Input in valid_keys?>
/ \
YES NO
| |
v v
[Return <sanity < 40?>
choice] / \
YES NO
| |
v v
[Display [Display
hostile normal
error] error]
| |
v v
[Loop back to "Read user input"]
7. Pseudocode Algorithm
BEGIN main
TRY
state ← new GameState()
state.memory ← 100
state.sanity ← 100
// Tutorial and setup
CALL clear_screen()
DISPLAY ASCII art title centred on screen
INPUT "Press Enter to continue"
DISPLAY startup boot sequence lines
DISPLAY tutorial instructions
// Gender and name selection
gender ← CALL input_choice(["Boy", "Girl"], state)
IF gender = "1" THEN
state.player_gender ← "Boy"
state.target_name ← "Husain"
ELSE
state.player_gender ← "Girl"
state.target_name ← "Fatima"
END IF
REPEAT
INPUT player_name
IF player_name = "" THEN
player_name ← "Player"
END IF
IF player_name = "Abdullah" THEN
DISPLAY "Name reserved. Choose another."
ELSE
EXIT LOOP
END IF
UNTIL valid name entered
state.player_name ← player_name
// ---- CHAPTER 1: THE EMPTY DESK ----
CALL clear_screen()
DISPLAY "CHAPTER 1: THE EMPTY DESK"
text ← "You sit in class. To your left, there is an empty desk."
DISPLAY CALL apply_text_effects(text, state)
choice ← CALL input_choice(["The person who sits there.", "Never mind."], state)
IF choice = "1" THEN
INPUT entered_name
state.girl_name_input ← entered_name
IF entered_name = state.target_name THEN
CALL state.mod_stats(mem=+5, san=-5)
ELSE
CALL state.mod_stats(mem=-5, san=+5)
END IF
ELSE
state.girl_name_input ← state.target_name
CALL state.mod_stats(mem=-10, san=+5)
END IF
// Minigames
CALL minigame_typing(state)
CALL minigame_math(state)
// Hallway exploration loop
REPEAT
choice ← CALL input_choice(["Check locker", "Listen to chatter", "Leave school"], state)
IF choice = "1" THEN
DISPLAY "You find a note in your locker."
CALL state.mod_stats(san=-5, mem=+5)
ELSE IF choice = "2" THEN
DISPLAY "You overhear a conversation about someone forgotten."
CALL state.mod_stats(san=-5)
ELSE IF choice = "3" THEN
EXIT LOOP
END IF
UNTIL choice = "3"
// ---- CHAPTER 2: SUBURBIA ----
sat_on_curb ← FALSE
REPEAT
DISPLAY "CHAPTER 2: SUBURBIA"
text ← "The houses all look the same."
DISPLAY CALL apply_text_effects(text, state)
options ← ["Head home", "Detour to house"]
IF NOT sat_on_curb THEN
APPEND "Sit on the curb" TO options
END IF
choice ← CALL input_choice(options, state)
IF choice = "1" THEN
CALL state.mod_stats(mem=-15, san=+15)
EXIT LOOP
ELSE IF choice = "2" THEN
CALL state.mod_stats(mem=+10, san=-15)
state.parents_house_visited ← TRUE
EXIT LOOP
ELSE IF choice = "3" AND NOT sat_on_curb THEN
CALL state.mod_stats(mem=+20, san=-20)
sat_on_curb ← TRUE
END IF
UNTIL choice = "1" OR choice = "2"
// ---- THE HOUSE (conditional) ----
IF state.parents_house_visited THEN
argued ← FALSE
REPEAT
DISPLAY "You knock on the door."
IF NOT argued THEN
options ← {1: "Argue", 2: "Show phone (Hack)", 3: "Leave"}
ELSE
options ← {2: "Show phone (Hack)", 3: "Leave"}
END IF
choice ← CALL input_choice(options, state)
IF choice = "1" AND NOT argued THEN
CALL state.mod_stats(san=-20, mem=+5)
argued ← TRUE
ELSE IF choice = "2" THEN
won ← CALL minigame_wordle(state)
IF won THEN
state.knows_truth ← TRUE
CALL state.mod_stats(mem=+20, san=-20)
END IF
EXIT LOOP
ELSE IF choice = "3" THEN
CALL state.mod_stats(san=+5, mem=-5)
EXIT LOOP
END IF
UNTIL exited
END IF
// ---- NIGHT ----
DISPLAY "NIGHT"
text ← "You are lying in bed."
DISPLAY CALL apply_text_effects(text, state)
DISPLAY "UNKNOWN ID: Do you really want them back?"
state.final_choice ← CALL input_choice(["YES", "NO"], state)
// ---- ENDINGS ----
IF state.final_choice = "2" OR (state.sanity > 60 AND state.memory < 40) THEN
DISPLAY "ENDING: IGNORANCE IS BLISS"
ELSE IF state.final_choice = "1" AND state.sanity < 40 THEN
DISPLAY "ENDING: THE KEEPER"
ELSE IF state.final_choice = "1" THEN
DISPLAY "ENDING: EQUIVALENT EXCHANGE"
END IF
CATCH KeyboardInterrupt
DISPLAY "[SIMULATION TERMINATED]"
CATCH Exception
DISPLAY error message
END TRY
END main
Pseudocode: apply_text_effects(text, state)
BEGIN apply_text_effects(text, state)
processed_text ← text
// Sanity effects: word repetition and creepy insertions
IF state.sanity < 80 THEN
words ← SPLIT processed_text BY spaces
new_words ← empty array
FOR EACH word IN words
APPEND word TO new_words
IF random() < (0.6 - state.sanity / 100) THEN
APPEND word TO new_words // echo effect
END IF
IF state.sanity < 50 AND random() < 0.2 THEN
APPEND "...stop..." TO new_words
END IF
END FOR
processed_text ← JOIN new_words WITH spaces
END IF
// Memory effects: letter replacement with dots
IF state.memory < 80 THEN
chars ← CONVERT processed_text TO character array
FOR i ← 0 TO LENGTH(chars) - 1
IF chars[i] is alphabetic AND random() < (0.6 - state.memory / 100) THEN
chars[i] ← "."
END IF
END FOR
processed_text ← JOIN chars
END IF
// Name replacement based on stats
current_name ← CALL state.get_missing_name()
IF state.girl_name_input IN processed_text AND current_name ≠ state.girl_name_input THEN
REPLACE state.girl_name_input WITH current_name IN processed_text
END IF
RETURN processed_text
END apply_text_effects
Pseudocode: minigame_typing(state)
BEGIN minigame_typing(state)
sentences ← ["The quick brown fox jumps over the lazy dog.",
"Why does nobody else remember the empty desk.",
"Reality is leaking from the corners of this room.",
"Everyone has forgotten about " + state.target_name + " but me."]
target ← random choice FROM sentences
DISPLAY target
// Countdown timer
FOR i ← 5 DOWN TO 1
DISPLAY "Time remaining: " + i
WAIT 1 second
END FOR
CALL clear_screen()
INPUT user_input
// Calculate accuracy score
IF user_input = target THEN
score ← 100
ELSE
matches ← count matching characters at same positions
total ← MAX(LENGTH(user_input), LENGTH(target))
score ← INTEGER(matches / total * 100)
END IF
DISPLAY "Accuracy: " + score + "%"
IF score > 80 THEN
CALL state.mod_stats(mem=+10)
ELSE IF score > 50 THEN
CALL state.mod_stats(san=-5)
ELSE
CALL state.mod_stats(san=-15)
END IF
RETURN score
END minigame_typing
8. Trace Tables
Trace Table 1: Full Playthrough - “Equivalent Exchange” Ending
This trace follows a player who investigates thoroughly, takes the detour, wins Wordle, and says YES.
| Step | Action / Input | memory | sanity | girl_name_input | parents_house_visited | knows_truth | final_choice | Notes |
|---|---|---|---|---|---|---|---|---|
| 1 | GameState initialised | 100 | 100 | "" | False | False | "" | Starting values |
| 2 | Gender: “1” (Boy) | 100 | 100 | "" | False | False | "" | target_name = “Husain” |
| 3 | Name: “Arafat” | 100 | 100 | "" | False | False | "" | player_name = “Arafat” |
| 4 | Chapter 1: Choose “1” (The person who sits there) | 100 | 100 | "" | False | False | "" | Player investigates |
| 5 | Enter name: “Husain” (correct) | 105→100 | 95 | ”Husain” | False | False | "" | mem clamped to 100; mem+5, san-5 |
| 6 | Typing minigame: score 85% | 100 | 95 | ”Husain” | False | False | "" | mem+10 (clamped to 100) |
| 7 | Math minigame: 3/3 correct | 100 | 95 | ”Husain” | False | False | "" | mem+10 (clamped to 100) |
| 8 | Hallway: “1” (Check locker) | 100 | 90 | ”Husain” | False | False | "" | san-5, mem+5 (clamped) |
| 9 | Hallway: “3” (Leave school) | 100 | 90 | ”Husain” | False | False | "" | Exits loop |
| 10 | Suburbia: “3” (Sit on curb) | 100 | 70 | ”Husain” | False | False | "" | mem+20 (clamped), san-20 |
| 11 | Suburbia: “2” (Detour) | 100 | 55 | ”Husain” | True | False | "" | mem+10 (clamped), san-15 |
| 12 | House: “2” (Show phone / Hack) | 100 | 55 | ”Husain” | True | False | "" | Enters Wordle |
| 13 | Wordle: Won | 100 | 30 | ”Husain” | True | True | "" | mem+10 (clamped) + mem+20 (clamped), san-5, san-20. knows_truth=True |
| 14 | Night: “1” (YES) | 100 | 30 | ”Husain” | True | True | ”1” | final_choice = “1” |
| 15 | Endings check: final_choice=“1”, sanity=30 (<40) | 100 | 30 | ”Husain” | True | True | ”1” | ENDING: THE KEEPER |
Note: With sanity at 30 (< 40), this actually triggers “The Keeper” ending. For “Equivalent Exchange”, sanity would need to be >= 40.
Trace Table 2: Safe Playthrough - “Ignorance is Bliss” Ending
This trace follows a player who avoids investigation and chooses safety.
| Step | Action / Input | memory | sanity | girl_name_input | parents_house_visited | final_choice | Notes |
|---|---|---|---|---|---|---|---|
| 1 | GameState initialised | 100 | 100 | "" | False | "" | Starting values |
| 2 | Gender: “2” (Girl) | 100 | 100 | "" | False | "" | target_name = “Fatima” |
| 3 | Name: “Sarah” | 100 | 100 | "" | False | "" | player_name set |
| 4 | Chapter 1: Choose “2” (Never mind) | 90 | 100 | ”Fatima” | False | "" | mem-10, san+5 (clamped). girl_name_input = target_name |
| 5 | Typing minigame: score 40% | 90 | 85 | ”Fatima” | False | "" | san-15 (score < 50) |
| 6 | Math minigame: 1/3 correct | 90 | 65 | ”Fatima” | False | "" | san-10 per wrong answer (x2) |
| 7 | Hallway: “3” (Leave school) | 90 | 65 | ”Fatima” | False | "" | Exits immediately |
| 8 | Suburbia: “1” (Head home) | 75 | 80 | ”Fatima” | False | "" | mem-15, san+15 |
| 9 | Parents house: skipped | 75 | 80 | ”Fatima” | False | "" | parents_house_visited = False |
| 10 | Night: “2” (NO) | 75 | 80 | ”Fatima” | False | ”2” | final_choice = “2” |
| 11 | Endings check: final_choice=“2” | 75 | 80 | ”Fatima” | False | ”2” | ENDING: IGNORANCE IS BLISS |
Trace Table 3: input_choice() with Invalid Input
| Step | user_input | valid_keys | user_in in valid_keys? | sanity | Output |
|---|---|---|---|---|---|
| 1 | ”hello” | [“1”, “2”, “3”] | No | 85 | ”That’s not an option.” (random from normal msgs) |
| 2 | ”5” | [“1”, “2”, “3”] | No | 85 | ”Try again.” (random from normal msgs) |
| 3 | "" | [“1”, “2”, “3”] | No | 85 | ”Focus.” (random from normal msgs) |
| 4 | ”2” | [“1”, “2”, “3”] | Yes | 85 | Returns “2” |