Weird

When Mood Music
2012-04-20 16:58:00 boggled Shuttin’ The Ole Dirt Down – Rev Hammer

Even though 1 + 1 ≠ 2, the following test passes. (swampSize is set elsewhere to be 4)

public void testDrawSwampMap() {
//Set up
Swamp s1 = new Swamp(swampSize);
String actualMap;
String expectedMap;

//Get value. The swampMap will vary every time the Swamp is created because
//an Ogre is added IN A RANDOM PLACE each time a Swamp is created.
//So remove the ogre, then draw the map.
s1.removeCreature(s1.ogreXcoord(), s1.ogreYcoord(), “OGRE”);
actualMap = s1.drawSwampMap();

expectedMap =
“(0,0): t(1,0): t(2,0): t(3,0): tnn” +
“(0,1): t(1,1): t(2,1): t(3,1): tnn” +
“(0,2): t(1,2): t(2,2): t(3,2): tnn” +
“(0,3): t(1,3): t(2,3): t(3,3): tnn”;

//Test
assertEquals(expectedMap, actualMap);
}

So “=” ≠ “equals”!

1 + 1 ≠ 2

When Mood Music
2012-04-20 16:05:00 annoyed, puzzled In The City – Razorlight

Following on from here, take a look at this code:

package _06Swampless_JUnitTests;

public class testString {

public static void main(String[] args) {
String piece1 = “donkeyOGREsnake”;
String piece2 = “donkeysnake”;
String piece3 = piece1.replace(“OGRE”, “”);
if (piece3 == piece2) {
System.out.println(“yeehah”);
}
System.out.println(“piece1: ” + piece1);
System.out.println(“piece2: ” + piece2);
System.out.println(“piece3: ” + piece3);
} //end main

} //end class

This sets up pieces of text which are identical except the first one has some extra characters, namely “OGRE” . A third piece is created as the first one minus “OGRE”. So the third piece should be the same as the second. The if block will print ‘yeehah’ if this is true and ‘boo hiss’ if they’re not.

The actual output is:
boohiss
piece1: donkeyOGREsnake
piece2: donkeysnake
piece3: donkeysnake

So two identical-looking pieces of text are in fact not identical. Bah!

Need drugs!

 

When Mood Music
2012-04-20 13:31:00 shattered Chinese Rock – The Ramones

I’ve just drunk my first coffee for over 2 years. 90 minutes of intensely watching 11-year-olds cycling – and trying to demonstrate and lead them towards good cycling habits – is utterly draining. And this was in a school play-ground. I’m not really looking forward to taking them out on the road.

Now I’m back to writing JUnit tests…

Testing my head

 

When Mood Music
2012-04-19 15:24:00 puzzled Fiji – K-series

Original thoughts
On the last of the JUnit tests, namely testing writeSwampToDisk(). This is called within the game if the user decides he or she is bored with watching creatures move around and try to kill each other.

