Project: ZenerTest

What It Does

ZenerTest tests your psychic ability by simulating a Zener card deck. It presents you with the back of a virtual card, and after guessing whether the symbol on the card is a circle, cross, wavy lines, a square, or star, you click the corresponding symbol beneath the card and the actual symbol is revealed to you. If you guess correctly, the revealed symbol is colored green and your score increases by one point; otherwise the symbol is shown red and your score is not increased. A couple of seconds after the card is revealed, a new card is selected for you to guess again. At any time, you may press the ‘S’ key on your keyboard to see your score (in terms of ‘hits’ and total number of ‘trials’); press the same key again to hide it.

How It Works

ZenerTest has two sprites: Card and Button. The Card sprite represents one of the five symbols a Zener deck can produce, and has a green and red costume for each of the five symbols, and one blue costume with no symbol to simulate the back of a card. The Button sprite creates a row of buttons representing the five possible card symbols, which the player can click to indicate which symbol she thinks is on the card. It possesses two costumes for each symbol, one dim and one bright; the bright costume shows when hovering the mouse-pointer over the button.

When the green flag is clicked to begin running the project, the Button sprite creates five clones of itself and assigns each a number 1 through 5, held in the buttonVal variable. As each clone is created, its buttonVal value determines where it is placed horizontally and also its costume. So, e.g., the first clone has a buttonVal of 1 so it is placed at x position -210 + (70 * 1), and it shows costume 1. The second clone has a value of 2 so it is placed at x position -210 + (70 * 2), and it shows costume 2. &c. To make each button display when the mouse-pointer hovers over it, I use a forever block to see if the button is touching the mouse-pointer and if it is then switch to costume buttonVal + 5, because the bright costumes are numbered 6 through 10. The pause variable is used to keep the player from highlighting or clicking other buttons during the two seconds a card’s value is revealed.

When the Button sprite is clicked, the script checks to see if pause is false (i.e., 0, meaning not paused), and if it is then:

  • set pause to 1 (true)
  • check to see if the buttonVal for the Button clone clicked matches the current cardVal of the Card sprite
  • if there is a match, set the match variable to 1 (true) and increase hits by 1
  • if there is not a match, just set match to 0 (false)
  • change trials by 1
  • broadcast the revealCard message, which tells the Card sprite to reveal the actual value of the card

When the green flag is clicked to begin running the project, the Button sprite broadcasts a getNewCard message after creating all the clones (i.e., buttons), which tells the Card sprite to switch to costume 11 (the blank card) and set the variable cardVal to a random number between 1 and 5, which corresponds to one of the five symbols the card could have. Note that this number is chosen before the sorcerer guesses the card’s value. When a button is clicked thus broadcasting a revealCard message, the Card sprite checks to see if match = 1 (true), and if it does then it switches to the costume corresponding to the cardVal number (the green card costumes are numbered 1 through 5), otherwise it switches to the costume numbered cardVal + 5 (the red card costumes are numbered 6 through 10). The Card sprite waits two seconds after revealing the card, then resets pause to 0 and broadcasts the getNewCard message telling itself to draw a new card.

Make It Better

  • Reduce the number of costumes. Good computer programmers usually try to do things in the most efficient way possible. This comes from the days when computers had much fewer resources than they do today, and programmers were required to be clever in order to fit the most functionality into such constrained systems. While Scratch is more forgiving than earlier programming languages, its leniency allows you to do things in (sometimes horribly) inefficient ways, and it is good practice to always be thinking about whether there is a smarter way to do what you need done. E.g., instead of having five green cards costumes and five red card costumes for the Card sprite, you could have only the green ones and use the set (color) effect to () block to change the tint of a green costume to red (or a red one to green, or a blue one to red or green). Likewise, instead of having dim and bright costumes for the Button sprite, you could have just a set of one or the other and use set (brightness) effect to () to change the brightness when hovering over a button (or not).
  • Technically, ZenerTest does not precisely simulate a deck of cards. With an actual deck of, say, 25 cards, five for each symbol, a star (e.g.) could only appear five times before you would need to shuffle the deck for a star to appear again (assuming you are discarding each card after it is read). The ZenerTest project randomly selects one of the five symbols, and then randomly selects another that is in no way contingent on which symbols came before it (except in the way that all pseudorandom number generating algorithms are), &c. There is no finite set of cards to draw from, so a star could appear more or less than five times within a range of 25 trials. If you wish to simulate an actual deck, you could modify the project to shuffle a list of fives sets of variables ranging 1 through 5. The Thebanet project demonstrates a shuffling algorithm.


The Zener card symbols used in this project were adapted from “Cartas Zener.svg” by multiple authors.