CodeWorrier

When Mood Music
2012-04-15 12:32:00 contemplative William’s Last Words – Manic Street Preachers

Original status
Returning to the programming project after a day of cycling and finishing some written coursework for another module, I was faced with a blur of methods (subroutines) written in the order I realised I needed them. These included some methods which were only there to test whether I could create, move and list my creatures.

The chronology followed the basic need to

  1. create a swamp and its ogre
  2. add enemies if luck so decided
  3. draw a map of the swamp and its denizens
  4. decide whether to have a battle
  5. the actual battle (so far only pseudocode).

In short, my code was an inaccessible mess. It didn’t help that the code for the Swamp called code for ogres and enemies which are in separate files. Given that my code has to be read and understood, I needed to tidy it. (Currently, only my lecturer and I need to read my code. However, if I end up writing code for anyone else, they – and maybe later workers – will need to be able to read and modify it easily.)

Problem statement
Given that my code is an inaccessible blur, how can it be tidied?

Solution methodology
It is surely sensible to break any long piece of writing into chunks, i.e. chapters, headings and subheadings etc. So why not do the same to my code?

As far as I know, Java doesn’t allow headings and subheadings. I’m pretty sure there’s no such feature in the IDE I use. However, there are two comment styles:
//comment

and

/** *******************
* comment *
********************* */

The green style is used throughout to say what individual methods, bits of method and individual lines do. I believe the blue style is now used to feed the JavaDoc system and I’ve seen it used for header blocks (name of program, author(s), copyright status, etc). However, I’ve not yet got into JavaDoc.

Solution
So ‘chapters’ in my code are headed
/** *******************
* ALL CAPS *
********************* */

and ‘sections’ are headed
/** *******************
* lower case *
********************* */

Recommendations of how this should really be done are very welcome!

Corollary
Chunking my code and moving the methods so they fit the chunks has also been helpful in that I’ve isolated methods no longer used into a METHODS USED ONLY DURING DEVELOPMENT/TESTING. I feel I should get rid of them but I’m not sure. Recommendations are again very welcome.

I need to write a piece on how my code works, including some comment on development – so in this instance it might be better to keep them. Also, this code won’t be transmitted (unlike JavaScript doing stuff in your browser or naughty things to your computer) so it doesn’t **need** to be concise.

Current status
In my Swamp class, I now have chapters for

  1. INSTANCE VARIABLES, CREATOR, SETTERS AND GETTERS
    8 items
  2. CREATE AND ADD OGRE TO SWAMP
    2 methods
  3. CREATE AND ADD ENEMIES TO SWAMP
    3 methods
  4. DRAW MAP OF SWAMP, INCLUDING LOCATIONS OF ALL CREATURES
    1 method, which is currently horribly inefficient because all creatures are examined (swampSize)^^2 times
  5. MOVE ALL CREATURES
    1 very short method that calls code from ‘Creature’ class
  6. BATTLE
    This has 5 sections:

    • Find ogre’s location – this will be called each turn of the game and will update an instance variable (2 methods)
    • Find and record how many enemies are in ogre’s location (1 method)
    • Decide whether there should be a battle (1 method)
    • Actual battle (3 methods)
    • Methods for removing creatures (2 methods)

     

  7. METHODS USED ONLY DURING DEVELOPMENT/TESTING
    5 methods

My Creature class has

  1. INSTANCE VARIABLES, CREATOR, SETTERS AND GETTERS
    13 items
  2. MOVE THE CREATURE
    2 methods – although I should split one of these into 3 separate methods
  3. WHERE IS THE CREATURE?
    1 method, currently unused.

My Ogre and Enemy classes just have creator methods, so don’t need chunking.

Bah!

 

When Mood Music
2012-04-13 22:17:00 relieved William’s Last Words – Manic Street Preachers

Much experimentation on a simpler version of my swamp later, it turns out I can remove creatures from the swamp’s creature collection after all. The trick is to FINISH finding the position (technically, the ‘index’) of the relevant creature first (i.e. finish the for-each loop), THEN remove the creature with that index. Now to try it on the full version of the swamp!

oops!

When Mood Music
2012-04-13 18:57:00 dorky The whole of the moon – The Waterboys

Oops – I forgot to call the code that invokes a battle. So no matter how many enemies are in his current grid-square, the ogre is immortal!

The following should NOT be the case:

casualty map

When Mood Music
2012-04-13 18:44:00 amused Who Needs Information – Roger Waters

The music was unintentional but is amusingly appropriate.

I can add a lot of creatures, move them all around and draw a textual ‘map’ of where they all are. Even better, it agrees with where the creatures themselves say they are!

 

  • List of creatures and their individuate coordinates 1
  • Independently-generated map 1
  • List of creatures and their individuate coordinates 2
  • Independently-generated map 2

The code to draw the map is horribly inefficient: for each grid-square in each row, each creature is asked ‘should you be added to the list of creatures for this grid-square?’. For a 4 by 4 swamp, each creature is interrogated mercilessly 16 times! I hope I can find a better way – maybe each creature could have a record of whether it’s been added to the map. But then it would need to be interrogated about this too!

