Joy of Programming

Programming brings me joy. Whenever I am struggling and making mistakes, I turn them into integers.

Ever make mistakes in life? Let’s make them integers. Yeah, they’re integers now.

Bob Ross (paraphrased)

Sometimes I struggle so much with a programming task that I lose sight of the joy. I get deep into a prideful fugue, where I set out to make the most optimal code that anyone has ever seen! Code that is better than yours! Code that would make an AI code generator just shut itself down in shame!

Comparison is the thief of joy.

Theodore Roosevelt

Practitioners of my chosen vocation sometimes imply that our art is drudgery, mundane, or bereft of joy; and it is better to hand it off to an AI code generator. That only challenges me to prove them wrong! I’ve got your joy right here! Look at my joyful code! LOOK AT IT!

So I sit down and joyfully program something optimal, fast, and tight. I disable all the error detection features of my IDE, letting the compiler/linker tell me where any errors are. I disable all the code completion features of my IDE as well, so as not to distract me from creating something truly inventive and original. Then I start to run into problems: Compiler errors; linker errors; language limitations; or I just get lost in my own prideful aspirations. The joy somehow disappears.

Just keep swimming!

Dory

But I have got to keep programming! I will get through this! I am brilliant! I will solve all these problems, if it takes me all night!

I get so lost in the process, that I lose sight of joy of programming.

Should I stay or should I go?

The Clash

When programming stops being a joy, your code starts to suffer. Your mistakes become bigger. You get into a state where everything you try simply does not work. And the solutions to your problems become more elusive.

This is when it is time to walk away. Go outside. Enjoy the view. Breathe some fresh air. Listen to the sounds around you.

This is when the way to get unstuck occurs to you. This is where you get to realize that all of your mistakes were merely learning devices. You know now what to do, and how to do it.

Isn’t it fantastic that you can change your mind and create all these happy things?

Bob Ross

Find your way back to the joy. Learn from your mistakes, and then delete them. Delete your code. Create new code. Keep it light. Keep it fun. Enjoy the lack of compiler and linker errors.

If you do too much, it’s going to lose its effectiveness.

Bob Ross

Most of all, be sure to take regular breaks. Spend some time with family. Walk your dog. Watch some videos. Listen to some music. Whatever inspires you. Whatever helps you maintain your sense of joy.

In painting, you have unlimited power. You have the ability to move mountains. You can bend rivers. But when I get home, the only thing I have power over is the garbage.

Bob Ross

Variables in JavaScript

A variable is a named container that can hold a single value. The value can be changed at any time.

Declaration

In order to use a variable in our JavaScript code, we must first declare it. Use the var keyword to declare a variable, followed by some whitespace, and then the variable name (x), finishing off with the end-of-statement symbol (;):

var x;

Test the Declaration

If we were to Run the above code as it is, it will finish and provide no feedback. So we will add a simple line of test code, using the JavaScript console.log() function:

var x;
console.log("x = " + x);

The above code adds the following text to the Console:

"x = undefined"

The initial value for the variable x was never specified, so it has no value (undefined in JavaScript). It is common to both declare and initialize a variable at the same time.

Initialized Declaration

In order to declare and initialize a variable, start with the var keyword, add whitespace, add the variable name (x), add the assignment operator (=), followed by the initial value of the variable (0), and finishing off with the end-of-statement symbol (;):

var x=0;

Test the Initialized Declaration

var x=0;
console.log("x = " + x);

The above code adds the following text to the Console:

"x = 0"

Link to sandbox code:
https://jsfiddle.net/clean_blue_dot/pyjx96bz/7/

Servo Motors on Three Axes

If we are designing a robot arm, we need it to be able to rotate freely on three axes; X, Y, and Z. This lesson covers connecting three servo motors to an Arduino UNO board, as well as controlling them with C++ code, using the Arduino IDE to deply the program over USB.

Servo Motors

MG90S Servo Motor Wires

Most servo motors have 3 wires:

  • Ground (negative pole of DC power, labeled as “-“)
  • Positive (positive pole of DC power, labeled as “+”)
  • Signal (Pulse Width Modulation input, labeled as “PWM”)

