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
-
Thousands of Linux Servers Infected with Stealth Malware Since 2021
Perfctl is capable of remaining undetected, which makes it dangerous and hard to mitigate.
-
Halcyon Creates Anti-Ransomware Protection for Linux
As more Linux systems are targeted by ransomware, Halcyon is stepping up its protection.
-
Valve and Arch Linux Announce Collaboration
Valve and Arch have come together for two projects that will have a serious impact on the Linux distribution.
-
Hacker Successfully Runs Linux on a CPU from the Early ‘70s
From the office of "Look what I can do," Dmitry Grinberg was able to get Linux running on a processor that was created in 1971.
-
OSI and LPI Form Strategic Alliance
With a goal of strengthening Linux and open source communities, this new alliance aims to nurture the growth of more highly skilled professionals.
-
Fedora 41 Beta Available with Some Interesting Additions
If you're a Fedora fan, you'll be excited to hear the beta version of the latest release is now available for testing and includes plenty of updates.
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.
-
Juno Tab 3 Launches with Ubuntu 24.04
Anyone looking for a full-blown Linux tablet need look no further. Juno has released the Tab 3.
-
New KDE Slimbook Plasma Available for Preorder
Powered by an AMD Ryzen CPU, the latest KDE Slimbook laptop is powerful enough for local AI tasks.