ATAR Year 11 Computer Science - Project 1 Part 2
ATAR Year 11 Computer Science - Project 1 Part 2
Development, Testing and Evaluation
Name: Arafat Course: Computer Science - ATAR Year 11 Task: Task 1 - Unit 1
1. Design Updates
Changes from Original Design
The following changes were made to the original design during development:
-
GameState class added: The original pseudocode used individual global variables for stats and flags. During development, these were consolidated into a
GameStateclass to keep all game data in one place. This improved code organisation and made it easier to pass state between functions using a singlestateparameter. -
Text distortion system added: The
apply_text_effects()function was not part of the original design but was added during development to dynamically corrupt displayed text when Memory or Sanity drops. This added significant depth to the gameplay experience. -
Dynamic name system added: The
get_missing_name()method was introduced to make the missing person’s displayed name change based on stats. This was not in the original flowchart but enhanced the psychological horror theme. -
Wordle minigame replaced a simpler puzzle: The original design had a basic number-guessing puzzle at the house scene. This was replaced with a full Wordle-style word game with green/yellow/grey feedback, which was more engaging and complex.
-
Hallway scene added as a loop: The original design had the hallway as a single pass-through. During development, it was changed to a loop allowing the player to explore multiple options before choosing to leave, which gave the scene more content.
-
Fast mode toggle added: A developer convenience feature (
FAST_MODE) was added to skip typewriter delays. This was not in the original design but proved essential for testing.
2. Test Plan and Results
Test Plan Overview
The test plan covers all major game scenarios including normal inputs, boundary cases, invalid inputs, all story pathways, all three endings, and all three minigames. Tests were conducted by running the program and recording actual outputs.
Test Cases
| Test ID | Test Description | Input(s) | Expected Output / Behaviour | Actual Output / Behaviour | Pass/Fail | Notes |
|---|---|---|---|---|---|---|
| T-01 | Program starts without errors | Run python Arafat_Project1Program.py | ASCII art title displays, “Press Enter” prompt appears | ASCII art displayed correctly, centred on screen. Press Enter prompt appeared. | Pass | |
| T-02 | Fast mode via command line | Run python Arafat_Project1Program.py fast | Game runs with no typewriter delay | All text appeared instantly with no character-by-character delay. | Pass | |
| T-03 | Gender selection - Boy | Type 1 at gender prompt | Gender set to Boy, target_name = “Husain" | "Identity confirmed” displayed. Target name set to Husain. | Pass | |
| T-04 | Gender selection - Girl | Type 2 at gender prompt | Gender set to Girl, target_name = “Fatima" | "Identity confirmed” displayed. Target name set to Fatima. | Pass | |
| T-05 | Gender selection - invalid input | Type 3 at gender prompt | Error message displayed, re-prompted | ”That’s not an option.” displayed, prompted again. | Pass | |
| T-06 | Gender selection - text input | Type hello at gender prompt | Error message displayed, re-prompted | ”Focus.” displayed, prompted again. | Pass | |
| T-07 | Name input - valid name | Type Arafat | Name accepted, “Welcome, Arafat.” displayed | ”Welcome, Arafat.” displayed correctly. | Pass | |
| T-08 | Name input - empty string | Press Enter with no text | Name defaults to “Player" | "Welcome, Player.” displayed. | Pass | |
| T-09 | Name input - reserved name “Abdullah” | Type Abdullah | Error: “Name reserved for an existing entity” | Error message displayed, re-prompted for name. | Pass | |
| T-10 | Name input - easter egg “fastmode” | Type fastmode | Fast mode enabled, name set to “Abdullah" | "[FAST MODE ENABLED]” displayed in green. Game proceeded with no delays. | Pass | |
| T-11 | Name input - easter egg “Husain” (as boy) | Type Husain | ”Welcome back.” displayed, target_name changes | ”Welcome back.” displayed in cyan. target_name changed to “Abdullah”. | Pass | |
| T-12 | Chapter 1 - choose to investigate (option 1) | Type 1 at first choice | Prompted to enter missing person’s name | ”You know someone sits there. What is their name?” displayed, input prompt appeared. | Pass | |
| T-13 | Chapter 1 - enter correct name | Type Husain (as boy) | “Yes… Husain. That sounds right.” + mem+5, san-5 | Message displayed. [+5 MEMORY] and [-5 SANITY] indicators shown. | Pass | |
| T-14 | Chapter 1 - enter wrong name | Type John (as boy) | Hint shown: “The name starts with H…” + mem-5, san+5 | Friend responds. Hint “(The name starts with H…)” shown in dim text. Stats updated. | Pass | |
| T-15 | Chapter 1 - choose “Never mind” (option 2) | Type 2 at first choice | ”You stay silent.” + mem-10, san+5 | ”You stay silent. Safer.” displayed. Stats updated correctly. | Pass | |
| T-16 | Typing minigame - perfect score | Type exact sentence shown | ”Accuracy: 100%” + “Excellent.” + mem+10 | Accuracy: 100% displayed. “Teacher: ‘Excellent.’” in green. [+10 MEMORY] shown. | Pass | |
| T-17 | Typing minigame - partial match | Type approximately correct sentence | Accuracy between 50-80% + “Acceptable.” + san-5 | Accuracy: 67% displayed. “Teacher: ‘Acceptable.’” displayed. [-5 SANITY] shown. | Pass | |
| T-18 | Typing minigame - poor performance | Type completely wrong text | Accuracy < 50% + “See me after class.” + san-15 | Accuracy: 12% displayed. “Teacher: ‘See me after class.’” in yellow. [-15 SANITY] shown. | Pass | |
| T-19 | Math minigame - correct answer | Answer 24 to 8 * 3 | ”Correct.” in green | ”Correct.” displayed in green text. | Pass | |
| T-20 | Math minigame - wrong answer | Answer 10 to 8 * 3 | ”Incorrect. Answer: 24” in red + san-10 | ”Incorrect. Answer: 24” displayed in red. [-10 SANITY] shown. | Pass | |
| T-21 | Math minigame - non-numeric input | Type abc instead of number | ”Numbers only.” + san-10 | ”Numbers only.” displayed in yellow. [-10 SANITY] shown. | Pass | |
| T-22 | Math minigame - all correct | Get 3/3 correct | mem+10 bonus | [+10 MEMORY] displayed after completing all 3 problems. | Pass | |
| T-23 | Hallway - check locker | Type 1 | Note found + san-5, mem+5 | ”Inside, you find a note: ‘Husain was here’.” displayed in yellow. Stats updated. | Pass | |
| T-24 | Hallway - listen to chatter | Type 2 | Overheard conversation + san-5 | Student dialogue displayed. [-5 SANITY] shown. | Pass | |
| T-25 | Hallway - leave school | Type 3 | Exits hallway loop | ”You push through the heavy double doors.” displayed. Scene ended. | Pass | |
| T-26 | Suburbia - head home (safe) | Type 1 | mem-15, san+15 | ”You keep your head down.” displayed. Stats updated. Proceeds to Night scene. | Pass | |
| T-27 | Suburbia - detour to house | Type 2 | mem+10, san-15, parents_house_visited=True | ”You take a sharp left turn.” displayed. Stats updated. House scene triggered. | Pass | |
| T-28 | Suburbia - sit on curb | Type 3 | mem+20, san-20. Option 3 disappears on next loop | ”You sit on the rough concrete.” displayed. Stats updated. On next iteration, only options 1 and 2 shown. | Pass | |
| T-29 | Suburbia - curb used twice | Type 3 twice | Second attempt: option 3 not available | After first use, only options “1” and “2” displayed. Option 3 removed from menu. | Pass | |
| T-30 | House - argue | Type 1 | Screaming scene + san-20, mem+5. Argue option disappears. | ”You scream at them.” displayed with high tenseness. Stats updated. On re-prompt, only options 2 and 3 shown. | Pass | |
| T-31 | House - show phone (Wordle) | Type 2 | Wordle minigame launches | Wordle game started with “Enter 5-letter password to unlock.” | Pass | |
| T-32 | Wordle - correct guess | Guess correct word | ”ACCESS GRANTED” + wallpaper reveal + mem+20, san-20 | ”ACCESS GRANTED.” in green. Photo revealed. knows_truth set to True. | Pass | |
| T-33 | Wordle - 5-letter validation | Type cat (3 letters) | “Must be 5 letters." | "Must be 5 letters.” displayed in yellow. Re-prompted without losing a guess. | Pass | |
| T-34 | Wordle - all guesses used | Use 6 wrong guesses | ”ACCESS DENIED” + san-10 | ”ACCESS DENIED.” displayed in red. [-10 SANITY] shown. | Pass | |
| T-35 | Wordle - high memory hint | Start Wordle with memory > 90 | Answer revealed in dim text | ”(YOU HAVE HIGH MEMORY! THE WORDLE’S ANSWER IS: GHOST)” displayed. | Pass | |
| T-36 | House - apologize/leave | Type 3 | san+5, mem-5 | Scene ended. Stats updated. Proceeded to Night. | Pass | |
| T-37 | Night - choose YES | Type 1 | final_choice = “1” | Proceeds to endings with final_choice set. | Pass | |
| T-38 | Night - choose NO | Type 2 | final_choice = “2” | Proceeds to endings with final_choice set. | Pass | |
| T-39 | Ending: Ignorance is Bliss | NO chosen | ”You never think of [name] again.” + ending title | ”ENDING: IGNORANCE IS BLISS” displayed. “Thank you for playing.” shown. | Pass | |
| T-40 | Ending: The Keeper | YES chosen, sanity < 40 | Phone melts, white room scene | ”ENDING: THE KEEPER” displayed. Dramatic text about remembering. | Pass | |
| T-41 | Ending: Equivalent Exchange | YES chosen, sanity >= 40 | Target returns, player fades | ”ENDING: EQUIVALENT EXCHANGE” displayed. Player’s hands fading. | Pass | |
| T-42 | Ending: Ignorance (stat override) | YES chosen but sanity > 60 and memory < 40 | Overridden to Ignorance despite YES | ”ENDING: IGNORANCE IS BLISS” displayed even though player chose YES. | Pass | Stats override the choice |
| T-43 | Text distortion - low sanity | Play with sanity < 50 | Words repeated, “…stop…” inserted | Text contained echoed words and occasional “…stop…” insertions. | Pass | |
| T-44 | Text distortion - low memory | Play with memory < 50 | Letters replaced with dots | Text contained scattered dots replacing alphabetic characters. | Pass | |
| T-45 | Name display - low memory | Play with memory < 30 | Name reverts to target_name | Despite entering a custom name, the game displayed the default target_name. | Pass | |
| T-46 | Name display - low sanity | Play with sanity < 30 | Name replaced with “THEY” | The missing person’s name appeared as “THEY” in all dialogue. | Pass | |
| T-47 | Keyboard interrupt handling | Press Ctrl+C during gameplay | ”[SIMULATION TERMINATED]” displayed, clean exit | ”[SIMULATION TERMINATED]” displayed. Program exited without traceback. | Pass | |
| T-48 | Invalid input - repeated attempts | Enter invalid input 5 times in a row | Error messages each time, no crash | Different error messages displayed each time (randomly selected). Program continued to re-prompt. | Pass | |
| T-49 | Invalid input - low sanity messages | Enter invalid input with sanity < 40 | Hostile error messages | Messages like “Stop it.”, “WRONG.”, “There is no escape.” displayed. | Pass | |
| T-50 | Terminal width handling | Run in narrow terminal (40 cols) | Game adapts to terminal width | Banner separators and centring adjusted to narrower width. No overflow. | Pass |
3. User Acceptance Testing (UAT)
3.1 Evaluation Against Functional Requirements
| Req ID | Requirement | Met? | Evidence / Comments |
|---|---|---|---|
| FR-01 | Title screen with ASCII art and typewriter effect | Yes | The run_tutorial() function displays centred ASCII art spelling “spin” and uses type_text() for all narrative text with character-by-character printing. |
| FR-02 | Gender selection determines missing person’s name | Yes | set_target_name_by_gender() sets “Husain” for boys and “Fatima” for girls. Verified in T-03 and T-04. |
| FR-03 | Name input with validation | Yes | Empty input defaults to “Player”. “Abdullah” is rejected with error message. Verified in T-07, T-08, T-09. |
| FR-04 | Memory and Sanity tracked (0-100) | Yes | mod_stats() uses max(0, min(100, ...)) to clamp values. Stats persist across all scenes via the GameState object. |
| FR-05 | Stat changes displayed with colour | Yes | mod_stats() calls type_text() with cyan for Memory and magenta for Sanity, showing signed values like [+10 MEMORY]. |
| FR-06 | Multiple-choice with input validation | Yes | input_choice() accepts both list and dict formats, validates against valid_keys, and loops until valid input is received. |
| FR-07 | Typing accuracy minigame | Yes | minigame_typing() displays a sentence from a list of 4 options, counts down 5 seconds, clears screen, accepts input, and calculates character-by-character accuracy. |
| FR-08 | Maths quiz with progressive difficulty | Yes | minigame_math() runs 3 rounds with increasing number ranges (difficulty multiplier). Operations include +, -, *. |
| FR-09 | Wordle minigame with coloured feedback | Yes | minigame_wordle() implements full Wordle logic: green (correct position), yellow (wrong position), grey (not in word). 6 attempts allowed. |
| FR-10 | Multiple story paths | Yes | Three paths in Suburbia (home, detour, curb), optional House scene with three sub-choices, Hallway with three exploration options. |
| FR-11 | Three distinct endings | Yes | ”Ignorance is Bliss”, “The Keeper”, and “Equivalent Exchange” each have unique narrative text and different trigger conditions. |
| FR-12 | Arrays for related data | Yes | sentences list in typing minigame, WORDS_LIST for Wordle, startup_lines in tutorial, msgs for error messages, ops for math operators. |
| FR-13 | Functions with parameters | Yes | 15+ functions use parameters: type_text(text, speed, color, new_line, tenseness), input_choice(options, state, prompt), apply_text_effects(text, state), mod_stats(mem, san), etc. |
| FR-14 | Dynamic text distortion | Yes | apply_text_effects() introduces word echoing below sanity 80, “…stop…” below sanity 50, and dot replacement below memory 80. |
| FR-15 | Dynamic name swapping | Yes | get_missing_name() returns different names based on stat thresholds: the typed name, the default target name, or “THEY”. |
| FR-16 | Graceful KeyboardInterrupt handling | Yes | main() wraps the entire game in a try/except that catches KeyboardInterrupt and displays “[SIMULATION TERMINATED]”. |
| FR-17 | Fast mode toggle | Yes | Activated via command-line argument fast or by typing “fastmode” as the player name. Sets all type_text delays to 0. |
3.2 Evaluation Against Non-Functional Requirements
| Req ID | Requirement | Met? | Evidence / Comments |
|---|---|---|---|
| NFR-01 | Runs in standard ANSI terminal | Yes | Tested on Windows (cmd, PowerShell) and Linux terminals. ANSI codes render correctly. Falls back to basic text if codes are unsupported. |
| NFR-02 | Meaningful naming conventions | Yes | All functions use snake_case (type_text, input_choice, scene_walk_home). Variables are descriptive (player_name, memory, sanity, target_name). Class uses PascalCase (GameState). |
| NFR-03 | Comments explaining purpose | Yes | Every function has a comment or docstring explaining its purpose. Key logic sections (stat clamping, wordle colouring, text effects) have inline comments. |
| NFR-04 | Consistent indentation and whitespace | Yes | 4-space indentation used throughout. Blank lines separate logical sections. Functions are separated by blank lines. |
| NFR-05 | Engaging typewriter pace | Yes | Default speed of 0.04s per character with punctuation pauses (0.6s for .!?:, 0.2s for ,). Tenseness parameter adds dramatic slowdown. |
| NFR-06 | Completable in 10-15 minutes | Yes | A full playthrough takes approximately 8-12 minutes with normal text speed, or 2-3 minutes in fast mode. |
| NFR-07 | Clear input prompts | Yes | Menu options are displayed in [1] Description format with a separator line. Input prompt uses > prefix. |
| NFR-08 | Terminal width adaptation | Yes | get_width() uses shutil.get_terminal_size() with a fallback of 70 columns. Banner and art centring use this width dynamically. |
3.3 User Experience Discussion
Clarity of text: The typewriter effect makes text engaging to read and creates an atmosphere matching the psychological horror theme. Colour-coded stat changes (cyan for Memory, magenta for Sanity) provide clear feedback without interrupting the narrative flow.
Difficulty level: The minigames are appropriately challenging. The typing test has a 5-second memorisation window, the math quiz scales difficulty across 3 rounds, and the Wordle game provides 6 attempts. The high-memory hint for Wordle rewards players who have been investigating.
Pacing: Dramatic scenes use the tenseness parameter to slow text, creating atmosphere. Action scenes use faster text. The pause pattern on punctuation (longer pauses on periods and question marks) creates a natural reading rhythm. Fast mode is available for replays.
Replayability: The gender choice, name entry, stat-driven text distortion, multiple story paths, and three endings provide meaningful replay value. Easter eggs reward exploration.
3.4 Peer Testing Feedback
A classmate tested the game and provided the following feedback:
- Positive: “The text effects when sanity drops are creepy and cool. The Wordle minigame was a fun surprise. The endings feel different enough to want to replay.”
- Suggestions: “Sometimes the typewriter effect is a bit slow during long paragraphs. Having a skip button would be nice. The math minigame could have more variety.”
- Bugs found: No game-breaking bugs were found during peer testing.
3.5 Known Bugs and Limitations
| Bug/Limitation | Impact | Severity |
|---|---|---|
eval() used for maths answer calculation | Works correctly for the limited operations used (+, -, *) but is generally considered unsafe for arbitrary input. Since only the game generates the expression (not the user), this is low risk. | Low |
| ANSI colours may not display on all terminals | Older Windows terminals (pre-Windows 10) may show raw escape codes instead of colours. | Low |
flush_input() may not work on all platforms | The function uses platform-specific modules (msvcrt on Windows, termios on Linux). If neither is available, it silently fails. Input buffering could cause skipped prompts. | Low |
| Wordle word list fallback is small | If wordle.txt is missing, only 7 words are available, making the game easier. | Medium |
| No save/load system | The game must be completed in one session. Closing the terminal loses all progress. | Medium |
| Text distortion can make text unreadable | At very low Memory (< 20), so many letters are replaced with dots that key narrative text becomes hard to read. | Low (intentional design) |
4. Developer Retrospective
4.1 What Worked Well
GameState class design: Consolidating all game variables into a single GameState class was a decision made early in development. This made it straightforward to pass game state between functions using a single state parameter and kept the code organised. Adding new flags (like knows_truth or parents_house_visited) was as simple as adding a new attribute to __init__.
Modular scene structure: Breaking the game into separate scene functions (scene_intro_school(), scene_walk_home(), etc.) made it easy to develop and test each scene independently. The main() function simply calls them in sequence, making the overall game flow easy to understand and modify.
Text effects system: The apply_text_effects() function added significant atmospheric depth with relatively simple logic (word duplication for low sanity, character replacement for low memory). This mechanic received positive feedback from testers and differentiated the game from a basic choice-based story.
Input validation approach: The input_choice() function handles all user input in one place, supporting both list and dictionary option formats. The sanity-sensitive error messages were a creative touch that reinforced the game’s theme.
4.2 What Did Not Work Well
Testing difficulty with typewriter effect: During development, testing was slow because every text display had a delay. The FAST_MODE toggle was added partway through development, and earlier testing would have been faster if it had been implemented from the start.
Hardcoded story content: All narrative text is embedded directly in the scene functions. For a larger game, this would become unmanageable. Separating story content into a data file or dictionary would have made editing and expanding the story easier.
Limited error handling in minigames: The maths minigame uses a bare except: clause which catches all exceptions, not just ValueError. This is bad practice as it could mask unexpected errors. A specific except ValueError: would be more appropriate.
Platform-specific code: The flush_input() function and os.system('cls'/'clear') calls introduce platform-specific behaviour. While the game works on both Windows and Linux, a more abstracted approach would improve portability.
4.3 What I Would Do Differently Next Time
Plan the stat balance earlier: The Memory/Sanity system required significant tweaking to ensure all three endings were reachable. Planning the stat economy (which choices give which values) on paper before coding would have saved time.
Separate content from logic: I would store all narrative text, option lists, and scene descriptions in a separate data structure (such as a dictionary or JSON file) rather than embedding them in function code. This would make it easier to edit the story without touching game logic.
Write tests alongside code: Rather than testing at the end, I would test each function as it was written. The minigames in particular had subtle bugs (e.g. the Wordle colour logic incorrectly marking duplicate letters) that took time to find because they were tested late.
Add a save system: The game has enough content that losing progress on a crash is frustrating. Implementing a simple save/load system (writing GameState attributes to a file) would improve the user experience.
Use specific exception handling: Replace bare except: clauses with specific exception types (except ValueError:, except FileNotFoundError:) to avoid silently catching unexpected errors during development.
5. Sources and Ethical Considerations
5.1 Sources Used
| Source | How It Was Used |
|---|---|
| Python 3 Official Documentation (docs.python.org) | Reference for standard library functions: shutil.get_terminal_size(), sys.stdout.write(), time.sleep(), random.choice(), base64.b64encode(). |
| Stack Overflow (stackoverflow.com) | Looked up how to flush terminal input on Windows (msvcrt) and Linux (termios). Adapted the approach for the flush_input() function. |
| Real Python (realpython.com) | Tutorial on ANSI escape codes for terminal colours. Used as reference for the colour dictionary in type_text(). |
| Wordle (New York Times) | The Wordle minigame is inspired by the word game Wordle. The green/yellow/grey feedback mechanic was implemented based on the publicly known rules of the game. |
| Class notes and textbook | Python control structures, functions, parameters, and lists. Pseudocode syntax conventions. |
5.2 Avoiding Plagiarism
All code in this project was written by me. The following elements were adapted from external sources:
flush_input()function: The approach of usingmsvcrt.kbhit()on Windows andtermios.tcflush()on Linux was adapted from Stack Overflow answers discussing terminal input buffering. The implementation was rewritten to fit the project’s needs.- ANSI colour codes: The escape code values (e.g.
\033[91mfor red) are standard terminal codes documented in many sources. The colour dictionary structure was my own design. - Wordle logic: The green-pass-then-yellow-pass algorithm for letter colouring is based on the publicly documented rules of Wordle. The implementation is original.
No code was directly copied from any source. All adapted techniques were rewritten and integrated into the project’s specific architecture.
5.3 Open Source and Licensing Considerations
- The project uses only Python standard library modules (
sys,time,random,os,shutil,math,base64). No third-party libraries or packages are used. - The optional
wordle.txtword list, if used, should be sourced from a public domain or openly licensed word list. The fallback list embedded in the code consists of common English words and does not require licensing. - No external images, sounds, or graphical assets are used (the game is entirely text-based).
- The ASCII art in the title screen is original.