NaGaProMo

I humbly present an idea and an experiment:

National Game Programming Month (NaGaProMo)


Based on the idea of National Novel Writing Month (NaNoWriMo), NaGaProMo instead focuses on programming a game from start to finish in one month.  You shouldn't try to create the next blockbuster title. Instead, NaGaProMo is a fun way to get some extra programming in while creating a new video game.  Get together with your friends to share tips and bounce ideas around throughout the month.

Rules:


1)  The game must be created entirely during the month of November.
2)  All programming must be done by you, the sole author.  (You can still use other libraries and APIs created by other programmers.)
3)  At the end of the month, you should have a reasonably stable game that can be run on your target device (PC, Android, etc.).

Next year, there may be some sort of length requirement, but I'm working through this for the first time myself this year.  You'll notice I called this whole thing an experiment at the start of this entry.

I'll be blogging about my progress throughout the month of November and hope to have a finished game in about a month.

Code Smiles - Refuctoring

Programmers often spend time talking about ways to avoid code "smells" but very little time is spent dealing with code "smiles".  Fortunately, I found a presentation that deals with the latter: http://www.waterfall2006.com/gorman.html

Sample quote: "Over time code "smiles" build up to create what is sometimes called maintainable code, more specifically, code that can be maintained by somebody other than the person that wrote it, and that means YOU!"

Programmers' Day++ Special

Happy Programmers' Day++ everyone!  Wikipedia has some more information on this holiday.  I forgot that this was a leap year, so the real Programmers' Day was yesterday... We'll just increment that day by one (hence the ++ operator) and continue on with our holiday.  Now on to some free ways to celebrate:

1)  For the nerdier IT folks (is that redundant?) you could check out Unix for the Beginning Mage.

2)  For the non-programmers, it's never too late to learn programming with the interactive Codeacademy website.

3)  For Windows programmers, try out the new Visual Studio 2012 Express that was released yesterday.

I'm going to be trying out method 3 over the next week and will be posting some information about my setup and initial experiences during that time.

Rethrowing Exceptions

How to Rethrow an Exception


When catching an exception in a language like C#, sometimes it's helpful to rethrow the exception to let some outer calling method handle the exception.

Example 1 (incorrect method):
catch (Exception ex)
{
    throw ex;
}

Example 2 (correct method):
catch (Exception ex)
{
    throw;
}

In the first example, a new exception is made based on the caught exception, but this new exception loses the stack trace of the original exception.  The second example is truly rethrowing the original exception and the stack trace is preserved.

Customizing the Rethrown Exception


In many cases, a programmer will want to add some data to an exception before it's rethrown.  There are two main methods for doing this.

Method 1:
catch (Exception ex)
{
    throw new CustomException("This is some custom data", ex);
}

Method 2:
catch (Exception ex)
{
    ex.Data.Add("CustomData", "This is some custom data");
    throw;
}

In the first method, a new Exception type is created that contains the original exception.  This is handy for cases where the logical exception has changed and the name should therefore change to reflect this.

In most cases, the type of exception is the same, but the current catch block is simply adding some extra debug information to the exception.  In this case, use the second method shown above.  Here we are simply adding some data to the current exception before rethrowing it.  This data is being added to a Dictionary, and is therefore structured as a key/value pair.  Both the key and value are of type object, but the key should be a string when possible.


SVN With Visual Studio Express

I was looking for an integrated version control system (VCS) for my development environment.  For my needs, it had to store revisions in the cloud to easily allow me to work from multiple computers and be simple to use.  For this project, my IDE is Visual C# Express 2010 and we'll be using Google Code with Subversion (SVN) as the VCS with the TortoiseSVN client.

Google Code


I chose Google Code as my hosted VCS solution for a few reasons:

1)  It encourages (requires?) its projects to be open source.
2)  It uses my existing Google Account.
3)  It allows multiple VCS implementations (Subversion, Git, and Mercurial).

Subversion


Subversion (SVN) is possibly the most popular VCS for code.  It's based on a repository that contains the current revision of code, along with all previous revisions.  To edit the code, a user checks out the latest version, updates it, and commits the changes back to the repository.  This creates a new revision automatically.  SVN keeps track of the revision of each file separately and also manages checkouts in a multiple user environment.  Wikipedia has a good overview of SVN.

