Sunday, October 4, 2015

The great experiment: teaching my son to program (part II)

Last time I described why I'm trying to teach my son how to program, and my two first failed attempts.  The third attempt is going to be a game.

My experience with the basic command-line project I did my son, has taught me that he is not as averse to text-mode (AKA "no-graphics") as I had previously thought.  I also learned that text-mode graphics is an easy and intuitive way to do I/O.  It's also quite powerful - just think back about some of the early games :-).  It is really important for me to show my son that there is no magic in programming.  That he can create a games with bare-bones tools.  That he understands how everything is done.  No physics engines, no sprites, no magic.

I decided that the next project will be a text-mode tank fighting game: two tanks fighting each other in a 2D terrain.  Something like this, only using text-mode graphics.
There are plenty of features we can develop, so this gives a long runway for this project alone.  I wrote down some of the features we might develop:

  • A 2D map which might be larger than the screen
  • Animation of shooting a tank shell
  • Animation of moving a tank around the screen
  • Different types of walls: some impenetrable, some not
  • Different types of ammunition
  • Game levels with different maps and different challenges
  • Animation when moving to the next level
  • Blast/explosion animation
  • Colors
  • Sound
  • Damage level and replenishment
  • Ammunition level and replenishment, through picking up "ammunition presents"
  • Different types of ammunition
  • Hidden walls, keys and other tricks that add surprises
  • Multi-player mode
  • Multi-player mode - over the network
  • Control from an Android application
  • Score display
  • Opening screen
  • Console interaction
  • Sprites, threads, collision detection

I can go on and on, but the point is that this is going to be interesting.
After making the list, I shared it with my son.  I wanted to get him excited more than I was. Everything is designed to pique his interest: the theme, the game, and even the project name.
I decided to stick to my bottom-up approach.  That is, I decided to teach through "doing" instead of teaching him in a structured manner.  Instead of teaching about classes, objects, control structures, variables, and the lot, we will just dive in.  This is how I learned to program and it was plenty good :-).

Each sit-down session is going to be self contained.  That is, I don't want to quit in the middle of a feature.  The application should always work.  For this to work, we need to program in small increments.  Another principle is that we both program: I show him how I do something and then ask him to implement something similar.  And, as before, keep things lean and bare-bones.  For example, if I can refrain from using functions for a few sessions, then I'll prefer to have one long 'main' function than to confuse him with functions for the sake of correctness.

We are using github to manage the source control and you can follow our progress there.
The first session was around the basic input/output:

  • We used Console.WriteLine to create a 2D map.  To add some excitement, we added a title to the screen and played with the colors of the foreground/background.
  • The main loop waits for user key presses and interprets them.  This introduced some basic control statements ('if', 'while') and their syntax.  Again, I introduced these non-nonchalantly: "we need to loop on the key press and this is how we do this.  Do you understand why we call this a loop?  Can you explain why we loop forever?"
  • My son understands the Cartesian coordinate system from school, so introducing the Console cursor location attributes was pretty straight-forward.
  • I first showed him how to handle a right-arrow key and then asked him to write the code for the other three arrow keys.  Of course, I sat next to him while he was doing this.  Some guidance was still required here and there.  
  • After he finished coding the basic loop, we player with the "tank" a bit and I showed him that nothing stops the tank from going off the map (or even the screen).  We discussed how to fix this (boundary checking) and I again added the code to handle this in case of moving to the right, and then asked him to add the code for the other cases.
  • Finally, we added the option to quit the game.  
  • He told me that today's games display "GG" (good game) when exiting, so I showed him how we can add some ASCII art.  
  • Of course, because the exit is so quick, we didn't see the GG displayed so we worked out a 2-second delay.
And that was it.  A good first session.  I ended by committing the code to a new repository in Github.
I felt my son enjoyed himself, so I might have done it right this time :-)

The great experiment: teaching my son to program (part I)

