Take time to think(!)

As a note to my future self: Take time to think!

*sigh*

Even at my advanced age, if I don’t think through an algorithm I can still waste an awful lot of time.

As an example I just started working on a complex algorithm for my Android football game based on the initial thoughts in my brain, and came to regret it. After recovering from that faux-pas I decided to write just a few simple notes like this to clarify my thoughts:

Running Plays

The result of the play depends on:

  • the offensive play called (OffensivePlay)
  • the defensive play called (DefensivePlay)
  • the primary blockers for the play
    • depends on o-formation
  • the primary defenders for the play
    • depends on d-formation
  • the skill of the rb

Passing Plays

The result of the play depends on:

  • the offensive play called (OffensivePlay)
  • the defensive play called (DefensivePlay)
  • the receiver rating
  • the rating of the defender covering the receiver
  • the qb rating
  • the o-line's pass-blocking ratings
    • depends on o-formation
  • the d-line's pass-rushing ratings
    • depends on d-formation

Just taking 10-15 minutes for that thought process would have saved me the 30+ minutes it took to write, unwrite, and rewrite the wrong code I wrote because I wasn’t thinking hard enough.

For instance, the notes about the running plays tells me to write a function like this:

def runningPlayResult: Result = (
    offensivePlay: OffensivePlay,
    defensivePlay: DefensivePlay,
    primaryBlockers: List[OffensivePlayer],
    primaryDefenders: List[DefensivePlayer],
    runningBack: RunningBack
)

Instead I did something else that wasn’t far from this, but was a mistake and a waste of time nonetheless.

Using comments in functions

In a related note I try to do the same thing when writing complicated functions. I first write the algorithm as a series of TODO notes, like this:

//TODO get the total ratings for all blockers
//TODO get the total ratings for all defenders
//TODO create a multiplier using BlockerRatings/DefenderRatings
//TODO create a new map using that multiplier

The I add the correct code as I figure out how to write it:

//TODO get the total ratings for all blockers
int totalBlockerRating = getTotalBlockerRating(offensiveBlockers, yourTeam);

//TODO get the total ratings for all defenders
int totalDefenderRating = getTotalRunDRating(keyDefenders, opponentTeam);

//TODO create a multiplier using BlockerRatings/DefenderRatings
float offensiveMultiplier = (float)totalBlockerRating / totalDefenderRating;

//TODO create a new map using that multiplier
Map<Float, Float> playMap2 = new HashMap<>();
for (Map.Entry<Integer, Float> entry : playMap.entrySet()) {
    float newKey = entry.getKey() * offensiveMultiplier;
    playMap2.put(newKey, entry.getValue());
}

Sometimes — as in the first example — I like to step away from the computer so I can think, and in the second case I just document what I want as a series of TODO statements and then implement the needed code.