Assignment 4: Cards For Humanity

For this assignment, I wanted to create a generative text output. I was thinking of games that play with words and phrases and I immediately thought of Cards Against Humanity. So I wanted to create a PG version that just uses playful humor and thus called it “Cards For Humanity”:)

The way my game is played is that the user first clicks on the deck of black cards and reads the prompt. Then, they will click on the deck of white cards and read the comical response. They can then click the button below to try multiple rounds. It is based on the party game below:
The part of my code that I want to highlight shows how I fit the varying text within the card. Since I didn’t want to limit the length of the text or the size of the font, I could only make the text fit by separating it into different lines. Words are added to the same line until it exceeds the max length.

function drawSelectedCard(x, y, cardText, isBlack) {
  fill(isBlack ? 0 : 255); //checks if card is from black deck and assigns color
  rect(x, y, cardWidth, cardHeight, 10);

  fill(isBlack ? 255 : 0); //text color opposite to card

  // Split the card text into lines to fit within the card
  let lines = splitLines(cardText, 70); //Maximum characters per line set to 70

  // Display each line of text within the card
  for (let i = 0; i < lines.length; i++) {
    text(lines[i], x + cardWidth / 2, y + cardHeight / 2 - (lines.length - 1) * 10 + i * 20); //vertical centering
  }
}

function splitLines(text, maxLength) {
  let words = text.split(' '); //split text into array of words
  let lines = [];
  let currentLine = '';

  for (let i = 0; i < words.length; i++) {
    if (textWidth(currentLine + words[i]) <= maxLength) { //checks if adding the current word to the current line exceeds the maximum length
      currentLine += words[i] + ' '; }
    else {
      //if the max length is exceeded, push the current line to the array and start a new line
      lines.push(currentLine);
      currentLine = words[i] + ' ';
    }
  }

  lines.push(currentLine); //push the last line to the array
  return lines; 
}

Overall, I am happy with the output. I would like to work further on this by adding more amusing prompts and responses. I would also like to improve the game by letting the user choose the best response from their set of already-selected white cards, like the actual game. Lastly, I could organize my code better by using OOP and making the cards objects.

Assignment #4 – Code – ☆Meticulous Misleading☆

When we learned how to do data visualization, I immediately knew that this is what I wanted to do for this assignment. I find data very interesting, but probably not for the reasons you think. Ever since I am little, my dad tells me to think about and interpret data critically. In fact, data is very nuanced in the media. In many aspects of journalism, digital or not, the data may be honest. However, it is not about the data itself. It is about how it is presented.

I remember one instance two years ago: my dad showed me a  two-sided graph comparing deaths due to two different factors over time (I can’t remember what the factors were, nor can I find the picture unfortunately). At first glance, the two graphs seemed pretty similar. But after looking closely, the x-axis for factor A went from 0 to 10, whereas the x-axis for factor B went from 0 to 100. Therefore, the visual representation was very misleading. So, data is in fact about how it is presented, and often, it will be presented in a way that favors the author’s argument despite it being deceitful – whether that be by withdrawing or skewing information

For this assignment, then, I wanted to visualize data in a way that would say ABSOLUTELY NOTHING to the reader. I just wanted to make a sort of artwork with it to prove my point. I searched for “art” on Kaggle, and found a sheet containing the artists whose works are featured in the MoMA collection. Here is the link to the file: https://www.kaggle.com/datasets/momanyc/museum-collection

And here is my sketch:

The data I first wanted to visualize was the gender of the artists, in order to create some sort of visual comparison between the number of male and female artists featured in the collection. For that, I mapped the birth and death years to the canvas, which I then used to represent circleX and circleY respectively (I ended up switching from circles to points, so I just used circleX and circleY as the coordinates for the latter). I then used an if else function to attribute the colors green to female artists and orange to male artists.