There are many reasons why I want to teach my kids to program.  For starters, it's just great fun. What could be a better present that to teach your children a new way to enjoy themselves?  When I program I sometimes feel like a novelist creating new worlds; sometimes like a carpenter using old techniques with new tools; sometimes like an architect free to implement my vision under the constraints of time, budget, physics and the almighty customer; sometimes like a detective collecting data to uncover who killed the pointer.  And all the time I'm an engineer - a problem solver.  In 2015, I believe, everyone should know something about programming.  Lawyers, and artists; doctors and carpenters; pilots and salesmen.  Everywhere around us are systems that someone else programmed, and understanding something about how these "things" work is empowering. Improving on these "things" can be life-changing.
Joy comes from quenching one's thirst to understand, to imagine and to create.  And so this skill is more than a utilitarian skill - it can be a lifelong hobby through which the kids will express their artistic sides.
Or not :-)
I don't know how this "experiment" will end: will my bubble burst, or will I help them open the gates of a new world?  At least, I hope, we will bond.  If only just a bit.

My daughter wasn't interested in this "project" of mine.
I couldn't entice her with promises of discovering bright new worlds. Bummer.  It took me a couple of weeks to recover from this arrow to the heart.
Alas, my son, who is younger and spends enough hours of the day playing games on the net, was more amenable.  So off we went.
To his room, that is, to crank up the old IDE.

Roll back a few weeks earlier: I was in the fantasizing stage at that time.  First thing I did was choose a language.  I wanted a high-level language to abstract away the complexities of the underlying hardware.  A language that has great development tools, and a large set of libraries pre-integrated in the development environment.  In other words, it should be intuitive and with minimum friction so that we can get off and going with no resistance.  C# was the obvious choice for me - it meets all my criteria and has a free world-class IDE provided by Microsoft.

I searched for online C# learning resources, but quickly gave up on that direction.  None of the sites I found provided an environment that is hands-on, educational, and captivating to a 13 year old with a short span of attention.
So it is up to me.  I have one chance, I know.  Get it wrong from the out-start, and I will lose his interest for a long time.
My son is a youtub'er and an online gamer fond of gadgets and is not easily impressed by simple graphics.  It took me a few drives to work and back, to come up with an idea (these long drives are good for catching up on podcasts, but also for reflection).    But before I hit this idea I had a couple of failures. I first tried interesting him in building a site on Wix.  He thought it was "cool", but it didn't stick.  Mostly it was my fault: I didn't plan ahead and I thought that once I show him the tools, he will pick it up from there - motivated by his endless curiosity.  But, no, that didn't happen.  He was much more "curious" about watching some youtube video :-(  And this was OK by me, because really, Wix is not programming. Next I tried interesting him in replicating the Mine Craft console interface.  I often see my son using the Mine Craft console and he commands it better that I know that Linux Bash shell. We hacked up in a single session, a simple command-line-interface console application which accepted user input and executed simple commands such as the 'log-in' command with (fake) user and password; 'quit' command to exit the application, and error messages.  I showed him how to use the Console object for basic I/O and taught him the basics of the "if" statement and string comparison.   I stuck to a bare-bones approach: use only what you need and use it "leanly" - no fluffy stuff to add confusion.  So, for example, when we used Console.WriteLine - well, it was just a way to print characters to the screen.  No explanation about classes, objects, or methods.
I never use C# myself, which is fortunate for this experiment. Each time I wasn't sure how to do something, we googled it.  Using the experiences and advice of others through google is a great lesson.

And then came the flop.
My son's attention was wavering and we've achieved enough for this first session.  So I called it quits and gave him some ideas on how he could make a few incremental changes.  And then I left him, hoping that I did enough to pique his curiosity and that he will continue alone later.  That "later" never came.  In the coming couple of weeks I tried to get him to continue alone a few times, but youtube and Mine Craft were more interesting.  But I saw the "spark" of curiosity and some excitement, and that was enough to keep me motivated.  He said he now understands how the Mine Craft command line works.

I learned two things from that experience.  First, this is going to be "our" project.  There are too many distractions luring him, and I'll have to sit with him through several sessions before trying again to invite him to work by himself.  And this is fine because I enjoyed our session.  Second, I really have to choose an interesting project, which also has a lot of room for new features.

The next project will be a game.