The colors of the wires vary, so check the documentation for your servo motors to properly identify the wires. In this example, we are using three MG90S servo motors.

Connections

  1. Connect the “+” wire of each servo to the “5V” pin on the Arduino board
  2. Connect the “-” wire of each servo to the “GND” pin on the Arduino board
  3. Connect the “PWM” wire of each servo to the ~9, ~10, and ~11 pins on the Arduino board (one per servo)

Control the Servos with Code

Example code that rotates the X, Y, and Z servo motors back and forth by 90 degrees.

Serving Suggestion

Here is an example of the above connections, using an Arduino UNO R3, breadboard, jumper wires, and three MG90S servos. Power provided by a solar-charged USB battery pack.

Servo Motors

In this lesson, we will connect a servo motor (and supporting components) to an Arduino UNO board and program the servo motor in C++ with the Arduino IDE.

Circuit Diagram

The components needed to complete this circuit:

  • Arduino UNO board
  • 100 μF electrolytic capacitor
  • 9v Battery

C++ Code

Solve a Maze

When we solve a maze, many of the techniques we utilize are far beyond the capability of even an advanced robot. For example, we can take a look and try out possible pathways without having to start physically or virtually moving through the maze. But what if we have no view to utilize, where all we see is the part of the maze we are currently in? In this case, a robot would have an advantage: It would be able to store “digital breadcrumbs” that can be used to backtrack quickly to “rooms” that have untested pathway options. The correct pathway through the maze could be determined in milliseconds, as long as the data of the maze pathways is accessible to the algorithm. Quickly determining the correct pathway, before rendering, is also a good way to validate that the maze has a solution. The queue technique that we implemented in the Draw a Maze lesson is also useful in a maze solving algorithm.

Version Zero

Version Zero quickly validates that a maze has a solution. But it highlights every pathway that it explored on its way to finding the ending cell. We need to refine all of the explored pathways down to a single pathway that is the single solution to the maze.

Version Zero in action:
https://school.cleanbluedot.com//wp-content/uploads/mazing_js/solving/version_zero.html

Version Zero code:
https://github.com/clean-blue-dot/solve-a-maze

Version Zero code in a sandbox:
https://jsfiddle.net/clean_blue_dot/xuzer01w/2/

Version One

Pointless Tree

Trees cover up a multitude of sins.

Bob Ross

Version One builds a tree (“PointlessTree”) out of all the explored pathways, creating branches whenever a direction is explored. When the end cell is reached, Version One backtracks from the tip of the last branch until it reaches the trunk of the tree, where the start cell is located.

Talk to the tree, make friends with it.

Bob Ross

By traversing the tree from the end cell to the trunk (start cell), all dead-end pathways are automatically ignored, as they are sibling branches: Only the parent branches are traversed.

There’s nothing wrong with having a tree as a friend.

Bob Ross

Version One in action:
https://school.cleanbluedot.com//wp-content/uploads/mazing_js/solving/version_one.html

Far from Finished

Now that this draw-and-solve-mazes program is working, we might consider this project completed, and release it. But it has no interactive features that allow a user to do anything other than re-run the process with a browser reload button. Most AI implementations are released in this incomplete state, as the importance of releasing to the Consumer Products Market trumps any potential improvements.

If we were to change this project into something different (like a game or embedded software for a maze-builder-robot), the code would need to be altered; as it is over-verbose and hard to maintain. The maze-drawing and maze-solving algorithms are lumped together in the same code. There is a mixture of “functional” and “object-oriented” code. Most of the code is “unrolled” (which is a lie, as it was never “rolled” in the first place): There are repeating patterns that would be much easier to maintain if they were implemented as functions. Cryptic variable names and over-reliance on text comments makes the code hard to read or understand.

Most programmers follow these simple rules:

  • Make it Work
  • Make it Right
  • Make it Fast

Make it Work

Despite being incomplete, this project contains great value in that it works. If every step we take in making something work is a mistake, the steps no longer count as mistakes: They become learning devices. They become part of the creative process. They become a method to achieve working from not-working.