Visual C# Express 2010


Visual C# Express 2010 is a free IDE for the C# programming language.  It is currently the latest version, but a new 2012 version has been announced for release later this year.

My language of choice is C# and I'm cheap, so this is the development IDE I prefer.  Unfortunately, one of the main differences between Visual Studio and Visual Studio Express is that the Express editions don't support plug-ins.  That rules out the possibility of an integrated VCS solution, but I continued to look for something that would simplify use of a VCS with Visual Studio Express.

(The setup instructions below do not use Visual Studio at all.  I mention it here mostly to indicate why I chose TortoiseSVN as the SVN client.)

TortoiseSVN


TortoiseSVN is an SVN client for Windows that has shell integration (i.e. it integrates with the right-click menu in Windows Explorer).  It will work with any SVN repository and is not tied to a specific programming language or IDE.

Setup


Now let's get everything set up.  We'll assume that you already have the first revision of code created.

1)  On the Google Code website, select "Create a new project".  Enter the relevant information about the project and make sure to select Subversion as the version control system.  Click "Create project" when completed.
2)  Go to the project's website that Google Code has created.  Go to the "Source" tab and leave this page up.  We'll need some information on it later.
3)  Download and install TortoiseSVN from the creator's website.  The default options are fine for our install.  After installation, restart  the computer to enable TortoiseSVN's shell integration.
4)  In Windows Explorer, right-click on the top-level folder for your code and select TortoiseSVN > Import.  (I intuitively and mistakenly selected Export the first time.  The Import and Export commands are named from the perspective of the hosted repository.  In this case, the repository is importing the first revision of code.)
5)  An import window will open up.  Go back to the website we left open in step 2 and look for a line similar to the following: "svn checkout https://project-name.googlecode.com/svn/trunk/ project-name --username user@gmail.com".  Copy the URL beginning with "https://" and ending with "trunk/" and paste it into the URL field from the import window.  Click OK in the import window.
6)  You will now be prompted for your username and password.  Look at the website we used in steps 2 and 5 again.  Click on the "googlecode.com password" link to go to a website that will show your SVN credentials.  Note that this password is not the same as your Google Account password.  Copy and paste this information into the import window's login screen.  You can also select to have TortoiseSVN remember these credentials.

Usage


At this point, Google Code and TortoiseSVN are all setup with a copy of your code.  Each time you want to edit the code, there is a simple 3 step procedure to follow:

1)  Right-click in a local folder and select "SVN Checkout...".  Confirm that the URL of repository is the same as we entered previously, and then click OK.  This will create a new folder containing the latest revision of your code.
2)  Using your editor or IDE of choice, edit the code.
3)  When you're ready, right-click on the project folder again and select "SVN Commit...".  The commit window will automatically select the files that have been updated.  Click OK to begin the commit.

Now, head on over to GrokCode to learn how to use source control effectively.

Serial Communication in Linux

Today I set up serial communication with a linux server and thought I'd document the procedure here.  The following instructions assume your linux distro uses GRUB.  This was tested on CentOS 5.6 (ish) and Windows 7.

We'll refer to the Linux computer that we are trying to connect to as the "server".  The computer we are using to make the serial connection will be the "client".

Procedure

Step 1)  On the server, open /boot/grub/grub.conf in a text editor and find the entry for your current kernel.  It will look something like this:
default=0
timeout=5
hiddenmenu
title CentOS (2.6.18-194.17.4.el5.centos.plus)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-194.17.4.el5.centos.plus ro root=/dev/VolGroup00/LogVol00 rhgb quiet
        initrd /initrd-2.6.18-194.17.4.el5.centos.plus.img

You may see multiple title sections.  Each of these is another possible boot option in GRUB.  Every time a new kernel is installed, a new boot entry is added to this list.  The old boot entry and kernel are left behind so that you can boot with them if you end up having any issues with your system.