The way I’d want to test it is to invoke a game and record the current state, e.g. the current value of Swamp() or drawSwampmap(). Then I’d save the game (which automatically closes it. Then I’d recall the game and compare the recalled state with the previously-noted saved state. If the two are the same, the read and write have succeeded.

The write method is within Swamp(), so that it can be called from Swamp()‘s basic routine. However, the read method is within a separate interface.

(The interface presents the user with a choice of new game or saved game.

  • If the user wants a new game, an new instance of Swamp() is kicked off.
  • If the user wants to recall a game from disk and a saved game exists, the interface’s read method is invoked.
  • [If there isn’t a saved game, the user gets a blocking for not reading the warning previously presented and a new game is started anyway.])

The read method can’t be in Swamp() because this would involve Swamp() trying to read itself. I’d like move the write method fromSwamp() to the interface (partly so I don’t have to write this test but mostly because that would seem neater) but the interface abdicates control to Swamp()‘s basic routine and then exits.

I guess the saved thing could be Swamp()‘s list of creatures, rather than Swamp() itself…… yes, that seems to work.

Some experimentation later
The test didn’t work when I compared lists of creatures. So to make it obvious, I’ve changed to comparing maps – purely textual output. While the two bits of text look identical, the test fails – implying they’re not!

Bah!

Destruction testing

 

When Mood Music
2012-04-18 14:37:00 puzzled Take a Breath (Live) – David Gilmour

Doggedly writing JUnit tests for my Swamp class.

Is there any point in writing a test for a method that randomly returns either ‘true’ or ‘false’? The only test I can think of is that the return value should b done of these values.

Also puzzled how I write a test for my method that draws a map of the Swamp and its Creatures. This will vary each time the game is run because an Ogre is placed in a random position each time the game is run, before the map is ever drawn.

bug-hunt!

When Mood Music
2012-04-17 22:25:00 frustrated The Robots – Kraftwerk

This morning I traced the ‘not working when recalled from saved state’ to the code that that calculates where the ogre is. (This is used to decide whether there should be a battle by counting the number of enemies at the ogre’s location. If there are none, no battle ensues. If there is only 1 enemy, there is a battle which the ogre wins and the enemy is removed. If there is more than 1 enemy, the enemies win, the ogre is removed and the game ends.)

During a brand-new game, the ogre-location method works fine. In a recalled-from-disk game, it doesn’t. The code in question (and rather questionable code) is in two pieces, one for the x-coordinate and one for the y-coordinate. Here’s the x-coordinate code:

public int ogreXcoord() {
    //Declare variable – it needs to be initialised, so use a silly number
    int ogreXCoordinate = 2000;

    //Code
    for (Creature tempCreature : creaturesInSwamp) {
        if (tempCreature.getType() == OGRE ) {
ogreXCoordinate = tempCreature.getxCoord();
} //end if
} //end for-each

    return ogreXCoordinate;
} //end ogreXcoord

The green bits are just comments to help humans read the code. The pink bits are reserved words, i.e words that have special meanings to Java and the blue bit is an example of an instance variable, i.e. a variable that occurs in every instance of the Swamp class.

The code translates as.
This method, named ‘ogreXcoord’ may be called from outside the Swamp class. It will return an integer.
Create an integer variable (which only exists within this method) called ‘ogreXCoordinate’ and sets its value to 2000.
One-by-one, put each Creature in this Swamp’s list of Creatures into a variable called tempCreature.
Then, for each version of tempCreature, if it is an ogre, then set
‘ogreXCoordinate’ to the value of the tempCreature’s x-coordinate.
When you have run through all the creatures and thus definitely have the required xCoordinate, pass this back to the code that called this method.

Why so complex? Only the ogre knows where it is. Each time it moves, it calculates new coordinates for itself and moves to these coordinates. (All Creatures do this, and don’t tell anyone where they are until asked.) So the program doesn’t know where the ogre is until it can ask him. And it can’t ask him where he is until it has found him – and it can only find him by looking through all the creatures in the Swamp and asking them in turn ‘Are you an ogre?’ (I guess this could be shortened by stopping asking once the ogre has been found. And he’s likely to be the first creature in the ‘CreaturesInSwamp’ list because he’s the first creature to be created once the swamp has been created. However, I don’t know that this is guaranteed.)

Anyway, I can show this works when the game is working – the ogreXCoordinate is always right. But in a recalled-from-disk game, this fails – the ogreXCoordinate is always returned as 2000. So the for-each loop is either not working or being ignored.

Bah!!!!!!

Bah humbug

When Mood Music
2012-04-16 17:43:00 confused Save The Day – Diss-cuss

Wierdness: so long as I start a new game each time, the game plays out as it should. However, if I recall a saved game from disk, the creatures appear not to battle and are effectively immortal.

This may or may not be connected with the moveAllCreatures() method in Swamp.class appearing to call moveCreature() in Creature.class at least twice per Creature.

If it were always twice, I’d be a little less confused.

Statistics

When Mood Music
2012-04-16 14:25:00 ground state, i.e. prevaricating Robber Rock – Yabby U

My lecturer tells me ‘All debugging code should be removed. The only exception is when a program can be run in debug mode as per SD1 coursework.’

I’ve saved a copy with the extra methods and commented-out pieces to track events elsewhere, then looked at what’s left after removing these undesirables.

 

Version lines ‘words’ characters characters that are spaces
complete code
340
1834
15,021
2654
comment lines removed,
i.e. just code lines
217
986
8345
1260
%
64
54
55
47
Hence comment lines
123
848
6676
1394
%
36
46
45
43
inline comments (e.g. //end method) removed,
i.e. pure code
217
873
7517
1148
%
64
45
50
43

So I’ve written 217 lines of code for this class of which around 50% is substantive – the rest is spaces and comments to allow humans to read it.

Programming coursework entries

When Mood Music
2012-04-16 12:29:00 sore Rino’s Prayer – Leftfield

With thanks to ggreig for alerting me to this…

It turns out I was using an image format that’s unsuitable for most browsers, so you may have been seeing ‘broken-link’ images or bank spaces instead of screenshots.

I’ve now converted the screenshots to PNG format – this seems to work in all the browsers I have for MacOSX Lion, Ubuntu Linux and Windows XP.