If I was still working with grid-square objects, the code would have been ‘for each grid-square in each row, ‘give me a list of your contents’. But that approach didn’t work because of the difficulty of moving creatures.

Don’t count your chickens

When Mood Music
2012-04-13 15:05:00 awake White Noise – Stiff Little Fingers

And now

  1. The ogre is automatically created when the swamp is created. (There’s a boolean to record whether he’s present/alive. This will be useful in deciding whether the game should end.
  2. I can count the enemies currently threatening the ogre.

So:

  1. Create swamp and ogre
  2. Will an enemy arrive?
  3. Yes – here it is!
  4. Move the denizens:
  5. How many enemies currently threaten the ogre?
  6. Will another enemy arrive?
  7. Yes – here it is!
  8. Move the denizens:
  9. How many enemies currently threaten the ogre?

Now I can decide whether to have a battle and then work out the outcome.

shake it all about

When Mood Music
2012-04-13 14:18:00 amused Shake Your Body (Down To The Ground) (Full Intention Mix) – Full Intention

And now I have a method to move the creatures all about:

So:

  1. Add an ogre
  2. Will an enemy arrive?
  3. Yes – here it is!
  4. Keep those beasties rolling!

 

populating the swamp

When Mood Music
2012-04-13 13:57:00 awake the ping of incoming emails

More farting about later, I now have a Swamp class which has a collection to hold creatures. I can add an ogre to a random location, then decide (and for now, report) whether an enemy is to be added, then do any necessary enemy-population augmentation. (The enemies always arrive at (0,0)). I also have a method to report which creatures are currently in the swamp and where they are.

So:

  1. Add an ogre
  2. Will an enemy arrive?
  3. Yes – here it is!

On the next go:

  1. Add an ogre
  2. Will an enemy arrive?
  3. No – poor ogre is lonely (but he likes it that way).

success?

When Mood Music
2012-04-13 01:16:00 anxious the whirring of Iggy’s fans

Lots of anxiety today: the condition to ensure my creatures didn’t move illegally gave rise to infinite loop after infinite loop. Having 4 sorts of creatures represented as integer values within grid-squares gave rise to LOTS of duplicated code. Aaarrggh!

I’d resisted coding the creatures as objects, despite the opportunity to show I understood inheritance (creature = ogre or enemy; enemy = donkey, parrot or snake) because I feared that there would be a class between the creatures having coordinates and the grid-squares having coordinates. The creature would have to get its coordinates from the grid square in which it currently resided. But while moving, it would have no source of coordinates. Worse, how would a creature tell a grid-square “I’m moving in – increment your count of my type of creature!”?

It struck me today that there may be no need for formal coding of grid-squares. If the creatures know and can change their own co-ordinates on command, then so long as they can’t move past the upper or lower bounds of the swamp, then things should work – or so I thought.

On its own, code of the form works.

public static void move(int size, int Coord) {
double decider;
int limit = size – 1;

do {
decider = Math.random();
if (decider < 0.5) {
Coord = Coord – 1;
} //end if
else Coord = Coord + 1;
} while (Coord < 0 || Coord > limit);
} //end move

The while condition says ‘keep trying while the co-ordinate is negative or past the upper limit’.

But try as I might, putting this into the code for a creature didn’t work – in fact the IDE came perilously close to choking Iggy.

So I’m doing it in a klutzy, non-satisfactory way:

  • If the current coordinate is 0, it’s then either unchanged or increased by 1.
  • If the current coordinate > 0 and < limit, it’s then decreased by 1, unchanged or increased by 1.
  • If the current coordinate is at the upper limit, it’s then decreased by 1 or unchanged.

To make an actual move, I run through the above process twice, once for x-direction and once for y-direction.

To ensure there is some movement, I find the x-distance travelled and the y-distance travelled: if both of these are zero, a boolean is set to ‘false’. The ‘make a move’ code is wrapped in a do/while loop which forces the code to be repeated until the boolean becomes true.

So now I can add an ogre to my program at a random place and a random choice of enemy at coordinates (0,0). Tomorrow I aim to have the game mechanism set up: this starts by placing an ogre at random. The luser is asked if another turn should occur. (If not, the game will quit.) At the start of each turn, all creatures already present move, then there is a finite chance of a new enemy turing up at (0,0).

After that, it’s just a matter of being able to serialise the game state so it can be saved, creating a set of tests and drawing UML diagrams.

bah!

When Mood Music
2012-04-12 00:57:00 aggravated Stars and Stripes of Corruption – Dead Kennedys

Bah! It seems to be time to stop. I’ve got methods which **should** move the ogre and his enemies reliably but…
An ogre is placed at random:

A suitable number of enemies arrive in the left-most square:

He moves – but in this case he just disappears. I guess he’s escaping the bounds of a do-while loop!
.

Then the donkeys should move – but this method appears to have gone to Cupertino.

Time to sleep!