Wednesday, August 26, 2009

Playing with Qt Jambi

Over the last couple of days I've been playing around with Qt Jambi, the Qt bindings for Java, which are pretty cool. I haven't used them that much so far, but they seem really nice. I'd been starting to write this little car game thing, which is more a proof of concept at the moment, which I've now ported to be able to use Qt.

Try it as an applet here (note this is using ordinary Java swing, not Qt as I'm not sure if you can embed a Qt widget in an Applet (or in any AWT or swing element). Then there'd be the trouble of having to download Jambi which is fairly big.

Use your arrow keys to drive around, Ctrl+R resets (in hindsight, not a good choice as it coincides with firefox's and epiphany's reload page shortcut (possibly other browsers too)). The physics is terrible, but I find it fun just driving around, making pretty patterns. You might need to click the applet to give it focus.

Or you can download it here. That includes the source. To run it using qt, it will need to find the Jambi jar file, and it looks in the current directory and "/usr/share/java/qtjambi.jar" (the latter is the default location in Ubuntu (and possibly other distros), so you just need to install the jambi package). You can download Qt Jambi here. Then you need to pass the command line option '--qt'. By default I try and use opengl (which is faster), if it doesn't seem to work, try '--qt --no-gl' to use the regular qt rendering engine.

The number in the top right corner is how many milliseconds it's taking to draw each frame (averaged over the last 100 frames I think). I found Qt with no opengl to be about the same speed as Java swing at 640x480, which I found surprising, I thought Qt would be significantly faster, though at full screen swing slows right down, while Qt only takes a little bit longer, and with opengl it's about 25% faster. YMMV.

I had to be a bit sneaky when writing this so that the swing version would run fine even without the Qt libraries. My first (which I thought was nicer) implementation didn't work, as there were references to the Qt classes in the classes that were being run, even though they weren't used. So when I redid it I had to split everything up, a swing version and a Qt version, so that when swing was being used there would be no references to the Qt classes. I wasn't sure that that would work, but it did, which is pretty cool. Enjoy.

Edit: It appears it's pretty hard for this thing to regain focus, I should probably look into that, enjoy it if you can get it to work, otherwise download the jar, that's more likely to work correctly.

Tuesday, August 25, 2009

Windows Network Grrr...

I've come to be incredibly frustrated with how networks work under Windows (XP) over the past year or so. I'll explain my set up a little first, I have a laptop which runs Ubuntu, I connect to the Internet via another computer (running Windows XP) which connects directly to our cable modem. I thought I'd have issues with this seeing as how I wasn't using Windows, but on my side it has been a breeze (much easier than in Vista on the same laptop).

The thing that irritates me is that every time the driver, firewall etc. is updated, or just at random other times, the computer stops me from connecting. I haven't changed anything on my laptop, I just can't connect to the network. So far we've managed to fix the problem by changing some option somewhere on the XP computer, in some nested dialog box, or whathaveyou after trying various things for around an hour. As I said earlier, it's incredibly frustrating. A thing like that should just work, which it does in Ubuntu, but not in XP (though I haven't tried the other way around). Rant over.

Thursday, August 6, 2009

The magic that's coming to your browser

I was reading on slashdot an article (actually it's more a blog) about some of the cool things that people can now do with javascript and HTML5 and the like in newer browsers. (Sorry if you're using IE, there may be new versions, but they don't support a lot of this stuff.

Have a look for yourself at some of these:

All of these are pretty cool, and note that they don't need any browser plugins to run (though some of them use external scripts, which is kind of like a plugin). I'll draw your attention to the last one in particular, notice that it doesn't use HTML, but the main page is an svg. People have been talking about how this could be the future of the web (though IE doesn't support svg at all yet AFAIK, so if it will be, it'll be a long time away). You may know of svg as a vector graphics format, wikipedia uses it quite a lot for graphs and things nowadays, where it is inherently better than standard images with pixels and all that, but it is a whole lot more than just a vector graphics format, which is why most browsers haven't fully implemented it yet (it's a whole pile of trickiness).

This could also potentially displace flash, which I'm a bit ambivalent about. At the moment I see some places where flash is used well, but all too many where it is used poorly, and the same could be done with these kind of technologies. Also, flash is a whole lot more mature that this, so it can do a whole lot more at the moment (you may have noticed the above could be quite CPU intensive), but there is good competition in the browser space so these should improve rapidly.

I hope you enjoyed my plagiarism of a slashdot article, and a bit of inane ramble.

Probably

When people ask me if I can do something, if I can come to something, etc. and I think I can and want to, my general response if 'probably.' This must infuriate some people who want to know things for "sure" and be able to plan. But I have good reasons for saying probably over definitely, sure, etc. in that it's impossibly to mean something like definitely, or sure when you're ntalking about the future. Anything could happen. And while my level of commitment is generally above the level usually referred to by probably, I can't think of a succinct way that I could say it more precisely.

In emails and things like that, I will sometimes say "Yes, barring some exceptional circumstance" or the like, but that's a bit of a mouthful in a conversation. "Almost certainly" is pretty good, but then I have to go through this whole thing when they ask me why I'm just "almost."

Oh, the tedium of trying to be precise...

Tuesday, July 21, 2009

RIP Marcoland

One week ago, the game I had been playing for a ridiculously long time went the way of the moa. I signed up to Marcoland back in 05, when I was in Japan, in November if I remember rightly. That's 3 and a half years ago - about a sixth of my life, crazy to think I played it for so long. In that time it was one of the things I'd do on the Internet every day, and I would hate to think the amount of time I spent there.

It was a MMORPG (Massively Multiplayer Online Role-Playing Game), you spent your time increasing your stats. There were also towns (the ML version of clans/guilds/etc), which would have wars with each other, a daily arena, a pvp system, and a whole bunch of other things. But, as with virtually all games of this type it got pretty repetitive, and if it hadn't been for the community there, in towns, in chat, in the forums, I'm sure I would've left a lot sooner. It was one of those games where you could play it in 5 minutes, or spend however much longer than that you wanted to there. And it was completely free, you couldn't get any advantages by donating (just nice things like a coloured name, an avatar, no ads, a custom emoticon, etc).

It's weird to think that it's gone, but I'm fairly sure it won't be back, at least not permanently that is. I've been finding I have a lot more free time so it's probably a good thing. I'd thought about quitting for a while for that very reason. I remember the day the site went down, a week ago now, I got on my computer, finished doing the other things I do on the net, and then was like, what do I do now?

I quite enjoyed the game though, it appealed to me in a number of ways. Firstly, it was a long term game, it involved a lot of planning. It also gave you a lot of stats, which I always like going through. I even programmed a few things for it, like a simulator to simulate the training beach to figure out what monster would be best to fight, a town war visualiser thing (which I never finished) and a little script-like thing that would parse the rankings pages to list players with the most protection.

The in game chat room was almost certainly the place I wasted the most time. I didn't start using this until I had been playing for about a year (or so, can't remember exactly), but I spent so much time there. Met a bunch of people - who I'll sadly lose contact with now. I had something like 80,000 chat lines I think. Which is sick. All that time lost. I was even a chat mod for a few months before the end.

I was pretty strong as a player goes, about 100th in terms of total stats, and about 30th in terms of stats/age (which gave a fairer reflection of how well younger players were doing). I would've been better than this but I didn't play so well at first, but I made up a lot later.

So would it have been better if I had never started playing? I reckon no. All in all I reckon the time I spent playing was a positive. It helped me out I reckon, and there'll be people I'll try to not lose contact with. It was something that was always with me, and would often cheer me up when I wasn't feeling so great. I don't want to play another similar game though, because I know how much time it takes, and would prefer to spend the time studying, or out in the world with friends, or whatever.

Anywho, good bye Marcoland, you were good while you lasted. And thanks Marco, thanks for all you gave to the players of ML.

Saturday, July 18, 2009

String Permutations II

I thought of a few ways I could optimise the permutation routines from yesterday, which were relatively simple, so I thought I'd try them out. I'm always interested in ways I can make code faster, and enjoy testing things like this out. Most of the improvements this time round were to the iterative method:
 1: public static List<String> getAllPermutationsIteratively(String s) {
 2:    int length = s.length();
 3:    if(length <= 1) {
 4:       return Arrays.asList(s);
 5:    }
 6: 
 7:    int numPermutations = factorial(length);
 8: 
 9:    List<String> permutations = new ArrayList<String>(numPermutations);
10: 
11:    for(int permNo = 0; permNo < numPermutations; permNo += 2) {
12:       char[] charsLeft = s.toCharArray();
13:       
14:       int size = length;
15:       
16:       char[] charArray = new char[length];
17:       
18:       int i, factorialSize = factorial(size);
19:       for(i = 0; i < length - 2; i++) {
20:          // The division means that the index only increases after so many iterations
21:          // The remainder reduces the number range to the number of iterations the index stayed
22:          // the same for in the previous division
23:          int factorialSizeMinusOne = factorial(--size);
24:          int index = (permNo % factorialSize) / factorialSizeMinusOne;
25:          factorialSize = factorialSizeMinusOne;
26:          
27:          charArray[i] = charsLeft[index];
28:          
29:          // Copy all elements from (index+1) onwards back one place, i.e. remove the element at
30:          // index. Note that size was decremented earlier.
31:          System.arraycopy(charsLeft, index+1, charsLeft, index, size - index);
32:       }
33:       
34:       charArray[i] = charsLeft[0];
35:       charArray[i + 1] = charsLeft[1];
36:       permutations.add(new String(charArray));
37: 
38:       charArray[i] = charsLeft[1];
39:       charArray[i + 1] = charsLeft[0];
40:       permutations.add(new String(charArray));
41:    }
42:    return permutations;
43: }
I got a new source code to html formatter by the way which I think gives better results. The first change isn't for performance, but just ensures it works properly for strings of length 0 (they could just as well throw an exception) and 1, which would've worked in my old iterative version, but not in my old recursive version (I think).

Next, I changed the loop so it increments by two each time, and did the final two letters e.g. AB and BA manually, which was a big performance improvement. The next one was saving the calculated factorial values, which saves one factorial calculation through iteration of the inner loop, which is again nice. I tried various ways of making this faster, but couldn't make it faster than it is here. Then instead of using an ArrayList of Characters, I changed it to use an array of chars, which performs better, but is a little trickier. This brought the speed of this version to be roughly equivalent to the recursive version.

Now I changed the recursive version to:
 1: public static List<String> getAllPermutationsRecursively(String s) {
 2:    int length = s.length();
 3:    if(length <= 1) {
 4:       return Arrays.asList(s);
 5:    }
 6: 
 7:    List<String> permutations = new ArrayList<String>(factorial(length));
 8: 
 9:    char[][] charArray = getAllPermutationsRecursively(s.toCharArray(), length, length - 1);
10:    for(int i = 0; i < charArray.length; i++) {
11:       permutations.add(new String(charArray[i]));
12:       charArray[i] = null; // Let the gc be able to clear this up
13:    }
14: 
15:    return permutations;
16: }
17: 
18: // length is the length if the original String
19: // pos is the current position in the char[] which a character will be added to. On the first
20: // call of this it should be one less than length
21: private static char[][] getAllPermutationsRecursively(char[] chars, int length, int pos) {
22:    char[][] toReturn = new char[factorial(pos + 1)][];
23: 
24:    // Though the == 1 case is simpler, it's faster if this is the base case
25:    if(chars.length == 2) {
26:       // There are two combinations, [0, 1] and [1, 0]
27:       toReturn[0] = new char[length];
28:       toReturn[1] = new char[length];
29: 
30:       toReturn[0][0] = toReturn[1][1] = chars[1];
31:       toReturn[0][1] = toReturn[1][0] = chars[0];
32:    } else {
33:       int toReturnPos = 0;
34:       for(int i = 0; i < chars.length; i++) {
35:          char c = chars[i]; // The current char
36: 
37:          // Make a copy of the array without c in it
38:          char[] newChars = new char[chars.length - 1];
39:          System.arraycopy(chars, 0, newChars, 0, i);
40:          System.arraycopy(chars, i + 1, newChars, i, chars.length - i - 1);
41: 
42:          // Add c to each of the returned arrays of chars
43:          for(char[] charArray : getAllPermutationsRecursively(newChars, length, pos - 1)) {
44:             charArray[pos] = c;
45:             toReturn[toReturnPos++] = charArray;
46:          }
47:       }
48:    }
49:    return toReturn;
50: }
This one only has a couple of minor changes, nothing major, it seems I did it pretty well the first time.

While doing this process I burnt my fingers a little with relatively shoddy benchmarking. At first I was getting wildly erratic results, even though I would run each version say 5 times, the time would vary by 50% (or more) between runs, which I thought was pretty crazy. The first thing I thought of doing to combat this was set my cpu governor to performance rather than dynamic, which means that it'll sit at full speed all the time, rather than throttling down. This made a remarkable difference, it seems there was a bit of lag in it going to full speed. I also have backround programs running, which you shouldn't really, but as I only run this in one thread, it shouldn't make too much of a difference.

The second main thing was that the JVM wasn't getting enough memory, so the one running second would run slower as the gc would run a lot more. By setting the starting and finishing memory to 512 MB (more than it should need, but I wanted to be on the safe size), I eliminated this discrepancy to a large degree. This also speed up the speed of execution by as much as two times, which is pretty remarkable. What brought this to my attention was running on "PARTICLEX" it would crash with an out of memory error when I changed the code and ran the iterative version first. It must've been right on the cusp of running out of memory before.

For a bit of analysis - the performance of the two in terms of speed is very close now. However in terms of memory, the iterative version should use less, but after the couple of changes I made to the recursive one that shouldn't be too bad. The iterative version is slightly shorter, so would probably get a slight preference by me, but hey. (Not that I can see any practical purpose for this).

Friday, July 17, 2009

String Permutations

Apparently the "Challenge" in the COMP102 assignment was to write some code to print out all the permutations of a string. (Say for ABC, that'd be ABC, ACB, BAC, BCA, CAB, CBA). However that challenge was apparently left over from last year, and due to the number of points of the paper changing, they haven't covered recursion yet. So I got challenged by a friend to write a program that did this without using recursion (which is the natural way I would do it).

I puzzled over this for a while, trying a couple of ways, with little success. Then I went to a tutorial for another paper, but didn't really pay much attention, more trying to figure out a solution for this problem. I made a little bit of progress, but the solution I implemented when I got back to the lab didn't work. But then I had a bit of a brain wave as I was working and managed to do it. Here's the code:
  1: public static List<String> getAllPermutationsIteratively(String s) {
  2:    int length = s.length();

  4:    List<Character> chars = new ArrayList<Character>(length);
  5:    for(char c : s.toCharArray()) {
  6:       chars.add(c);
  7:    }

  9:    int numPermutations = factorial(length);

 11:    List<String> permutations = new ArrayList<String>(numPermutations);

 13:    for(int permNo = 0; permNo < numPermutations; permNo++) {
 14:       List<Character> charsLeft = new ArrayList<Character>(chars);

 16:       char[] currentString = new char[length];

 18:       for(int i = 0; i < length; i++) {
 19:          int index = (permNo % factorial(charsLeft.size())) / factorial(charsLeft.size() - 1);
 20:          currentString[i] = charsLeft.remove(index);
 21:       }

 23:       permutations.add(new String(currentString));
 24:    }
 25:    return permutations;
 26: }
Line 19 contains the magic statement. I commented this as, "The division means that the index only increases after so many iterations. The remainder reduces the number range to the number of iterations the index stayed the same for in the previous division." I don't know if that helps all that much, but if you write down a table (which I can't be bothered doing) it makes a lot more sense what's happening. (Or get it to process "0123" or "01234" and print out each string in the resulting list)

I then wondered how this would compare to a recursive implementation, so did one of those too:
  1: public static List<String> getAllPermutationsRecursively(String s) {
  2:    int length = s.length();

  4:    List<String> permutations = new ArrayList<String>(factorial(length));

  6:    for(char[] c : getAllPermutationsRecursively(s.toCharArray(), length, length - 1)) {
  7:       permutations.add(new String(c));
  8:    }

 10:    return permutations;
 11: }

 13: private static char[][] getAllPermutationsRecursively(char[] chars, int length, int pos) {
 14:    char[][] toReturn = new char[factorial(pos + 1)][];

 16:    if(chars.length == 2) {
 17:       toReturn[0] = new char[length];
 18:       toReturn[1] = new char[length];

 20:       toReturn[0][0] = toReturn[1][1] = chars[1];
 21:       toReturn[0][1] = toReturn[1][0] = chars[0];
 22:    } else {
 23:       int toReturnPos = 0;
 24:       for(int i = 0; i < chars.length; i++) {
 25:          char c = chars[i];

 27:          char[] newChars = new char[chars.length - 1];
 28:          System.arraycopy(chars, 0, newChars, 0, i);
 29:          System.arraycopy(chars, i + 1, newChars, i, chars.length - i - 1);

 31:          for(char[] charArray : getAllPermutationsRecursively(newChars, length, pos - 1)) {
 32:             charArray[pos] = c;
 33:             toReturn[toReturnPos++] = charArray;
 34:          }
 35:       }
 36:    }
 37:    return toReturn;
 38: }
Despite this being a little longer, conceptually I think it's much simpler. (Yes, I did strip out the comments to be annoying). It's not the first version I wrote, but rather as optimised as I could be bothered doing, making it much faster than my original naive implementation.

This version turns out to be more than twice as fast as the iterative version. The two main reasons for this are that the iterative version copies, then removes the elements of a List copy of the chars in the string for every string returned, and it also does a whole lot of remainder and division operations.

Oh yeah, if you're wondering this is my factorial function:
  1: private static int factorial(int n) {
  2:    int factorial = 1;
  3:    for(int i = 2; i <= n; i++) {
  4:       factorial *= i;
  5:    }
  6:    return factorial;
  7: }
I tried a few versions, including saving each value to a list, then an array so they wouldn't have to be calculated again, and having the first 10 values precalculated, but these were slower, so I went back to this implementation. It's probably got something to do with the way the compiler optimises it.

The other thing to note with this implementation is that there is a maximum length for the string. Say the length of the input string is n, then n! must be less than 2^31 (the maximum value of an int) otherwise the arrays cannot be made big enough to fit all the permuatations. This means you can use words at most 12 letters long. In practice, I only got it to work for strings of length 10 or less. I ran out of stack space, even when allocating 2500 MB for a 11 letter word. It wouldn't let me set the memory to 3000 MB or higher for some reason.

This shows I'm up to the COMP102 challenge. Boy is that satisfying.