An ASCII puzzle for an escape room challenge


The countBits function (lines 21-29) returns the number of 1s in a binary representation of the number n, which it figures out through a series of binary operations. After defining iCount, the function sets up a while loop with the condition n. In C, a while loop runs while its condition is not zero. Because the provided condition here is just a number, it will run until the number becomes zero.

In the binary AND (&) of the number n with 1, if the low-order bit (the least significant bit, or bit 1 in this case) is set, this operation evaluates to 1; otherwise, it evaluates to  . Therefore, iCount increments by either 1 or 0 depending on whether the bit is set. The right shift operator ( >>= ) shifts iCount, discarding the low-order bit and moving everything over one place. The loop repeats, checking the new low-order bit again. Eventually, when the entire value has been right shifted, only 0s are left in n. At that point, n = 0, the while loop exits, and return iCount returns the number of bits that are set. You'll see how this is used in the next function.


The rotateOutputs function (lines 31-67) picks a random number until it finds one with the appropriate number of bits; then, it turns on the associate output pins (the lower row of electrical connections in the puzzle). These connections are used in the current round of the game, indicated by LEDs.

The three variables are the number of bits to be set (iNeededBits), the number of bits in the generated random number (iCurrentBits), and the current random number (iRandom).

The number of bits needed (iNeededBits) is set by calling countBits with the current character the players seek. The while (lines 38-41) loops until iNeededBits is not equal to countBits(iRandom), which was initially set to zero, but is set to random(0,255) within the loop. In this way, random numbers are chosen until one is found in which the number of set bits matches the goal; then the loop exits.

Line 43 prints the random number to the serial monitor for debugging, and lines 44-66 update all of the electrical connections so that they are all either HIGH or LOW, depending on the value of iRandom set above. The binary ANDs (&) with 1 (line 44), 2 (line 47), …, 128 (line 65), checking only one bit in the number at a time. For each bit, digitalWrite either turns the appropriate pin on or off.

ledYES and ledNO

The ledYES and ledNO utility functions (lines 69-80) just display YES or NO on the display. One or the other is called when the player checks to see whether the current wiring is correct. In each case, the showDigit function is called with position (first argument) and character (second argument) hard coded.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • New Tech Retrofit

    An electronic project at a local science center was showing its age, calling for a refresh: in this case, rebuilding it almost from scratch with an Arduino instead of relays.

  • Perl: Arduino Project

    With a few lines of self-written firmware and a simple Perl script, Perlmeister Mike Schilli trains one of his Linux computers with a plugged in Arduino board to switch electrical equipment on and off using a relay. Enchanting.

  • Serial Communications

    We explore serial communications, from the electrical specs to protocols and libraries, with an example of serial communication with an Arduino.

  • Sudoku

    Some regard Sudoku as the 21st

    century Rubik’s Cube. We’ll

    show you how to get started

    with Sudoku in Linux.

  • Knight's Tour

    If you're looking for a head start on solving the classic Knight's Tour chess challenge, try this homegrown Python script.

comments powered by Disqus