A Roguelike in less than 512 BytesRogue was one of the first graphical computer games. It involved a player searching a dungeon for treasure, whilst avoiding or defeating monsters. It used ascii characters for graphics in lieu of images due to the primitive nature of the hardware available at the time. The game eventually spawned copy-cat games, the most famous of which are Angband and Nethack. This category of dungeon-exploration game is called a "roguelike" Roguelike games still have a large following today, and the development of which are often an open-ended project for an author to explore the usage of a newly learnt computer language. Back in 2006, there was a competition to develop such games with the limitiation that only seven days could be used. The seven-day-roguelike (7DRL) competition was a success, and produced many entries. Soon after the competition was completed, I decided to undertake creating such a game in two days instead of seven, with the further limitation that the source code must fit in under 2KiB. At the time, this 2KiB roguelike was the smallest game of its type ever created. Over the past few years, others have attempted the creation of minature roguelike games, and there now are several 1kiB games in existance. Twice as small as the original smallest roguelike, these pushed forward the boundary of coding within a small number of bytes. Now, in order push forward even further into the rediculous, I have set myself the task of creating a roguelike within half a KiB (512 bytes) of source code. The resulting game follows:
This weighs in at a hefty 493 bytes of C source code. I call it the "Monster Caves". Decend downwards, and kill as many monsters as you can. Beware! Hitting an already dead monster causes it to arise as a nearly unkillable Lich! How many monsters can you kill before your luck runs out, or you find the mysterious moving stairwell? Note that the game doesn't have enough bytes to remember (and print out) your kill total, so you'll have to do that yourself. You can use the numeric keypad (with num-lock on) to move about. Move into a monster to attack it, and move into a stairway to decend another level. If you get stuck in a disconnected part of a level, try pressing some other keys... you may just be able to teleport out. To compile the source code use So the above source is extremely hard to read and understand, so how does it work? The first trick is to use the C pre-processor to replace the #defines with their macro-expanded result. This (together with the addition of the removed header) yields
Unfortunately, this is less than enlightening, so some pretty-printing is in order. Adding in extra white-space together with more braces yields
Now the main structure of the code can be seen. The first part initializes the map. This is followed by a loop which initilizes the monsters. The stairway is created, and then the main loop is entered. This prints the screen if it is the player's go, and handles monster and player movement. Finally, if the player hits a stairway, Note how boolean logic and short-circuit evaulation has been used instead of explicit if statements in many places. The resulting code is much shorter if done this way. Of particular note is that the xor operation (^) being used as a != operator. Another silly trick that doesn't actually reduce code size, but definitely makes things harder to read is the use of Another trick used is the insertion of the assignement of one variable within the expression for the assignment of another. i.e.
More things to note are that the player command input is handled by a complex expression that just happens to use the fact that 46 (ascii for the floor character symbol '.') is the same as 49 mod 3, which is the ascii for '1', at the start of the numeric keypad. These ascii values are also used to define C99 dynamic arrays to hold the map and monster lists. The fact that 77, the ascii value of 'M' is close to 80, the width of the screen, is conveniently used. Expanding the boolean logic expressions into more standard Unfortunately, the game didn't quite get small enough that the extra feature of a kill counter could be added. Its tiny size also prevented some error checking that would be in a larger version. A player might press a non-numeric key causing the character to "teleport" across the map. Similarly, the lack of error checking causes strange things to happen when two monsters or a monster and the staircase are generated on top of each other. The moving staircase feature is actually this bug. By redefining these bugs into features they are fixed via lampshading. Finally, here is the source code before any compression at all. Notice how the dungeon generation and monster placement algorithms were changed, and how the coordinate system was changed to be an absolute offset from the start of the map, rather than a x,y tuple.
|
About Us | Returns Policy | Privacy Policy | Send us Feedback |
Company Info |
Product Index |
Category Index |
Help |
Terms of Use
Copyright © Lockless Inc All Rights Reserved. |
Comments
Mingos said...BTW, the captcha on the comments is for superhuman captcha readers... 4 tries so far...
j[m] = 35;
j being an int and m an array of char, shouldn't that be m[j] ?!
Does the second version of the code really compile ?
So what does j[m] represents ?? the same as m[j] ?
i ported to python with libtcod (jice and mingos roguelike API)
https://sites.google.com/site/comoelroguesite/MonsterCaves.zip?attredirects=0&d=1
i think the (v1 - v2) must be (v2 - v1) to work properly in the rr function