Tuesday, January 27, 2009

Cool Programming Tricks Episode 1: The “It’s me again!” technique.

I thought I’d divulge some of the coding tricks I use most often for my fellow programmers visiting this blog. Mainly I would like to get some opinions on them; after all, I’d like to know if I’m walking on a short pier. However, I think they’re fairly useful little tricks and I’m proud of how they’ve worked out for me so far.

By the way, I’m not familiar with ALL the major design patterns, so some of my tricks might have names I don’t know of, in which case – fill me in!

Now, on to my favorite trick by far. You can do this in just about any language that supports inheritance.

As we all know, a pointer to an interface or base class can be assigned to any children of said class, provided you use only the methods available in the pointer’s type ( if you don’t know what I’m talking about, get a design patterns book FAST! ) One of my favorite things to break up into small encapsulated classes is the program’s interface. A game’s loading screen, game play, credits, score board, etc, are often crammed into a single driver class or even called in the main loop with a ton of conditionals. I prefer them to be in separate classes.

So try this. You have your main class with its main loop. There are a series of functions that get looped through in any mode, usually draw() and update(). Whatever the current mode is, the loop delegates to that mode and it runs until a switch is needed. Normally, programmers will have some kind of return value or other check to see when to make the switch. But I prefer to have the MODE do the switching. If update() gets called once a loop, why not have it return the next mode to switch to?



mode * nextMode = curMode->update();
if( nextMode != curMode ) {

delete curMode;

curMode = nextMode;
}


If you have some way of only keeping one of each mode ( singleton, or something else, ) simply don’t delete. This is even easier with boost’s smart pointers or your chosen language’s garbage collection. Long story short, your current mode will keep returning itself ( “ITS ME AGAIN” ) until it needs to switch, in which case it returns an instance to the appropriate mode. You can even have one return NULL for something else, say, ending the program.

This trick does not stop at game modes. Anything which delegates functionality to different child classes using the strategy pattern can use this in some form. For example, a game I am currently working on nests the use in two cases. The game’s mode is done this way, but within one of them I use the trick again, for dialog boxes. In the case of my game I don’t even need singletons or such.

I have yet to run into even a small amount of trouble doing this. Tell me what you think.

Friday, January 9, 2009

The Windmill of Quixotic Code

When you program, are you a perfectionist? Do you take to heart all the lessons you learned from your shelf of computer books - lessons like, "always make your code reusable"? Coming into my recent job, I truly felt like being that way was going to help me exceed all their expectations. I was going to give them the ideal code - a comment for every variable and function, everything in a class structure, no globals. Then I opened up the project I'd be working on for the first time, and saw a "goto".

What you learn when you leave school is that perfect code doesn't exist for large projects. It's a pie in the sky, and if anyone preaches it to you, they are trying to make themselves seem like better programmers than they probably are. In the actual "biz", you get three adjectives for computer software, of which you may only have two at any given time:

Efficient.
Good.
Cheap.

My workplace, EDAS, is strictly the first two, but even then there are tradeoffs between "efficient" and "good". I consider "good" programming to be modular, since new features only need to affect certain elements of the code. But nothing's as "efficient" as code created with a specific purpose. So we have to keep things about 50/50 if we want a good name in our industry. Sometimes that means a goto, or a global variable.

If you go into a project charging at windmills, you'll quickly find very little accomplished. Seek what is useful, not what is ideal. If you are a hobbyist, I encourage you to try everything in your code. Try all the things you've been told not to try, and attempt to figure out where they're most useful. You'll get an occasional geek on a soapbox telling you that your code's inferior, but if nothing else it will be YOU and not them that actually knows why something must be avoided, rather than doing so dogmatically.

This is a lesson I myself have learned, and thought neccessary to share. I wish I had fully understood it myself when I came aboard with this company. But, at least I'm doing a good job now, and luckily I unlearn as quickly as I learn.