This challenge is based on one proposed on the usenet group rec.games.roguelike.development a few years ago. I can't find the original newsgroup post, but you can have a look a the Github repo of solutions. It was only golfed in a couple of languages and I'd love to see some more!


The aim is to build a program that presents a top-down view of a dungeon using ascii characters. There will be an @ sign representing the player that can be moved through the free space in the dungeon (represented by ), though it cannot pass through the walls (represented by #).

The map of the dungeon must look like this:

####  ####
#  #  #  #
#  ####  #
#        #
##      ##
 #      #
 #      #
##      ##
#        #
#  ####  #
#  #  #  #
####  ####

The player must begin at location {2,2}, where {0,0} is the top left-hand corner.


The user needs to be able to move the player in the four cardinal directions using the arrow keys on the keyboard.

There needs to be some way for the user to exit the program. It does not need to be a graceful exit (for example, it doesn't matter if an exception is printed).

The map and player need to be drawn before any input has been taken, and the player needs to be updated after each input.


Feel free to use established libraries for console input or output, such as Curses. Just mention in your answer what you are using.


This is code golf, shortest code wins!

  • \$\begingroup\$ Pretty close to a duplicate of Build an engine for a maze game which could certainly use some additional entries. Thoughts? \$\endgroup\$ Commented Aug 24, 2012 at 2:46
  • \$\begingroup\$ @dmckee It's definitely pretty similar. I hope the simpler input mechanism and the challenge of efficiently hardcoding the preset map will make it different enough. \$\endgroup\$ Commented Aug 24, 2012 at 2:51
  • \$\begingroup\$ I'll certainly buy the hardcoded map bit. Now just let me just think on how I might adapt my previous solution... \$\endgroup\$ Commented Aug 24, 2012 at 2:52
  • 2
    \$\begingroup\$ I just can't help but mention the game that introduced me to C: nethack.org \$\endgroup\$
    – SeanC
    Commented Aug 24, 2012 at 4:53

4 Answers 4


C, 257 253 222 220

Uses system("cls") instead of curses (use system("clear") for Linux systems) and a clever algorithm to fit the map into an 8-digit number. Non-extended keys end the program, e.g. escape.

EDIT: Now also shows your hero below the map by using a<230 instead of a<132:

 ###  ###
 # #  # #
## #  # ##
  #    #
 ##    ##


a,p=14,w=11,X,Y;m(I){X=I%w-1,Y=I/w;return 70313263>>(Y>5?w-Y:Y)*5+(X>4?9-X:X)&1;}main(){do{system("cls");a=a&4?1:a&2?-1:a&8?-w:w;p+=!m(p+a)*a;for(a=0;++a<230;)putch(a%w?a-p?m(a)*35:64:10);}while(a=getch()>>7?getch():0);}
  • \$\begingroup\$ This doesn't compile for me. \$\endgroup\$
    – Matt
    Commented Aug 24, 2012 at 14:11
  • \$\begingroup\$ Compiles and works for me using Visual Studio 2008. \$\endgroup\$ Commented Aug 24, 2012 at 15:20
  • \$\begingroup\$ @Matt: Hm.. I successfully tried both MinGW (gcc 4.6.1) and MSVC (VS 2009) under Windows so far. What's the error message? \$\endgroup\$
    – schnaader
    Commented Aug 24, 2012 at 16:19
  • \$\begingroup\$ @schnaader in gcc 4.4.5 I get: test.c:(.text+0x1a1): undefined reference to `putch'. I get the same error for getch \$\endgroup\$
    – Matt
    Commented Aug 24, 2012 at 17:03
  • \$\begingroup\$ For putch, there's putchar which does the same, but I don't know how to replace getch - there's a getchar too, but it doesn't work for me - seems it doesn't recognize the cursor keys. \$\endgroup\$
    – schnaader
    Commented Aug 24, 2012 at 17:42

Ruby 1.9 + Curses (248)

require'curses';include Curses;noecho;curs_set 0
b=0xf3e499e601c0d0240b0380679927cf.to_s(2).tr'01',' #'
s=init_screen<<b.scan(/.{10}/)*$/;s.keypad 1
p=22;d=->t=?@{setpos p/10,p%10;addch t;6};d[]
  • 1
    \$\begingroup\$ That uses a map different from the specified one. I recommend using 0xf3e499e601c0d0240b0380679927cf instead. \$\endgroup\$
    – Matt
    Commented Aug 24, 2012 at 4:00

Python 332 319 317

from curses import*
M=0xf3e499e601c0d0240b0380679927cf;S=initscr();S.keypad(1);x,y=2,2;A=S.addstr;[A(a,b,[' ','#'][M>>(10*a+b)&1])for a in range(12)for b in range(10)]
while 1:A(y,x,'@');k=S.getch();A(y,x,' ');X=[[x,x-1],[x+1,1]][k==261][k==260];Y=[[y,y-1],[y+1,y+1]][k==258][k==259];x,y=[(X,Y),(x,y)][M>>(10*Y+X)&1]

The python curses library is only officially supported on linux. There are unofficial ones available for windows, but I can't guarantee that this will work with it.

To save a few characters I hard coded the keycodes for up, down, left, and right. This may cause problems for some people. If this doesn't work for anyone I can post a version that should.

Use ctrl+c to exit. You will probably have to reset your terminal after exiting, but the challenge specifically said the exit didn't have to be graceful.


QBasic, 314 313 bytes

This sort of problem simply begs for a QBasic solution.

DIM w(12,10)
FOR r=1TO 12
FOR c=1TO 10
w(r,c)=(d*2AND 2^c)>0
IF""=a$GOTO 9
?" "
IF w(x,y)THEN i=x:j=y
IF k>9GOTO 1
DATA 48,438,390,510,252,765,765,252,510,390,438,48

This is golfed QBasic, which will be expanded significantly by the autoformatter. But, if you type this exact code into the IDE and hit F5, it should run. Tested on QB64.



The map is encoded row-wise as the bits of the integers in the DATA statement (1 for space, 0 for wall). The nested FOR loop unpacks them, storing truth values in the 2D array w, and printing # or accordingly. (Note that true in QBasic is -1, thus why we're adding to 35 instead of subtracting!) The player starts at 3,3 because most things are 1-indexed in QBasic.

We then enter a GOTO loop: print the @, get keyboard input, convert to extended character code, and modify x and y based on whether the user pressed L/U/R/D. If w(x,y) is true, then it's a space and we can move there; otherwise, stay put. Finally, the shortest way I found to exit is by pressing the tab key (ASCII 9). Any other input loops us back up to the first LOCATE statement.

I must say, I'm rather tickled to have beaten Python with a QBasic answer.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.