When we are in the process of making something work, we do not waste our time trying to make it right. Our code should be ugly and unrolled. Our variable names cryptic and full of spelling and grammatical errors. Our compilers/interpreters should be reporting coding errors constantly. Our code should always be doing something unexpected. It needs to be broken until it works.

Make it Right

Now that our code is working, we should make it right by organizing it into structures, classes, functions, and self-documenting code. Any portions of our code that would be useful for other projects (such as the creation of a maze or the solving of a maze) should be separated out into code “libraries” that can be re-used as part of other projects.

Make it Fast

Once our code is right, we could translate it into another programming language or “port” it over to another platform. These lessons use JavaScript in order to be portable to all devices, but JavaScript is far from ideal as a programming language: Slow, interpreted, and dubious numeric processing (for example, in JavaScript, 1 + “1” = “11”). Ideally, I would create cross-platform C++ code based on this project, using pointers, templates, and optimized algorithms.

Draw a Maze

Not just for mice anymore!

One way to design, program, and test robots: Teach them to solve a maze.

Before we can solve a maze, however, we need to design a tool that creates a single-solution maze.

The best way to create and solve a maze is in software. Even when a physical robot is tasked with solving a physical maze, the job can be accomplished with less energy and time, when it is done purely in software. This could be accomplished by analysis of an image of the maze. Or by analysis of the data that represents the maze pathways.

For this lesson, we will design and implement an algorithm that creates a single-solution maze. The pathway data is stored in a rectangular array of cells, and the image is drawn by rendering boxes representing the cells.

Version Zero

Not entirely unexpected: The algorithm draws an initial pathway, stopping as soon as it hits the first dead-end.

Proposed Redesign Approach

We need to add a feature that stores previous cells that have unused directions, so they can be revisited, and the other directions utilized.

Version Zero in action:
https://school.cleanbluedot.com//wp-content/uploads/mazing_js/version_zero.html

Version Zero code:
https://github.com/clean-blue-dot/draw-a-maze/blob/main/version_zero.html

Version One

Version One uses a queue. It enqueues cells that have unused directions still available. It also enqueues each new cell that is being added as a branch. The maze drawing loop runs until there are no more cells in the queue.

Predictable

Notice how predictable a Version One maze is. The solution is very easy to track on sight, especially if we start at the Southeast corner and find the pathway to the Northwest corner. There are no spiral patterns or any complex dead-ends. What we want out of a maze generator is unpredictability. The probability of available pathway directions in the North or West is so low that the random direction picker is almost always picking either South or East.

Proposed Redesign Approach

Version Zero, despite failing to draw complete mazes, produces unpredictable pathways. Version One, despite failing to draw unpredictable pathways, retains cells in an optimal way. We need to revert the pathway generator loop to Version Zero, but add a feature that revisits cells that have unused directions still available whenever a dead-end has been reached.

Version One in action:
https://school.cleanbluedot.com//wp-content/uploads/mazing_js/version_one.html

Version One code:
https://github.com/clean-blue-dot/draw-a-maze/blob/main/version_one.html

Version Two

Version Two only dequeues a backtrack cell when a dead end is reached. It also centers the maze within the window. The pathways are allowed to wander until a spiral or other structure leads to a dead end. The predictable starting point (Northwest corner) makes the North and West pathways look straight and easy.

Proposed Redesign Approach

We need to add a feature that randomly selects a starting (x, y) position, to make the appearance of straightaways less probable.

Version Two in action:
https://school.cleanbluedot.com//wp-content/uploads/mazing_js/version_two.html

Version Two code:
https://github.com/clean-blue-dot/draw-a-maze/blob/main/version_two.html

Version Three

Version Three randomly picks a starting position, creates random pathways, and dequeues a backtrack cell whenever a dead end is reached.

Version Three in action:
https://school.cleanbluedot.com//wp-content/uploads/mazing_js/version_three.html

Version Three code:
https://github.com/clean-blue-dot/draw-a-maze/blob/main/version_three.html

Version Three code in a sandbox:
https://jsfiddle.net/clean_blue_dot/k1gsn4df/12/

Next Lesson:
Solve a Maze