An ASCII puzzle for an escape room challenge
showDigit
The showDigit
function (lines 82-126) is responsible for drawing the provided character on the display. I start by defining int iPattern
and then use switch
to find the character provided in cLetter
.
On each line of the switch
function, case
says: If I match '<this>'
then do whatever is after the colon (:
). If it does not match, it moves on to the next case
statement until it finds a match or drops off the end without a match. Once a match is found, iPattern
is set to a number represented in binary with the 0b
at the front (i.e., much like a preceding 0x
denotes hex notation).
The binary number specifies which segments of the seven-segment display should be illuminated to display this character. Once the pattern is defined, the break
exits the switch
block. Without break
, C would keep evaluating the rest of the case
statements and possibly find another match. Here, the function exits as soon as a match is found.
Finally, line 125 calls lc.setRow
, which is the LED controller's function to turn on a set of LEDs. setRow
takes three arguments: the chip number (always 0 in this case), the position in which to place this character (iPosition
), and which segments to illuminate (iPattern
).
Setup
In the Arduino world, the special setup
function (lines 128-164) is called once when the Arduino powers on, allowing you to initialize variables, turn on hardware, and make sure everything is properly configured before your main program runs. To begin, the code initializes the serial monitor in the Arduino IDE with Serial.begin (9600)
for debugging messages. The baud rate (speed) of the serial connection is 9600, but this number doesn't really matter, as long as it matches what is selected in the serial monitor.
The pinMode
of analog pins A0 through A7 are set to INPUT_PULLUP
. As the value suggests, this makes the pin an input and also enables its internal pull-up resistor. Even though I'm using the Arduino analog pins, I'm just using them as digital inputs in this case. Pin 10 is set in the same way and will be the "check" input to determine whether the current wiring is correct.
The next series of pinMode
s sets a number of GPIO pins to OUTPUT
. Pins 14, 15, and 16 are the data, clock, and chip select lines of the LED driver, and pins 2 through 9 are the top row of electrical connections on the puzzle. The digitalWrite
sets pin 16 to HIGH
, which allows the LED driver to listen to incoming data. Because the project only has one driver, it can be left on indefinitely; in this case, it could even be connected directly to V+, but this arrangement was more convenient.
The randomSeed
function initializes the Arduino's random number engine. An analogRead
of an unused digital input essentially picks up static, causing the return of a random number, which is used as a seed.
The rotateOutputs
was defined earlier, so when the puzzle starts, the lower row of electrical connections is ready to go.
The last couple of lines set up the LED driver. An lc.shutdown
set to false
means the LEDs should not be shutdown. The lc.setIntensity
sets the brightness of the display. The range is 0 to 16, so a value of 8 sets brightness at 50 percent. Finally, lc.clearDisplay
erases anything that was previously on the display. The first two functions are called with a
as the first argument. The 7219 driver chip can be daisy-chained, so you have to specify the chip in the chain to which you are talking. Because this setup only has one chip, the value will always be
.
Loop
After the setup
function finishes, the Arduino loop
function (lines 166-210) loops continuously until power is removed. In this function resides the main logic of the program.
To begin, I check to see whether cLastLetter
does not equal the current puzzle character, displayTarget
(i.e., show the value the player is trying to achieve), and update cLastLetter
to the current puzzle character.
Next, I check to see whether pin 10 is LOW
. If so, the player wants to know whether their current wiring is correct. To check, I initialize iPort
, then digitalRead
each of the input pins, and add the appropriate power of 2 if the pin is LOW
(lines 178-185). For a pin to be LOW
, the player had to connect a clip lead between this connection and one of the active connections on the lower row indicated by LEDs.
Once I've calculated iPort
, I check to see if it equals cLastLetter
, which means the players have found the correct combination. In that case, I increment iLetterIndex
, debug print "CORRECT"
, display YES on the LEDs, and then wait for 1 second (line 192).
The for
loops over the characters discovered so far. I call showDigit
and provide the position as 7 - i
, which makes sure the drawing starts from the left side of the display. The second argument, puzzle [ i ]
, is the character at that position. As each character is discovered it is added to the display.
Finally, rotateOutputs
ensures a different set of connections will be active for the next round. On the next iteration of the loop, iLetterIndex
has been updated, so a new number will be displayed for the players to find.
If the players did not guess correctly, the else
block (line 200) runs instead, debug prints INCORRECT, displays NO on the LEDs, waits for 1 second, redisplays the target value, and finally picks a new set of active connections with rotateOutputs
.
Line 208 loops infinitely while
a digitalRead
of pin 10 returns LOW
and delays a tenth of a second before checking again. Once pin 10 returns to HIGH
(the clip is removed), the loop continues.
« Previous 1 2 3 4 Next »
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Gnome 47.2 Now Available
Gnome 47.2 is now available for general use but don't expect much in the way of newness, as this is all about improvements and bug fixes.
-
Latest Cinnamon Desktop Releases with a Bold New Look
Just in time for the holidays, the developer of the Cinnamon desktop has shipped a new release to help spice up your eggnog with new features and a new look.
-
Armbian 24.11 Released with Expanded Hardware Support
If you've been waiting for Armbian to support OrangePi 5 Max and Radxa ROCK 5B+, the wait is over.
-
SUSE Renames Several Products for Better Name Recognition
SUSE has been a very powerful player in the European market, but it knows it must branch out to gain serious traction. Will a name change do the trick?
-
ESET Discovers New Linux Malware
WolfsBane is an all-in-one malware that has hit the Linux operating system and includes a dropper, a launcher, and a backdoor.
-
New Linux Kernel Patch Allows Forcing a CPU Mitigation
Even when CPU mitigations can consume precious CPU cycles, it might not be a bad idea to allow users to enable them, even if your machine isn't vulnerable.
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.