In order to have terminal output displayed over serial during bootup, we need to append some serial settings to the appropriate boot entry.  Each title section is implicitly numbered starting with 0.  Take a look at your default=# line to determine which entry is booting up by default and add your changes to that entry.  Or you could just add the serial settings to every entry.
default=0
timeout=5
hiddenmenu
serial --unit=0 --speed=38400 --word=8 --parity=no --stop=1
terminal --timeout=30 serial console
title CentOS (2.6.18-194.17.4.el5.centos.plus)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-194.17.4.el5.centos.plus ro root=/dev/VolGroup00/LogVol00 rhgb quiet console=tty0 console=ttyS0,38400n8
        initrd /initrd-2.6.18-194.17.4.el5.centos.plus.img

Step 2)  Open /etc/inittab in a text editor.  Add the following two lines at the bottom of the file:
T0:23:respawn:/sbin/getty -L ttyS0 38400 vt100
T1:23:respawn:/sbin/getty -L ttyS1 38400 vt100

Step 3)  Connect the server and client computers together with a serial cable.

Step 4)  Open up a serial communication program on the client computer.  I prefer to use Hyper Terminal.  This program was included free in Windows XP, but is not part of Windows Vista or later.  If you can copy the program from a Windows XP computer, it will still run in newer versions of Windows.

Step 5)  Configure Hyper Terminal for to use the proper serial settings.  For us, that will be:

Port:  COM3
Bits per second:  38400
Data bits:  8
Parity:  No
Stop Bits:  1
Flow Control:  Hardware

If you are using an actual serial port on the client, you will most likely be using COM1 or COM2.  If, like me, you are using a Serial-to-USB converter, it will probably be COM3.  If the above settings still don't work, try changing Flow Control to None.

Final

At this point, you will be able to see the normal terminal output during server bootup on the client's serial display.  Once the Linux server is booted up, you will be presented with a login prompt giving you shell access to the server.


Regular Expression Lookarounds

(This post deals with creating a single regular expression that matches a valid string syntax and then only matches a specific subset of those valid strings.)

I've been working with regular expressions on my current project.  I've used them in the past but I bumped into something that stumped me with my current problem.  I've got a list of file names that I'm checking for validity with our document control naming scheme.  My current task is to look for any file names that have lowercase letters but are otherwise valid.  These will then be flagged for review and then automatically fixed to uppercase letters.

My first step was to create a regular expression that matched valid file names:
^[0-9]{3}-[0-9]{4}-[0-9A-Za-z][0-9]{2}-[0-9a-zA-Z]{2}-[0-9A-Za-z]{1,3}

In a more human-readable form, this means that the file names must be of the form: ###-####-X##-XX-Y where # is any digit, X is any alphanumeric character, and Y is a section of alphanumeric characters of variable length between 1 and 3 characters.  Example valid name: 123-4567-A89-B0-11

This regular expression worked out exactly as intended, but as part of this project I also learned some shorthand which simplifies the above expression and makes it more readable:
^\d{3}-\d{4}-[[:alnum:]]\d{2}-[[:alnum:]]{2}-[[:alnum:]]{1,3}

This takes advantage of two shorthand elements:  \d is equivalent to [0-9] and [[:alnum:]] is equivalent to [0-9A-Z-a-z].  Unfortunately, C# doesn't seem to recognize the second of those two shortcuts.  Gordon McKinney has a good reference sheet for regular expressions.

The next step was to look for file names that were matched by the previous regular expression but have a lowercase letter in them.  The easy way to do this would be to save the list of matches from the first expression and then match against the following expression to look for any lowercase letters:
[a-z]
or
[[:lower:]]

Simple, right?  Except that my requirements were to accomplish this all in one regular expression.  I experimented with a few things before finally stumbling on lookarounds.  I never could get my solution working with a positive lookahead (I think the problem was with the starting anchor), but I did get it working with a positive lookbehind:
^\d{3}-\d{4}-[[:alnum:]]\d{2}-[[:alnum:]]{2}-[[:alnum:]]{1,3}(?<=[[:lower:]])

This expression is first looking for the above-mentioned valid naming scheme, and then it looks back through the regular expression for anything matching [[:lower:]].  Upon finding a match, the entire expression is now considered matched.