Then, I started working on turning the visualization into an inaccurate/incomplete one:

  1. I changed the mapping to include birth years only after 1850, although some were born between 1730 and then. Similarly, I only included the artists who died after 1900, though some died between 1795 and then.
  2. I added 50 to both the width and the height in the mapping in order to “enlarge” the position of the sketch.
  3. I added a random component to circleX and circleY, which slightly randomized the position of each point, making it dynamic.
  4. I used the sin function to randomize the size of each point. Some are therefore bigger, and some are smaller, creating some sort of “illusion” when it comes to the data.
  5. I animated the background to transition from orange to green to black continuously. This way, you sometimes see all the points, sometimes only the green ones, and sometimes only the orange ones. It all depends then on at which point of the sketch you look, and you will see different things.
  6. Finally, I set the alpha of the background to 70 in order to have a trail. This gives the impression of having more points than there actually are.

For parts 5 and 6, here is the code:

//   mapping the sin value to different colors
let sinValue = (sin(angle) + 1) / 2;

let r, g, b;

if (sinValue < 1 / 3) {
  // transitions from black to green
  r = map(sinValue, 0, 1 / 3, 0, 215);
  g = map(sinValue, 0, 1 / 3, 0, 234);
  b = map(sinValue, 0, 1 / 3, 0, 193);
} else if (sinValue < 2 / 3) {
  // transitions from green to orange
  r = map(sinValue, 1 / 3, 2 / 3, 215, 232);
  g = map(sinValue, 1 / 3, 2 / 3, 234, 103);
  b = map(sinValue, 1 / 3, 2 / 3, 193, 42);
} else {
  // transitions from orange back to black
  r = map(sinValue, 2 / 3, 1, 232, 0);
  g = map(sinValue, 2 / 3, 1, 103, 0);
  b = map(sinValue, 2 / 3, 1, 42, 0);
}

background(r, g, b, 70);

I feel like I’ve achieved what I wanted to, and as usual, it has been a learning process. I would say I didn’t really encounter any difficulties, I just had fun practicing data visualization especially in my own little way 🙂

 

Assignment 4 – Mood clock

For this assignment, I was inspired by the fluid nature of emotions and how our surroundings can influence our mood throughout the day. It got me thinking about the concept of time and its relentless, cyclical pattern. This reflection led me to ponder the idea of visualizing time not just as a sequence of numbers but as an ever-changing spectrum of emotions. What if we could see the time of day reflected through our moods?

**double click on the sketch to interact**

It incorporates a real-time clock, showing hours, minutes, and seconds, alongside a pulsating ellipse that grows and shrinks with each passing second. The background color shifts through various hues—each representing a different mood such as “Dreamy,” “Energetic,” “Calm,” and “Reflective”—as the day progresses. But here’s the twist: users can manually switch between these moods with the press of a key, creating a playful interaction between the digital environment and the user’s current emotional state.

//change mood based on time if the user didn't select any
  if(mood == ""){
  if (hours < 6) {
    def = "Dreamy";
  } else if (hours < 12) {
    def = "Energetic";
  } else if (hours < 18) {
    def = "Calm";
  } else {
    def = "Reflective";
  }
    mood=def;
  }

  //Change background color based on the selected mood
  switch (mood) {
    case "Dreamy":
      bgColor = background(120, 113, 255);
      break;
    case "Energetic":
      bgColor = background(255, 213, 0);
      break;
    case "Calm":
      bgColor = background(0, 255, 183);
      break;
    case "Reflective":
      bgColor = background(255, 105, 180);
      break;
    default:
      bgColor = background(0); 
  }

Adding more interactive elements, such as allowing users to input their current mood or introducing more complex animations that respond to the time of day, are just a couple of ideas I’m exploring. And I really hope the mood clock would allow people to sit and reflect on their emotions throughout the day.

Week 4: Reading Response by Sihyun Kim

