Civil War Strategy Game (Part 2): The Main Routine Continued

We started our jaunt through the main routine found in CWSTRAT.BAS in Part 1 of this series. We’ll continue our journey in this post, expect things to speed up as we move through as I’ll try to avoid recapitulating on topics already addressed in previous posts.

We’ll pick up on line 36 where we are introduced to a very important concept, the modularization of our code. One of the recurring difficulties in writing software is keeping it understandable and maintainable. By taking a potentially large piece of code and breaking it down into its logical parts we are able to reduce the complexity of understanding and maintaining code.

On line 36 we see CALL filer(1) – this tells us that a portion of our code is modularized into a subroutine filer. When we CALL that subroutine we are asking BASIC to jump to where we have defined the subroutine filer, execute all code in the defined subroutine, and then resume execution at the next command following CALL filer(1), in this case that would be on line 37.

Lets jump down in our code to where the subroutine filer is defined (lines 1172-1296). We can see that we define a subroutine like so:

SUB subroutinename (parameters)
' Code to Execute
END SUB

We use SUB...END SUB to bracket our subroutine code so that BASIC knows where the subroutine starts and stops. We give the subroutine a unique name (in this case filer) and we define parameters (if needed, in this case switch).

We won’t dive into this subroutine in-depth at this point, only note it’s overall purpose – to handle various types of file interactions. Since we passed the value 1 when calling filer the parameter switch will contain this value. This will result in CASE 1 being executed rather than CASE 2 or CASE 3. In other portions of the game’s code we’ll see calls to filer with different arguments – e.g. 2 and 3.

At first this may seem like a hassle. Aren’t we making the code more difficult to read by separating it into different locations? Why not put it directly in-line? There are two key reasons:

  1. The DRY Principle – “Don’t Repeat Yourself” – That is, you don’t want to write the same code at multiple locations in your program. Otherwise each time you make a change to this code you need to remember to make the update in all other locations in code that have this same code. By keeping the code in a subroutine you have only one location where the code is updated and it applies to all instances in which it is called. Applying this principle is a big boon of maintainability.
  2. If we were talking about a program of 30-40 lines one might legitimately argue that moving the code out of its in-place location is more trouble than good. As the program extends in length (this game is thousands of lines in length but still relatively short compared to most popular software developed these days!) the ability to manage the entirety of the code and it’s interrelations within one’s mind becomes impossible. By putting portions of the code in subroutines we “abstract” it and no longer have to consider the details of how the code runs unless we are actively making changes to the code.

Okay, okay, we didn’t make much progress today…but I’ll be back soon.

Leave a Reply