Lode Runner 4K

This is an easy change you could do which hopefully will improve things a bit:

if (crazyMode> 0) { crazyMode = crazyMode - 1 find nearest ladder or edge and climb up/climb down/jump down. } else { If(player above) find nearest ladder and climb up if(player below find nearest ladder or edge to jump off if(player on same level) { if(possible to close in on X) close in on X // It is possible to come closer on the X-axis, so do it! else crazyMode = 100 + random(100) // It is not possible to come closer on the X-axis, switch to crazyMode for 100 to 199 steps. } }
It will stop the enemies from getting stuck which is the most important part. It’s not a lot to change from your current code.

You may be right the new second level is eaiser than the first. I think I may take your suggestion and switch them around.
The key to the first level is not letting the left most guards get the gold at the left bottom of the screen if he does there is no way to trap him to get the gold back. The guards alway try to follow you so stay above them untill you can safely jump down and get the gold before them. Any other guard that gets some gold can be traped. For instance if a guard falls in the hole with the gold at the top. Just dig away the block at the side of the hole and make the guard follow you into the hole (it won’t look like a hole, but he will still get traped).

Good luck.

Thanks for the suggestion. Try the new version an see if you still think it needs tweeking. I have change the AI slightly. It is now like this.

If(player above) find nearest lader
if(player below find nearest lader or edge to jump off
if(player on same level) try to close X (even if it means falling off a lader or edge)

So now the guards don’t get stuck. But they may look silly jumping off a short ladder only to reclimb it and jump off again in and endless loop if the player does not move. But the new levels keep you moving so this is not so noticable. I will see if I can fit you suggestion in and see if it makes an improvement. What will add some code is that since in crazyMode the guard is no longer following the player. I will have to remember if they were going up or down a ladder and to continue in the same direction. Also when they finish climbing a ladder. What will stop them from finding the same lader as it will be the closest and just climbing back down. Now that I think of it, won’t your algorithm just make them climb up and down the same lader.

Well I tried the new 1st level and got beat up bad. One problem I noticed was in the empty square closest to the start with the gold bag. I fell in it, and none of the bots were smart enough to get up to me and chase me in, and I couldn’t figure out a way to restart. So I smacked all of the keys in hoping of finding a restart key, no luck.

:slight_smile:

Btw I figured out how to do the first level now. Actually I figured it out last night, just didn’t make a post. After trying a couple strategies and not being able to win, I finally realized you could dig a hole while climbing a ladder. Big help. :slight_smile:

[quote]Now that I think of it, won’t your algorithm just make them climb up and down the same lader.
[/quote]
True, my bad. It’s not as easy as that.

Here is the latest version of lode runner 4k. http://elmkom.tripod.com/cgi-bin/l.pl

I switched around some of the levels and inserted a new one to make the difficulty build up a little more gradually. So there are now 5 levels.

See if it seams more balanced now.

PS. If the title isn’t Lode Runner4k. Just hit the link again to get the fresh copy. Does any one know why you have to try twice to get webstart to realize the jar is out of date.

Just had to add that you’ve done a great job with this one! I’ve always liked Lode Runner though. :slight_smile:

Suggestion to add some sparkle: Make the background dark blue and have pixel stars scroll from right to left in the background (easily doable if you are using double buffering and are redrawing the entire screen on the backbuffer each time.). It was something I thought about adding to my Sokoban4k game but in the end I crammed in a couple of more levels instead.

I duno Donald, I think maybe you should cut maybe 4 or 5 levels and give us that extra sparkle :slight_smile: you’d be surprised how little things like that can increase the likeability (if that’s a word) :wink:

[quote]I duno Donald, I think maybe you should cut maybe 4 or 5 levels and give us that extra sparkle Smiley you’d be surprised how little things like that can increase the likeability (if that’s a word) Wink
[/quote]
Hm, you might be right. I guess no one will be disappointed if I decrease the number of levels from 95 to 85 anyway. :slight_smile:

[quote]Suggestion to add some sparkle: Make the background dark blue and have pixel stars scroll from right to left
[/quote]
Thanks for the suggestion. Here is a new version with blue sky and stars. http://elmkom.tripod.com/cgi-bin/l.pl
I had to drop a level to get it to fit. See what you think. How do you get so many levels in your game. It takes me about 100 bytes per level.

Wow! It looks really awesome if you ask me! The stars could go a little lower though so that we can see more of them, but it looks fine the way it is now as well. :slight_smile:

Regarding how I could fit that many levels in the game:

I rely on the lzw-compression to do a good job, for compression to have a high efficiency the data should be represented with a small amount of symbols and patterns should occur frequently (preferably close to each other). To represent the levels in my game I only need a couple of symbols. Normally the “standard” for storing Sokoban game levels looks like this:
`######

#@

$*

.*

######`
With the symbols meaning:

wall

empty square

  • A “box” on top of a box-goal square
    $ A “box” on top of a normal square
    @ the player

It’s easy to assume right now that a textfile with lots of levels next to eachother would compress fairly well. I wanted this to compress fairly well inside a class-file (which will be in a compressed Jar-file). First I introduced a new symbol, N, which means a new line. The map now looks like this:
`######N

#N

#@ #N

$* #N

.* #N

#N

######`

I now decided that I want to store all my levels in a single (very long) string, this will result in the characters lying next to eachother inside the classfile without any code in between them (thus the “preferably have patterns next to each other” will be fulfilled). At first this is how I store one level (the above one):
String level = “######N# #N# #@ #N# $* #N# .* #N# #N######”;

As I want to store all my levels in a large string until run-time I need to separate them. I decided that the sequence NN will be used to separate levels, as two new lines in a row never occurs and I don’t want to introduce a new symbol. This is how I store the first two levels.
String levels = “######N# #N# #@ #N# $* #N# .* #N# #N######NN####N# .#N# ###N#*@ #N# $ #N# ###N####”;

To handle the levels I decided to have them in an array, position 0 being the first level and so further. The actual line in my source code looks something like:
String[] levelArray = “######N# #N# #@ #N# $* #N# .* #N# #N######NN####N# .#N# ###N#*@ #N# $ #N# ###N####NNGG####N### ####N# $ #N# # #$ #N# . .#@ #N#########NN########N# #N# .**$@#N# #N##### #NGGGG####NNG#######NG# #NG# .$. #N## $@$ #N# .$. #N# #N########”.split(“NN”);

The only difference is that my line includes 95 levels and is several thousand characters long. My class file compresses very well, from over 10kb to <4kb. The complete source for my game is available last in my blog entry about the game: Click.

Thanks for the info on how you do your levels. I use almost the same method I have not been able to beat the LZW compression.
As my levels are all 26*16 I do not need the line or level separators. For example the first level looks like this


byte [] level=( 
     "   G                     H"+
     "H##X##H          G       H"+
     "H     H    HXXXXXXXXH G  H"+
     "H G E H    H        HXXX H"+
     "HX#X#XH    H        H    H"+
     "H     H----H-----  EH    H"+
     "H     H    H    HXXX#####H"+
     "H     H    H G  H        H"+
     "H   E H G  HXXXXH        H"+
     "#XXX#XX#XX#H        HXXHXX"+
     "#XXX#      H        H  H  "+
     "#G  #      H  ------H  H G"+
     "XXXXXXXXHXXX###     H XXXX"+
     "        H           H     "+
     "        H   P       H     "+
     "XXXXXXXXXXXXXXXXXXXXXXXXXX").getBytes();

By the way you can use the + oprerator to keep the levels readable without any size cost. The compiler puts the strings together for you.
I guess I just have too many images and game logic to get many levels in.

But how do you store many levels then? (You just showed one level.) I’m able to put all my levels into one big chunk, which will make it easier for the LZW compression as the patterns are all close to eachother.

Also, by looking at your example level as well as other levels. I think you will gain in compression efficiency if you store them row by row, instead of column by column as you do now. It seems like a Lode Runner maps has more patterns if it is stored in that direction. If you do it like that, your first lines on the map you showed would be:

byte [] level=(
	" HHHHHHHH###X  X"+
	" #  X    XXGX  X"+
	" # G#    XX X  X"+
	" X  X    XX X  X"+
	" # E#   E###X  X"+
	" #  X    X  X  X"+
	" HHHHHHHHX  X  X"+
	"     -   #  X  X"+
	"     -  GX  HHHX"+
	"     -   X  X  X"+
	"     -   #  X  X"+
	"  HHHHHHHHHHX  X"+
	"  X  -  X   # PX"+
	"  X  - GX   #  X"+
	"  X  -  X  -#  X"+
	..... and so on.... 

It’s worth trying out if you really want more levels in the game. How much space are you lowering your jar-fie size with if you exclude all levels?

Yes I just showed one level. I in fact do put all the levels together in one big string. If I exclued all the levels it saves about 400 bytes for 4 levels. So on average about 100 butes per level. Note uncompressed it is 416 bytes per level. I could try and switch the rows for columns as you suggest. But I am not sure It will make a difference.

It probably wouldn’t make that big a difference to switch rows into columns, it was more or less a “desperate” advice. :slight_smile: If you only have around 400 bytes for level data I doubt you can do anything magically to have that many levels, the compression won’t kick in until you have a larger chunk of level data with patterns which it could recognize.

As you know which symbols you are using (a limited set) and roughly how often they occur you could try using a Huffman encoding. As it is a symbol encoding scheme the main goal is to encode each symbol with as few bits as possible (as in morse code), you might know this already but now it’s said anyway. :slight_smile: If you tried that you might use a Huffman encoding scheme set like:
`
0
10
110
<#> 1110
<-> 11110
111110
1111110

11111110 11111111 `

And write the entire level down as a long binary string, with 11111111 terminating said string, you would end up with: (line breaks there for clarity, one line per line in your map (not the row->columns switched one.)
000111110000000000000000000000110 11011101110101110111011000000000001111100000000110 1100000011000001101010101010101010110011111000110 11001111100111111001100000110000000001101010100110 110101110101110101100000110000000001100000110 110000001101111011110111101111011011110111101111011110111100011111101100000110 110000001100000110000011010101011101110111011101110110 11000000110000011001111100011000000000110 110000111111001100111110001101010101011000000000110 1110101010111010101110101011101100000000011010101101010 11101010101110000000110000000001100011000 111011111000111000000011000111101111011110111101111011110110001100111110 101010101010101011010101011101110111000000110010101010 000000001100000000000011000000 0000000011000011111110000000011000000 101010101010101010101010101010101010101010101010101011111111
This gives us 800 bits under something pretty close to optimal symbol encoding (it would have been optimal if the encoding scheme would have been based on statistical data from your levels, which you could hard code as it will make for a higher compression in this case).

The above level could be stored in 80 bytes, but it will vary depending on the symbol frequency in each level. This data will get some additional compression from the LZW algorithm if it had a larger chunk of level data, but as you only have 400 bytes to play with I guess you are out of luck.

Anyway, it’s still a nice game! Even if it only has a few levels, I guess your best bet is to optimize your code instead of level data. If you succeed in that and get more space for your level data, then your level data will hopefully be compressed better as well.

Thanks for the suggestion. I had already tried the huffman encoding. But it did not do any better that with out it. I think you are right the place to look is not in the level data but in the images and code logic.

hi all,

lode runner 4k is great game, it is amazing what can you do with only 4k.

i have problem that i can’t complete first level. there is last gold piece behind wall and i can’t get it. what am i supposed to do to get the final piece and finish the level?

tahnkyou

If you want to dig down two layers, first dig out 2 floor tiles on layer 1, and 1 on layer 2…

In case you mised it in the post use the comma and period keys to dig.