After reading chapter one of the book entitled “The Design of Everyday Things”, I found myself agreeing with the main argument that the author makes in his book. In this book, the author talks about what makes a good design. I think the most important argument he makes is that the two of the most important characteristics of good design are discoverability and understanding. Discoverability indicates that the user should be able to figure out what actions are possible and how to perform them and understanding indicates what all functions mean and how the product is supposed to be used. I agree with him that discoverability and understanding are the key features of what makes a good design. I also believe that a design is called “good” when it is intuitive whereas we could figure out how to use the object and all the purpose of it at first glance. 

I agree with the author in his argument about how we are so “machine-centered” instead of being “human-centered”.When the user is not able to use a machine properly, we often tend to blame the user for not being able to figure out how to use the machine instead of thinking about the machine as “poorly designed.”  This machine-centered mindset is something that I also noticed in my surroundings. I also believe that this is the mindset of the engineers who build and design the machines. I find some machines very complicated to use even with the user’s guide. Sometimes, I think the machines are too focused on the “technical requirements” that they forget to consider human behavior. I find it quite ironic that machines that are built for people fail to consider the “people”. 

Then, I came to think that this might be the paradox of technology- as it is more developed to offer more technological benefits to the users, the more it becomes difficult to use. Technology can simplify yet complicate our lives. This idea made me think that one of the most concerning challenges to the designers would be how they should balance the desire for more developed technologies and functions with the need for simple and human-centered design. As the author argues, the more the technology develops and the machines become multifunctional, the more the machine is prone to make the users become overwhelmed and frustrated. In a way, I think that it is the job of the designers to make complicated things look “simple and easy” to use.

Also, I thought that a “good design” that satisfies everyone  becomes harder to achieve as the machines add more functions. And I thought that a good design might be something “subjective”  instead of  “objective”. As the author says, what a person finds intuitive is based on that person’s experience. To someone who is used to technology and machines, a newly-built machine might seem to be very intuitive and user-friendly even without reading the user’s guide, but the machine might seem to be “poorly designed” for someone who is not familiar with the machines. Perhaps, to the engineers who are so used to all that logic and orders of machines, the machines that the public perceived to be “poorly designed” might have been intuitive. Likewise, when the machines get more complicated, while there might be a design that the “majority” can satisfy, I think there might not be a design that “everyone” can satisfy. 

Overall, I truly found the reading very interesting and engaging. Also, the reading made me reconsider what a good design is. After all, this reading made me think that a good design is a design that is intuitive and that a good design is subjective based on the experience of the users as what a person thinks of as intuitive differs from the person’s prior knowledge and experience. 

 

Assignment 4 – Matrix Letters

From this assignment, I took direct inspiration from the Matrix franchise to recreate their famous wall of green symbols.

18 ans plus tard, on connaît enfin la signification du code vert de la ...

At its core, the project consists of two main classes: MatrixSymbol and Stream.

    1. MatrixSymbol Class:
      • Each character falling down the screen is represented by an instance of the MatrixSymbol class.
      • The MatrixSymbol class is responsible for storing properties such as position (x, y), character value (value), speed (speed), and brightness (brightness).
      • Characters are randomly selected from a wide range of Unicode characters, including hiragana and kanji, providing diversity to the falling text effect.
      • The rain() method handles the downward movement of the symbol, ensuring it wraps back to the top of the screen when reaching the bottom.
    2. Stream Class:
        • A stream consists of multiple MatrixSymbol instances, forming a vertical column of falling text.
        • Each stream is generated with a random number of symbols (totalSymbols) and a random speed (speed).
        • The generateSymbols() method populates the stream with symbols, positioning them at random vertical offsets to create a staggered appearance.
        • The render() method displays and animates the symbols within the stream, applying color variation to enhance visual appeal.

      The brightness of each symbol is randomly adjusted, creating subtle variations in color and brightness, adding depth to the visual effect.
      Unicode Character Range: By utilizing a wide range of Unicode characters, including hiragana and kanji, I achieve a diverse selection of symbols.

Challenges:

