Civil War Strategy Game (Part 1): The Main Routine

Lets pick up in CWSTRAT.BAS following our declarations and include on line 19:

isreplay = 0

We set a variable named isreplay to 0, this is used to track whether this is the first game the user is launching after loading the application.

newgame:

This is a line label and is linked to the infamous GOTO statement. I’m not a fan of line labels and we’ll seek to refactor these out when we begin changing the code…but we aren’t there yet.

Next, a number of variables are initialized:

isgameover = 0
canrecruit = 0
emancipate = 0
usadv = 0
filel = 1
vicflag(1) = 1
FOR k = 1 TO 4
armysize(k) = 0: armyloc(k) = 0: armymove(k) = 0: armylead(k) = 0: armyname$(k) = ""
NEXT k

FOR k = 1 TO 2
navysize(k) = 0: navyloc(k) = 0: navmove(k) = 0
rr(k) = 0: victory(k) = 0: tracks(k) = 0
NEXT k

These variables provide state throughout the program. Unfortunately, we don’t have exact documentation on what each of these variables does so one of our first tasks as we walk through the code is to identify the purpose of the variables and how they are utilized throughout the code. Lets take a quick look at these variables:

  • isgameover – When initialized this variable is set to 0. The only time it is changed is in SUB maxx in CWSTRAT2.BAS. The maxx subroutine shows the high score and saves this information to a high score file. It then sets isgameover to 1. Back in CWSTRAT.BAS we have an early check on the isgameover variable and if its value is greater than zero a GOTO newgame is executed, starting a new game. Pretty simple, a little bit of bouncing around to find how it works.
    • Eventually we’ll want to look at potentially refactoring the code so that instead of setting a variable value and then looking for that value to have changed we instead simply call from SUB maxx to a SUB newgame, but at the moment we do not have newgame as a SUB but part of the main routine.
    • You may wonder why the code for GOTO newgame is found back in CWSTRAT.BAS instead of in CWSTRAT2.BAS’ SUB maxx. This is due to the way line labels work. Line labels only work within their context – thus a line label cannot be called from another subroutine/function than where that subroutine/function exists.
  • canrecruit – Determines whether the Recruit menu option is available by checking if the amount of cash a player has exceeds the cost of recruiting additional troops.
  • emancipate – There are “special events” which occur at semi-random times throughout the game, including the Emancipation Proclamation. Unlike many other events which can occur multiple times, Emancipation can only occur once. This flag is changed from 0 to 1 when the emancipation event has occurred once and ensures it does not run again.
  • usadv – The US had a significant industrial advantage over the CS in the American Civil War. An attempt is made to reflect this through the usadv variable. At some point we may refactor the variable to be clearer – e.g. usadvantage. Its longer, but my preference is for slightly longer clearly self-documenting naming than more concise but less clear naming.
    • I am unsure of Mr. Hutsell’s personal preference. At the time of Hutsell’s original composition of this software there were significant constraints on what one could do with coding due to limits on code file sizes.
  • filel – This flag determines whether there are existing saved game files. If there are, then it allows the Load menu option to display under Files, otherwise it hides it. No use letting people load games that don’t exist.
    • At some point we might refactor the variable name to something like savedexists.
  • vicflag() – In this game there are a number of “Victory Conditions” which trigger the end of the game. Which conditions are enabled at any given time can be controlled in the games’ settings. The vicflag() array contains individual values correlating to each victory condition available. By reading this array the program can determine whether to trigger the game ending based on the appropriate indexed value within the array.
  • The k variable using in our FOR...NEXT loops is a value for keeping track of how many times the loop has executed and ending it at the appropriate iteration. It does not have any long-term meaning for the application. Essentially what happens here is that the first time the loop runs k in the arrays within the loop is swapped out for 1, the second time it is swapped out for 2, and so on.
    • This is ensuring that all armies are non-existent when the game first starts, it doesn’t want to accidentally retain some state from any previous game.
    • The various arrays delineate particular aspects of the army state – size, location, movement, leadership ranking, name.
    • For the sake of keeping code concise, : can be used to place multiple commands on a single line. I, personally, prefer placing commands on separate lines. This is also preferable with MS BASIC due to some debuggers reading multiple statements on a single line as a single statement during the debugging process.
  • We again use the k variable, the name here is not important. It is simply a variable we use to keep track of how many times we have executed our loop. This time we only go through the loop twice – this is because for the following arrays there are only two possible indexes. For example, the navy can be either US or CS, there is no option for a third navy nor can (in this game) the US or CS have multiple navies as they can multiple armies.
    • For the navies we set size, location, and movement.
    • For the railroad we set rr(x) where x is side 1 (US) or side 2 (CS) and a value of 0 indicates that there is no railroad movement available (thus the game will hide the Railroad menu option).
    • tracks(x) keeps track of where an army is moving from/to via railroad.
    • victory(x) keeps track of the relative victory points each side has secured. When certain events occur (e.g. winning a battle) points are added to the victor’s victory points total.

Leave a Reply