An interactive quiz that determins your moral philosophy profile // ICM W3
Sep 23, 2024
The Idea
Last week in ICM, we explored conditionals like if
, else
, &&
, and ||
. I wanted to use these concepts to create a project that not only incorporates them but also allows the choices made to yield different outcomes based on how users interact with them.
This was the assignment : CREATE • CHOICES
Two roads diverged in a yellow wood, And sorry I could not travel both... Life is full of difficult choices, use conditional statements to control the flow of your programs. Create a sketch that asks people to make difficult choices that have surprising consequences.
Which choices are easier, harder? Which choices are false choices?
What internal or external factors influence the choice? How do others’ choices affect your choices?
What choices surprise you with unexpected outcomes?
Can you combine choices to create hard-to-predict results? (Hint: Use &&
and ||
Concept Overview
I had an idea for an interactive game that would present players with ethical dilemmas and determine their moral philosophy profile based on their choices. I started by sketching out the idea on paper and then some wireframes in Figma to visualize the flow more coherently.
The concept was to have multiple screens: an intro, three ethical dilemmas, and then a result screen showing the player's ethical profile, based on the choices they made.
Initially, I wanted to include tons of features and complex interactions, but I quickly realized I needed to simplify things to actually get a working prototype.
here are the main differences between the first and second iterations and why I made those changes.
First design:
Each screen had unique components and interactions based around buttons.
Required programming mouse X and Y coordinates.
Used the "mouseIsPressed" function to check if the mouse was within the button's area.
Made the code more complex and harder to manage.
Second design:
Simplified by removing the need for mouse interaction.
Switched to the "keyPressed" function to check for specific key inputs.
Created a uniform layout across all screens to maintain consistency.
Nested everything into objects and functions, streamlining the code structure.
Allowed for a functioning prototype without focusing on intricate details.
Foundations
Initially, I approached the project by creating individual functions for each screen. This seemed logical at first, but it quickly became apparent that it wasn't the most efficient method.
This approach worked for a single screen, but as I added more screens and complexity, I realized I needed a more scalable solution, as handling multiple screens and sorting through the code to insert conditional logic became quite hectic.
Embracing Objects and Modularity
After discussing my project with Nikolai, I learned about using objects to structure my code more effectively. This was a game-changer! I created objects for each screen, containing all the necessary text and instructions:
Then, I created corresponding draw functions for each screen:
Implementing Game Logic
In the game, each choice the player makes influences their ethical profile by adjusting the U, V, and D scores. Here's how the scoring system works for each dilemma:
Dilemma 1: The Trolley Problem
Option A (Do nothing): Increases D, decreases U
Option B (Push the stranger): Increases U, decreases V
This dilemma pits utilitarian thinking (saving more lives) against deontological ethics (not using someone as a means) and virtue ethics (the character implications of choosing to end a life directly).
Dilemma 2: The White Lie
Option A (Tell the truth): Increases D, decreases V
Option B (Lie to protect feelings): Increases V, decreases D
This scenario explores the tension between deontological ethics (the duty to tell the truth) and virtue ethics (being kind and considerate).
Dilemma 3: Corporate Whistleblowing
Option A (Report illegal activities): Increases U and V
Option B (Stay silent): Decreases D and V
This dilemma balances utilitarian ethics (preventing environmental damage) against potential negative consequences (job losses). It also involves virtue ethics (integrity and courage) and touches on deontological considerations (the duty to obey the law and prevent harm).
Here's a pseudocode representation of this scoring system:
This scoring system allows for nuanced ethical profiles based on the player's choices. For example:
A player who consistently chooses utilitarian options will end up with a high U score and lower V and D scores.
A player who balances different ethical considerations might have more even scores across U, V, and D.
A player who strongly adheres to one ethical framework while rejecting others might end up with one very high score and two low scores.
Implementing this scoring system required careful consideration of how each choice reflects different ethical frameworks. It also involved deciding how much each choice should impact the scores and ensuring that the final scores would lead to meaningful and varied ethical profiles.
In the actual code, this logic was implemented within the keyPressed() function:
This scoring system forms the foundation of the game's ethical profiling mechanism. It translates the player's choices into a quantifiable ethical stance, which is then used by the profile() function to determine the player's final ethical profile. This was the most challenging part, creating the profile() function to determine the player's ethical profile based on their scores. This required careful consideration of how to define each ethical profile. I did use Claude to help me with the math because I was not able to do the math logic myself but it gave me something that looked like this.
which when translated to code looked something like this -
The Final Product
After a lot of trial and error(and endlessly bothering Nikolai to sit thorough my pseudo code logic) I finally got everything working! Here's the Pseudo code and the complete code:
Final Quiz!
Reflections and Learnings
This project has been an incredible learning experience. I've learned about object-oriented programming, state management, and the importance of systematic debugging. It's amazing how breaking down complex problems into smaller, manageable parts can make such a difference in the development process.
One of the key realizations I had was about the limitations of P5.js when it comes to building more complex applications. While it's great for creating interactive sketches, I found myself struggling as my project grew in scale and complexity. Trying to manage game state, user interactions, and data flow all within a single P5.js sketch made me appreciate why larger applications are often split into backend, frontend, and data structure components. I can now see how separating these concerns into distinct layers could have made this project more manageable and scalable.