Ensuring a balanced distribution of hiragana and kanji characters while maintaining randomness posed a challenge. Fine-tuning the character ranges was necessary to achieve a visually appealing mix.
As well, as the number of symbols and streams increases, performance may degrade. Thus it was important for me to write efficient code which would not suffer from performance degradation.

 

 

Reading Reflection Week 4 – Dachi Tarughishvili

Don Norman, author of “Design of Everyday Things” brings various examples and concepts when it comes to technology and challenges that arise with designing devices we use in our everyday lives. The thing that stood out to me the most was his example of a watch with four buttons. The whole paragraph talks about how it makes the user experience less enjoyable since now the watch is not merely about checking time but also providing users with additional functions. While the premise of a more feature-packed piece of technology is quite optimistic, the reality of it only confuses the vast majority of users as it takes away from its main function. Expanded this to today, this remains true. I personally own a smartwatch. Initially, I thought it would be very useful and offer numerous features. While it does all that, after the initial novelty wore off, I saw why so many people dislike them. There is no disagreement that some of these features are quite useful: instant notifications from your phone, the ability to call, reply to messages, check different apps, and so on. However, we already have peace of technology that provides all that and the purpose of the watch is redirected to a compromised clone of such device. Small screen, limited performance, difficulty interacting with UI and small buttons, and abundance of features I will probably never use, are the same sort of challenges Norman talked about. The fact that I have to charge it every day to keep it going puts a huge barrier to usability.
At the end of the day, a watch should serve one function, to display time at a quick glance. How many of us, have used our smartphones to do that even though we ourselves have digital watches on our wrists? We are sacrificing user-friendly design for the sake of complexity. It is a product that tries to be sophisticated – a jack of all trades but never excelling at anything in particular. Even when it comes to displaying time, the options and different layouts get overwhelming. This design ignores fundamental elements of good design which are simplicity, clarity, and ease of use. And what if something goes wrong? It is not a simple repair. It is attractive but not that affordable. Do I regret my purchase? Not really. At least I used it for my homework reflection.

Reading Response Week 4

One of the aspects that piqued my interest in the reading was the paradox of technology. It is without a doubt that things tend to get replaced as newer and better technology emerges. As the complexity increases alongside it, I believe there is certain fragility that comes with as well. In the case of watches, as it evolves to maximize efficiency there could be certain capabilities that are sacrificed in order to achieve that. These sacrifices are what causes these fragilities. This leads to the question of whether there should be balance between them, as this could lead to lower efficiency. I think that there are many examples of products that is made with this in mind, but they are not particularly regarded as better in this society’s standards.

In regards to design, I often noticed that when something has a good design, it is rarely notices, but if it has a bad design, the annoyances are highlighted much easily. When the design is good, there seems to be a certain smoothness within the system, but if the design is bad, certain redundancy or annoyances are to be found. With a good conceptual model, the communication between the design and the user becomes less confusing. With complex operating systems like Microsoft, it contains numerous manuals but when there are certain errors, troubleshooting it becomes more and more vague in some cases therefore requiring additional help, which I believe is large but inevitable design flaw.

Week 4: Hangman

The concept for this week’s assignment, I wanted to make a hangman word game. The code consists of helper functions such as keyPressed, startNewGame, checkGuess etc. Firstly, it creates a number of empty dashes  based on the number of letters in the chosen word. As a letter is pressed, dashes are changed to a letter if the letter is in the word, and the body of the hangman is drawn if it is not. At the end of the game, it checks if the user guessed the word correctly, and shows corresponding texts.

Further on, I would like to add randomized word generation or read from csv or text file large pool of words.

code:

let word;
let guessedWord;
let maxAttempts = 6
let attemptsLeft = maxAttempts;
let guessedLetters = [];

function setup() {
  createCanvas(400, 400);
  textAlign(CENTER, CENTER);
  startNewGame();
}

