Nice code and switches

I had a thought while I was working on the game Alone In the Office (my LudumDare 22 entry). I wonder if I can make this code look more beautiful. So I went through and refactored the code. Okay, so I cleaned it up. There was cleaning to be done. But, I wondered if I could find any useful tid-bits of information about what other people do to keep code nice. I found this article and I noticed B. B is to return the immediate value of a boolean test instead of testing if the boolean test returned true or false. Mind you, in certain cases you DO need to check. In the cases of some of my code, I did not. B is the one thing I apparently overlooked in programming over the years. It’s interesting how I never noticed it to say the least. Anyways, upon reading to the end I find this article.

Called, “abolish the switch statement”, this article goes on to explain how to inaccurately use a switch statement and why it looks ugly. Then suggesting the use of maps. As an ex-web programmer and game programmer, I can tell you something that’s right and wrong about this. What’s right, switches are used improperly by inexperienced programmers. That’s especially true since I’ve taught and am still teaching programming to people. What’s wrong, everything else, including the solution itself. This article takes into no account values that go into the objects when declared nor the fact that switches are faster, especially on mobile devices.

In a game, each object has methods it calls based on the action it’s performing. *Unless you’ve got some super-abstract game model that allows you to handle actions outside the object, you aren’t going to make a new class for an action. Therefore, making their solution fail immediately. Take a look at this abstract example showing the proper use of switch i.e. not using magic numbers and why this looks as nice as the code could ever be.

public class GenericGameCharacter
{
    const int ACTION_IDLE = 0;
    const int ACTION_WALKING = 1;
    const int ACTION_RUNNING = 2;
    const int ACTION_JUMPING = 3;
    const int ACTION_ATTACKING = 4;
 
    public int Action;
 
    public GameObject(){}
 
    public void Update()
    {
        switch (Action)
        {
            case ACTION_IDLE:
                updateIdle();
                break;
            case ACTION_WALKING:
                updateWalking();
                break;
            case ACTION_RUNNING:
                updateRunning();
                break;
            case ACTION_JUMPING:
                updateJumping();
                break;
            case ACTION_ATTACKING:
                updateAttacking();
                break;
            default:
                // Error
        }
    }
 
    public void Draw()
    {
        switch (Action)
        {
            case ACTION_IDLE:
                drawIdle();
                break;
            case ACTION_WALKING:
                drawWalking();
                break;
            case ACTION_RUNNING:
                drawRunning();
                break;
            case ACTION_JUMPING:
                drawJumping();
                break;
            case ACTION_ATTACKING:
                drawAttacking();
                break;
            default:
                // Error
        }
    }
 
    private void updateIdle(){}
    private void updateWalking(){}
    private void updateRunning(){}
    private void updateJumping(){}
    private void updateAttacking(){}
 
    private void drawIdle(){}
    private void drawWalking(){}
    private void drawRunning(){}
    private void drawJumping(){}
    private void drawAttacking(){}
}

This code is still very much readable and a very good example of the proper use of switches. You aren’t going to get much cleaner or optimized than that. Consider sixty calls a second to the function Update() and Draw() on a mobile device. Compare the speeds to some other odd handling of the code just to make it look and feel “prettier.” The article is a good example of the fine-line between nice looking code and practical code.

Rules to follow when using switches
1) Don’t use magic numbers, they’re sickening to programmers. Constants are there for a reason.
2) You must have at least three conditions running at the same level. Otherwise use if-else.
3) Code should jump to a function to execute the desired conditions. You should not do the code inside the case directly.
4) More than fifteen conditions and you’re probably doing something wrong. Refactor your code.

*As a last note, take the example with a grain of salt. Typically, I don’t call different drawing functions when handling the drawing. It typically draws based on my sprite animation class’ selected image frame.

 
  • joe

    That’s an amazingly clean code there, a fine example for everyone. And it’s true that switch statements are faster.

    I am inexperienced at programming, and I have to admit I would use magic numbers before I read this article, and I was curious what would be wrong with using a large switch statement with more than fifteen conditions?

    Also isn’t in-lined code faster than jumping to a function? Unless the point is purely readability.

    • Goodlookinguy

      “I was curious what would be wrong with using a large switch statement with more than fifteen conditions?”

      Methods and functions should never be longer than the screen you’re working on. You shouldn’t have to scroll to see to the end of the method or function. Fifteen conditions is about right for a pretty large screen. Aside from that reason, if you start having a ridiculously large list. It’ll make it harder for you and other programmers to know everything that one method or function can do. By stepping back and refactoring, you could then think about grouping up certain types of methods or functions that have more in common and break them down into smarter more accessible lists.

      “Also isn’t in-lined code faster than jumping to a function? Unless the point is purely readability.”

      It is for readability. This also goes back to my statement earlier, which is also a readability statement, “Methods and functions should never be longer than the screen you’re working on.” Jumping to a method or function and coming back doesn’t take any electronic device long anyways. It’s two commands, called “jmp” and “ret”, on x86 and x64-86 processors. So going to a method or function and coming back is very quick and will make it so that you won’t be completely lost if you come back to your code later.

 
© 2017 NRGsoft