function draw() {
  background(220);

  // Display hangman
  drawHangman();

  // Display guessed word
  textSize(32);
  text(guessedWord.join(' '), width / 2, height / 2 - 20);

  // Display attempts left
  textSize(16);
  text(`Attempts left: ${attemptsLeft}`, width / 2, height - 20);

  // Display guessed letters
  text(`Guessed letters: ${guessedLetters.join(', ')}`, width / 2, height - 40);

  // Check for game over
  if (attemptsLeft === 0 || guessedWord.indexOf('_') === -1) {
    gameOver();
  }
}

function keyPressed() {
  if (keyCode === ENTER) {
    startNewGame();
  } else if (key >= 'a' && key <= 'z' && !guessedLetters.includes(key)) {
    checkGuess(key);
  }
}

function startNewGame() {
  // List of possible words
  let words = ["apple", "banana", "simulation", "problems", "reaction"];

  // Choose a random word
  word = random(words).split('');

  // Initialize guessedWord with underscores
  guessedWord = Array(word.length).fill('_');

  // Reset attempts
  attemptsLeft = maxAttempts;

  // Reset guessed letters
  guessedLetters = [];
}

function checkGuess(letter) {
  // Add guessed letter to the list
  guessedLetters.push(letter);

  // Check if the letter is in the word
  let correctGuess = false;
  for (let i = 0; i < word.length; i++) {
    if (word[i] === letter) {
      guessedWord[i] = letter;
      correctGuess = true;
    }
  }

  // Decrease attempts if the guess is incorrect
  if (!correctGuess) {
    attemptsLeft--;
  }
}

function drawHangman() {
  stroke(0);
  
  line(width / 2 - 100, height /2 - 80 ,width /2 - 50, height /2 -80)
  line(width / 2 - 75, height / 2 -80, width / 2 -75, height /2 - 180)
  line(width / 2 -75, height / 2 - 180, width / 2, height / 2 - 180)
  line(width / 2, height / 2 - 180, width / 2, height / 2- 160)
  
  // Head
  if (attemptsLeft < maxAttempts) {
    ellipse(width / 2, height / 4 - 50, 20, 20)
  }

  // Body
  if (attemptsLeft < maxAttempts - 1) {
    line(width / 2, height / 4 - 40, width / 2, height / 2 - 80);
  }

  // Left arm
  if (attemptsLeft < maxAttempts - 2) {
    line(width / 2, height / 4 -30, width / 2 - 20, height / 4-10 );
  }

  // Right arm
  if (attemptsLeft < maxAttempts - 3) {
    line(width / 2, height / 4 -30, width / 2 + 20, height / 4 -10);
  }

  // Left leg
  if (attemptsLeft < maxAttempts - 4) {
    line(width / 2, height / 2 - 80, width / 2 - 20, height / 2 -60);
  }

  // Right leg
  if (attemptsLeft < maxAttempts - 5) {
    line(width / 2, height / 2 -80, width / 2 + 20, height / 2 -60);
  }
}

function gameOver() {
  // Display game over message
  textSize(16);
  if (guessedWord.indexOf('_') === -1) {
    text("You guessed the word!", width / 2, height / 2 + 60);
  } else {
    text("Game over! The word was " + word.join(''), width / 2, height / 2 + 60);
  }

  // Display new game prompt
  textSize(16);
  text("Press ENTER for a new game", width / 2, height/ 2 + 100);
}

the game:

Assignment 4: A Sincere Letter Generator by Sihyun Kim :)

Concept:

As soon as the professor introduced us to the “poetry generator” and its code, I wanted to apply this concept and code that we learned in class. Then, I came up with the idea of creating a “random letter generator” by applying the concept and code we learned in class. To make it resemble a real letter, I downloaded some “letter background” templates from Canva and obtained some handwritten-style fonts from https://www.1001fonts.com/handwritten-fonts.html to make the letter appear as if it were genuinely written by someone. Additionally, to make my output more interesting, I allowed the background image and font to be randomly generated.

Highlight of the Code:

There are three functions I intentionally created: generateLetter(), getRandomWord(), and mouseClicked(). generateLetter() is responsible for generating the random content, getRandomWord() retrieves a random word from the string array based on the given index, and mouseClicked() generates “new letters” when the mouse is clicked.

I am proud of all the code I have written for this project. However, I am most proud of the code I created for the generateLetter() function.

//function to generate the letter content using random words
function generateLetter() {
  //constructing the letter content involving template literal and getRandomWord() function
  let letterContent = `Dear ${getRandomWord(RECIPIENT)},

I wanted to take a moment to ${getRandomWord(VERB)} my ${getRandomWord(ADJECTIVE)} ${getRandomWord(NOUN)} for your ${getRandomWord(NOUN)}.Your ${getRandomWord(NOUN)} means a lot to me, and I am truly ${getRandomWord(ADJECTIVE)} to have you in my life. From the ${getRandomWord(ADJECTIVE)} ${getRandomWord(NOUN)} we've shared to the ${getRandomWord(ADJECTIVE)} ${getRandomWord(NOUN)} we've ${getRandomWord(VERB)} together, every ${getRandomWord(NOUN)} with you is a ${getRandomWord(ADJECTIVE)} ${getRandomWord(NOUN)} I hold dear to my heart. As we continue on our journey together, I look forward to creating many more ${getRandomWord(ADJECTIVE)} memories with you.With ${getRandomWord(EMOTION)}, ${getRandomWord(EMOTION)}, and ${getRandomWord(EMOTION)}, I want to express how much you ${getRandomWord(VERB)} and ${getRandomWord(VERB)} to me. Wishing you ${getRandomWord(ADJECTIVE)} days ahead and ${getRandomWord(ADJECTIVE)} adventures.

With ${getRandomWord(EMOTION)},
${getRandomWord(NAME)}`;

  textAlign(LEFT); //aligning text to center
  text(letterContent, 130, 250, width - 250, height); //displaying the letter content on the canvas
}

 

The attached code above is what I created for the generateLetter() function. I am proud of this code primarily because of the utilization of template literals. Initially, I considered adopting the same approach as our professor did when generating poetry. However, I realized that my code would become too lengthy if I followed the exact same method. So, I began contemplating how to make my code more concise. Eventually, I came up with the idea of utilizing template literals in my code. Template literals, a feature in JavaScript, allow you to embed expressions within strings. This feature enabled me to directly integrate the getRandomWord() function into my base letter content, making my code more concise. Although I was aware of the existence of template literals before, I had never used them. Thus, it was initially challenging for me to figure out how to apply them and understand the syntax. I felt a sense of pride in myself for successfully incorporating template literals to make my code more concise.

Final Output:

**Click the mouse t0 randomly generate a new letter! 

Reflection:

Overall, I am very satisfied with my project. Although it was initially challenging for me to grasp the syntax of template literals, I thoroughly enjoyed working on this project. As for areas of improvement for next time, I believe adding animation where the letter’s content is being written or implementing a feature where the viewer can change particular words one by one when clicked would be intriguing.

Week 3 Reflection – Finding Interactivity

I thought the author was crazy. The use of informal words and phrases jumped me out of my seat (not literally), but it allowed me to picture Crawford as an author because of how expressive the whole chapter is.

Defining interactivity is hard. There is no absolute correct definition for the word that matches its meaning. Beyond his definition that interactivity is a cyclic process where two actors alternately listen, think, and speak, I believe sense is also an important process to add to the definition.

Most stuff that we call ‘interactive’, even in the lower degrees (based on Crawford’s degrees of interactivity), requires human sensory input. Without haptic feedback, some interactivity is gone. Think about phones, computers, or even toys, they require humans to touch, move, and (sometimes) break them for it to be interactive. Although this sounds very ableist, I believe that our senses count as much as the three actions to experience interactivity that Crawford seeks. That human sensory is important to add to the definition of “What is interactive?