You can move about by using the 'roguelike keyset' from angband. r rests,
and x exits. There are four different types of monsters, each with
different behaviour, and you move about a random dungeon. (Unfortunately
only one level deep with no exit.) The game uses ncurses for the io, and
is a total of 1976 bytes of C source code.
Here is the source code for those who don't value their sanity:
#include <stdlib.h>
#include <ncurses.h>
#define X 256
#define E struct en
#define V void
#define S(i) ((i)>0?1:(i)<0?-1:0)
#define R(i) ((rand()>>8)%i)
#define Z return(o->n);
#define F(i) V i(E*o)
#define G g[o->t]
#define C stdscr
#define W(i,j) (s=i,i=j,j=s)
#define I int
#define K(i) if(c==i)D=
#define Y (R(127)+64)
V nm(I,I);E*g[X*X];E{I s,t,h;char c;E*(*a)(E*);V (*i)(E*);E*n;}p,e,w;
I x=40,i2,j2,i,j,k,c,D,s;char *r,T[X],F[5]="MBjw";F(em){g[o->s=o->t]=o;}
F(wi){g[o->s]=o;}F(J){g[o->s]=&e;G->i(o);}E*dd(E*o){Z}E*mo(E*o)
{o->t=o->s+S((p.s&255)-(o->s&255))+S((p.s>>8)-(o->s>>8))*X;J(o);Z}
E*mm(E*o){o->t=o->s+R(3)-1+R(3)*X-X;J(o);Z}E*mb(E*o){if(!R(127))
nm(o->s+R(3)-1+R(3)*X-X,3);return(mm(o));}E*(*v[4])(E*o)={mo,mm,dd,mb};
E*pl(E*o){if(!R(31))nm(Y*X+Y,R(4));wclear(C);wmove(C,0,8);if(r)
waddstr(C,r);else{sprintf(T,"HP: %d XP %d",p.h,x-40);waddstr(C,T);}
for(j=D=0;j<16;j++){wmove(C,j+2,1);for(k=0;k<32;k++)waddch(C,g[p.s+(j-8)
*X+k-8]->c);}wrefresh(C);r=0;while(!(c=getch()));if(!R(9)&&++o->h>x/2)
o->h=x/2;if(c=='x'){endwin();exit(0);}K('h')-1;K('l')1;K('k')-X;K('j')X;
K('y')-1-X;K('u')1-X;K('b')X-1;K('n')1+X;o->t=o->s+D;J(o);Z}F(pi)
{if((o->a!=pl)&&((p.h-=2)<0))p.n=0;wi(o);}F(mi){if(o->a==pl){pi(G);
if((G->h-=5)<0){G->c=0;G->i=em;x++;em(o);r="You killed it!";}}wi(o);}
V nm(I s,I t){if (g[s]==&e){E*n=malloc(sizeof(E));*n=p;n->s=s;n->a=v[t];
n->h=40-(n->c=F[t])/4;n->i=mi;g[s]=p.n=n;}}V d(I a,I b,I l,I m)
{if(a>b)W(a,b);if(l>m)W(l,m);for(;l<=m;l++)for(c=a;c<=b;c++)g[l*X+c]=&e;
}I main(V){E*n,*o=&p;p.n=o;p.h=20;p.a=pl;p.i=pi;p.c=64;e.i=em;e.c=46;
w.i=wi;w.c=35;srand(time(0));initscr();wrefresh(C);cbreak();
intrflush(C,0);for(;i<X*X;i++)g[i]=&w;i=D=X/2;for(k=0;k<20;k++)
{I h=R(3)+3,w=R(7)+3;d(i-w,i+w,D-h,D+h);i2=Y;j2=Y;if(R(2)){d(i,i2,D,D);
d(i2,i2,D,j2);}else{d(i,i,D,j2);d(i,i2,j2,j2);}i=i2;D=j2;}g[p.s=32896]=o;
for(k<<2;k;k--)nm(Y*X+Y,R(4));while(n=o->a(o)){if(!n->c){o->n=n->n;
free(n);n=o->n;}o=n;}endwin();printf("You have died!");return(0);}
Steven
That is art!
That's just brilliant.
A.
[snip the insanity]
Wow. You should submit this for the next obfuscated C code contest.
That's a truly nice piece of code... you plan entering it in a
Obfuscated C contest? :-D
For those without GCC here's a more readable version -- not much help
huh? I managed to figure out most of it (the dungen is brilliant) but
didn't have the time nor inclination to comment it. Maybe the author has
a more readable version? :-)
void nm(int,int);
struct en*g[256*256];
struct en{
int s,t,h;
char c;
struct en*(*a)(struct en*);
void (*i)(struct en*);struct en*n;
} p,e,w;
int x=40,i2,j2,i,j,k,c,D,s;
char *r,T[256],F[5]="MBjw";
void em(struct en*o) {
g[o->s=o->t]=o;
}
void wi(struct en*o){
g[o->s]=o;
}
void J(struct en*o){
g[o->s]=&e;
g[o->t]->i(o);
}
struct en*dd(struct en*o){
return(o->n);
}
struct en*mo(struct en*o){
o->t=o->s+(((p.s&255)-(o->s&255))>0?1:((p.s&255)-(o->s&255))<0?-1:0)+(((p.s>>8)-(o->s>>8))>0?1:((p.s>>8)-(o->s>>8))<0?-1:0)*256;
J(o);
return(o->n);
}
struct en*mm(struct en*o){
o->t=o->s+((rand()>>8)%3)-1+((rand()>>8)%3)*256 -256;
J(o);
return(o->n);
}
struct en*mb(struct en*o){
if(!((rand()>>8)%127))nm(o->s+((rand()>>8)%3)-1+((rand()>>8)%3)*256
-256,3);
return(mm(o));
}
struct en*(*v[4])(struct en*o) = {mo,mm,dd,mb};
struct en*pl(struct en*o) {
if(!((rand()>>8)%31)) nm((((rand()>>8)%127)+64)*256
+(((rand()>>8)%127)+64),((rand()>>8)%4));
wclear(stdscr);
wmove(stdscr,0,8);
if (r)
waddnstr(stdscr,r,-1);
else {
sprintf(T,"HP: %d XP %d",p.h,x-40);
waddnstr(stdscr,T,-1);
}
for(j=D=0;j<16;j++) {
wmove(stdscr,j+2,1);
for(k=0;k<32;k++) waddch(stdscr,g[p.s+(j-8)*256 +k-8]->c);
}
wrefresh(stdscr);
r=0;
while(!(c=wgetch(stdscr)));
if(!((rand()>>8)%9)&&++o->h>x/2) o->h=x/2;
if(c=='x') {
endwin();
exit(0);
}
if(c=='h') D=-1;
if(c=='l') D=1;
if(c=='k') D=-256;
if(c=='j') D=256;
if(c=='y') D=-1-256;
if(c=='u') D=1-256;
if(c=='b') D=256 -1;
if(c=='n') D=1+256;o->t=o->s+D;
J(o);
return(o->n);
}
void pi(struct en*o) {
if((o->a!=pl)&&((p.h-=2)<0)) p.n=0;
wi(o);
}
void mi(struct en*o){
if(o->a==pl){
pi(g[o->t]);
if((g[o->t]->h-=5)<0){
g[o->t]->c=0;
g[o->t]->i=em;
x++;
em(o);
r="You killed it!";
}
}
wi(o);
}
void nm(int s,int t) {
if (g[s]==&e) {
struct en*n=malloc(sizeof(struct en));
*n=p;
n->s=s;
n->a=v[t];
n->h=40-(n->c=F[t])/4;
n->i=mi;
g[s]=p.n=n;
}
}
void d(int a,int b,int l,int m) {
if(a>b)(s=a,a=b,b=s);
if(l>m)(s=l,l=m,m=s);
for(;l<=m;l++)
for(c=a;c<=b;c++)g[l*256 +c]=&e;
}
int main(void){
struct en*n,*o=&p;p.n=o;p.h=20;p.a=pl;p.i=pi;p.c=64;e.i=em;e.c=46;
w.i=wi;
w.c=35;
srand(time(0));
initscr();
wrefresh(stdscr);
cbreak();
intrflush(stdscr,0);
for(;i<256*256;i++) g[i]=&w;i=D=256/2;
for(k=0;k<20;k++) {
int h=((rand()>>8)%3)+3,w=((rand()>>8)%7)+3;
d(i-w,i+w,D-h,D+h);
i2=(((rand()>>8)%127)+64);
j2=(((rand()>>8)%127)+64);
if(((rand()>>8)%2)){
d(i,i2,D,D);
d(i2,i2,D,j2);
} else {
d(i,i,D,j2);
d(i,i2,j2,j2);
}
i=i2;
D=j2;
}
g[p.s=32896]=o;
for(k<<2;k;k--) nm((((rand()>>8)%127)+64)*256
+(((rand()>>8)%127)+64),((rand()>>8)%4));
while(n=o->a(o)){
if(!n->c){
o->n=n->n;
free(n);
n=o->n;
}
o=n;
}
endwin();
printf("You have died!");
return(0);
}
--
At your service,
Kornel Kisielewicz (adminATchaosforge.org) [http://chaosforge.org]
"If hackers will ever use virtual reality, it would show a bunch
of text terminals floating around them..." -- The Sheep
> I decided to write a roguelike in two days... However, for an extra
> challenge, I decided to have the extra requirement that the source code
> must be less than 2KB in size. Here is the result.
>
> You can move about by using the 'roguelike keyset' from angband. r rests,
> and x exits. There are four different types of monsters, each with
> different behaviour, and you move about a random dungeon. (Unfortunately
> only one level deep with no exit.) The game uses ncurses for the io, and
> is a total of 1976 bytes of C source code.
Ok... for some reason I couldn't put this down. There now is a new version
with loads more monsters (9 in total). You gain hp, and faster
regeneration as you level up every 40xp. Beware, now the most difficult
monster is a summoner.
Of course all the extra features cost bytes... and now I'm just barely below
the 2KB limit at 2047 bytes. But anyway, here is the worlds smallest
roguelike, with even insaner coding techniques:
#include <stdlib.h>
#include <ncurses.h>
#define X 256
#define E struct E
#define V void
#define S(i) ((i)>0?1:(i)<0?-1:0)
#define R(i) ((rand()>>8)%i)
#define Z return o->n;
#define F(i) V i(E*o)
#define G g[o->t]
#define C stdscr
#define W(i,j) if(i>j)(s=i,i=j,j=s);
#define I int
#define K(i) if(c==i)D=
#define Y (R(127)+64)
#define u o->s
#define A u+S((p.s&255)-(u&255))+S((p.s>>8)-(u>>8))*X
#define H R(3)-1+R(3)*X-X
V q(I,I);E*g[X*X];E{char c;V(*i)(E*);E*(*a)(E*);E*n;I h,s,t;}p,e,w;I
x=40,y=40,N,M,i,j,k,c,D,s;char*r,F[40]="zcmwBMjHP:%d\tXP:%d\tLVL:%d",
T[X];F(f){g[u]=o;}F(em){g[u=o->t]=o;}F(J){g[u]=&e;G->i(o);}E*U(E*o){Z}
E*P(E*o){o->t=A;J(o);Z}E*O(E*o){o->t=u+H;J(o);Z}E*B(E*o){if(!R(X))
q(u+H,3);return O(o);}E*L(E*o){for(s=u;u!=p.s;u=A)if(g[u]==&w){u=s;
return P(o);}q(u+H,R(8));u=s;return U(o);}E*a(E*o){o->h++>y&&(o->h=y);
return P(o);}E*(*v[9])(E*)={P,O,U,B,O,P,U,a,L};E*pl(E*o){if(!R(31))
q(Y*X+Y,R(6)+x/y%5-1);wclear(C);wmove(C,0,8);if(r)waddstr(C,r);else{
sprintf(T,F+7,p.h,x-y,x/y);waddstr(C,T);}for(j=D=0;j<16;j++){wmove(C,
j+2,1);for(k=0;k<y;waddch(C,g[p.s+(j-8)*X-20+k++]->c));}wrefresh(C);
r=0;while(!(c=getch()));if(c=='x')p.n=0;if(!R(9)&&(o->h+=x/y)>x/2)o->h
=x/2;K('h')-1;K('l')1;K('k')-X;K('j')X;K('y')-1-X;K('u')1-X;K('b')X-1;
K('n')1+X;o->t=u+D;J(o);Z}F(pi){if(o->a!=pl&&((p.h-=2)<0))p.n=0;f(o);}
F(mi){if(o->a==pl){pi(G);if((G->h-=5)<0){G->c=0;G=&e;x++;em(o);
r="You killed it!";}}f(o);}V q(I s,I t){if(g[s]==&e){E*n=malloc(sizeof
*n);*n=(E){F[t],mi,v[t],p.n,y-F[t]/4,s};g[s]=p.n=n;}}V d(I a,I b,I l,I m
{W(a,b)W(l,m)for(;l<=m;l++)for(c=a;c<=b;g[l*X+c++]=&e);}I main(V)
{E*o=&p,*n;p=(E){64,pi,pl,o,20,32896};e=(E){46,em};w=(E){35,f};srand
(time(0));initscr();wrefresh(C);cbreak();intrflush(C,0);for(;i<X*X;
g[i++]=&w);i=D=X/2;for(;k<20;k++){I h=R(3)+3,w=R(7)+3;d(i-w,i+w,D-h,
D+h);N=Y;M=Y;if(R(2)){d(i,N,D,D);d(N,N,D,M);}else{d(i,i,D,M);
d(i,N,M,M);}i=N;D=M;}g[p.s]=o;for(k<<4;k;k--)q(Y*X+Y,R(5));while(
n=o->a(o)){if(!n->c){o->n=n->n;free(n);n=o->n;}o=n;}endwin();if(
p.h<=0)printf("You have died!\n");return 0;}
Steven
> Steven Fuerst napisa?(a):
>> I decided to write a roguelike in two days... However, for an extra
>> challenge, I decided to have the extra requirement that the source code
>> must be less than 2KB in size. Here is the result.
>>
>> You can move about by using the 'roguelike keyset' from angband. r
>> rests,
>> and x exits. There are four different types of monsters, each with
>> different behaviour, and you move about a random dungeon. (Unfortunately
>> only one level deep with no exit.) The game uses ncurses for the io, and
>> is a total of 1976 bytes of C source code.
>>
>> Here is the source code for those who don't value their sanity:
>
> That's a truly nice piece of code... you plan entering it in a
> Obfuscated C contest? :-D
Not yet... maybe I'll submit an improved version then the competition opens
this year.
>
> For those without GCC here's a more readable version -- not much help
> huh? I managed to figure out most of it (the dungen is brilliant) but
> didn't have the time nor inclination to comment it. Maybe the author has
> a more readable version? :-)
Sorry... would you believe that I actually edit the condensed version I
pasted here? It started out at about 4.5K of normal code... and was then
condensed while more features were added.
I'll try to add comments so people will understand what is going on:
Forward delcare for the new_monster() function.
> void nm(int,int);
The map. Locations are stored as x+y*256. This takes less bytes than a
multidimensional array to access in the source code.
> struct en*g[256*256];
The structure that holds all the information for the player, monsters and
walls in the dungeon. en is short for 'entity'.
> struct en{
s is the current location of the object.
t is the location it wants to move to.
h is its current hit points.
> int s,t,h;
c is the character that is displayed on the map.
> char c;
action function. This is what is called in the event loop in main() for
this object.
> struct en*(*a)(struct en*);
interaction function. If something wants to move into this square, this
function is called.
> void (*i)(struct en*);
This is a pointer to the next object in the event loop.
> struct en*n;
p is the player, e is an empty square, and w is a wall.
> } p,e,w;
lots of variables, used all over the place.
x is xp+40
> int x=40,i2,j2,i,j,k,c,D,s;
r is a message to display on the screen. T is a temp buffer for making the
HP/XP message. F is an array of the monster symbols.
> char *r,T[256],F[5]="MBjw";
This is the interaction function for an empty square. It takes a reference
to the object that wants to move into it, and updates the objects location
> void em(struct en*o) {
> g[o->s=o->t]=o;
> }
This is the interaction function for a wall. It restores an object to its
original location.
> void wi(struct en*o){
> g[o->s]=o;
> }
This is the "Interact" function. It makes the old location of an entity
empty, and then calls the interaction function of the place it wants to
move to.
> void J(struct en*o){
> g[o->s]=&e;
> g[o->t]->i(o);
> }
This is the action function for a monster that doesn't move - it just
returns the next object in the event loop.
> struct en*dd(struct en*o){
> return(o->n);
> }
This is the action function for the monster with the "smart" AI. It moves
towards you if it can. This is actually more understandable in macro form.
> struct en*mo(struct en*o){
>
> o->t=o->s+(((p.s&255)-(o->s&255))>0?1
((p.s&255)-(o->s&255))<0?-1:0)+(((p.s>>8)-(o->s>>8))>0?1
((p.s>>8)-(o->s>>8))<0?-1:0)*256;
> J(o);
> return(o->n);
> }
This is the action function for the monster that moves about randomly.
> struct en*mm(struct en*o){
> o->t=o->s+((rand()>>8)%3)-1+((rand()>>8)%3)*256 -256;
> J(o);
> return(o->n);
> }
This is the action function for the monster that breeds explosively. It
tries to generate a copy of itself next to itself some of the time, and
then calls the function to move about randomly.
> struct en*mb(struct en*o){
> if(!((rand()>>8)%127))nm(o->s+((rand()>>8)%3)-1+((rand()>>8)%3)*256
> -256,3);
> return(mm(o));
> }
Here is an array of all the monster action functions, so we can pick one.
> struct en*(*v[4])(struct en*o) = {mo,mm,dd,mb};
This is the player's action function.
> struct en*pl(struct en*o) {
First, occasionally try to generate a new monster somewhere on the map.
> if(!((rand()>>8)%31)) nm((((rand()>>8)%127)+64)*256
> +(((rand()>>8)%127)+64),((rand()>>8)%4));
init the screen.
> wclear(stdscr);
> wmove(stdscr,0,8);
Draw the message on the top / hp bar.
> if (r)
> waddnstr(stdscr,r,-1);
> else {
> sprintf(T,"HP: %d XP %d",p.h,x-40);
> waddnstr(stdscr,T,-1);
> }
Draw the map.
> for(j=D=0;j<16;j++) {
> wmove(stdscr,j+2,1);
> for(k=0;k<32;k++) waddch(stdscr,g[p.s+(j-8)*256 +k-8]->c);
> }
> wrefresh(stdscr);
Get a keypress
> r=0;
> while(!(c=wgetch(stdscr)));
regenerate hp from time to time.
> if(!((rand()>>8)%9)&&++o->h>x/2) o->h=x/2;
Does the player want to exit the game?
> if(c=='x') {
> endwin();
> exit(0);
> }
Move about by setting the offset to the current location.
> if(c=='h') D=-1;
> if(c=='l') D=1;
> if(c=='k') D=-256;
> if(c=='j') D=256;
> if(c=='y') D=-1-256;
> if(c=='u') D=1-256;
> if(c=='b') D=256 -1;
> if(c=='n') D=1+256;
Set the next location.
> o->t=o->s+D;
Try to move/attack there.
> J(o);
> return(o->n);
> }
This is the player interaction function... called when a monster tries to
move on top of the player, or if the player does nothing this turn.
> void pi(struct en*o) {
Basically, this does damage to the player... if dead, the even loop is
broken.
> if((o->a!=pl)&&((p.h-=2)<0)) p.n=0;
The player still lives, so don't move here.
> wi(o);
> }
This is the monster interaction function... called when the player or
another monster tries to move on top of a monster.
> void mi(struct en*o){
> if(o->a==pl){
Damage the player, so immobile monsters fight back.
> pi(g[o->t]);
Damage the monster.
> if((g[o->t]->h-=5)<0){
If dead, set a flag so we can remove it from the event loop in main()
> g[o->t]->c=0;
Clear the grid
> g[o->t]->i=em;
Gain xp
> x++;
Allow us to move onto the square.
> em(o);
> r="You killed it!";
> }
> }
Stop movement.
> wi(o);
> }
Function that tries to make a new monster.
> void nm(int s,int t) {
Only if the square is empty
> if (g[s]==&e) {
> struct en*n=malloc(sizeof(struct en));
This line is really n->n = p.n, but shorter.
> *n=p;
Fill in the rest of the data for the monster.
> n->s=s;
> n->a=v[t];
> n->h=40-(n->c=F[t])/4;
> n->i=mi;
Insert it into the map and event loop.
> g[s]=p.n=n;
> }
> }
Draw an empty region in the dungeon.
> void d(int a,int b,int l,int m) {
> if(a>b)(s=a,a=b,b=s);
> if(l>m)(s=l,l=m,m=s);
> for(;l<=m;l++)
> for(c=a;c<=b;c++)g[l*256 +c]=&e;
> }
>
> int main(void){
> struct en*n,*o=&p;
Set up the player starting information.
> p.n=o;p.h=20;p.a=pl;p.i=pi;p.c=64;
Empty square information
> e.i=em;e.c=46;
Wall information
> w.i=wi;w.c=35;
Set up ncurses
> srand(time(0));
> initscr();
> wrefresh(stdscr);
> cbreak();
> intrflush(stdscr,0);
Fill the dungeon with walls.
> for(;i<256*256;i++) g[i]=&w;
Force a room to be in the middle of the dungeon.
> i=D=256/2;
Draw rooms, and connect them with tunnels. The rooms (deliberately)
overlap. This makes a moderately interesting dungeon.
> for(k=0;k<20;k++) {
> int h=((rand()>>8)%3)+3,w=((rand()>>8)%7)+3;
> d(i-w,i+w,D-h,D+h);
> i2=(((rand()>>8)%127)+64);
> j2=(((rand()>>8)%127)+64);
The tunnels can be generated in two different ways. This often leads to
rooms connected to many others, but can lead to dead-end rooms just often
enough not to be annoying.
> if(((rand()>>8)%2)){
> d(i,i2,D,D);
> d(i2,i2,D,j2);
> } else {
> d(i,i,D,j2);
> d(i,i2,j2,j2);
> }
> i=i2;
> D=j2;
> }
Set the player location to be in the middle of the guaranteed room centered
at 128,128
> g[p.s=32896]=o;
Make some monsters in the dungeon.
> for(k<<2;k;k--) nm((((rand()>>8)%127)+64)*256
> +(((rand()>>8)%127)+64),((rand()>>8)%4));
The main event loop. This controls everything. It calls the action
functions one after another for all the entities in the circular linked
list.
> while(n=o->a(o)){
Since it is a singularly linked list, we can only (quickly) delete things in
it when we have a pointer to two adjacent objects... which is why the
monster deletion is done here.
> if(!n->c){
> o->n=n->n;
> free(n);
> n=o->n;
> }
> o=n;
> }
Exit upon player death.
> endwin();
> printf("You have died!\n");
> return(0);
> }
Done!
The new version is somewhat more complicated, with more monster action
functions... but the core logic is the same.
Steven.
Alas this version does not compile for me. Line 35 ( which starts with
{W(a,b)W(l,m)for(;l<=m;l++) ) has some syntax errors.
Keep up the good work.
Shawn M Moore
You are right... Looks like the lines are slightly too long, and some things
got truncated. This version has 69 character lines, and is exactly 2048
bytes. (I was using a trick where a space at the end of the line isn't
needed in the other version.)
o->h=x/2;K('h')-1;K('l')1;K('k')-X;K('j')X;K('y')-1-X;K('u')1-X;
K('b')X-1;K('n')1+X;o->t=u+D;J(o);Z}F(pi){if(o->a!=pl&&((p.h-=2)<0))
p.n=0;f(o);}F(mi){if(o->a==pl){pi(G);if((G->h-=5)<0){G->c=0;G=&e;x++;
em(o);r="You killed it!";}}f(o);}V q(I s,I t){if(g[s]==&e){E*n=
malloc(sizeof*n);*n=(E){F[t],mi,v[t],p.n,y-F[t]/4,s};g[s]=p.n=n;}}
V d(I a,I b,I l,I m){W(a,b)W(l,m)for(;l<=m;l++)for(c=a;c<=b;g[l*X+
c++]=&e);}I main(V){E*o=&p,*n;p=(E){64,pi,pl,o,20,32896};e=(E)
{46,em};w=(E){35,f};srand(time(0));initscr();wrefresh(C);cbreak();
intrflush(C,0);for(;i<X*X;g[i++]=&w);i=D=X/2;for(;k<20;k++){I h=R(3)
+3,w=R(7)+3;d(i-w,i+w,D-h,D+h);N=Y;M=Y;if(R(2)){d(i,N,D,D);d(N,N,D,M)
;}else{d(i,i,D,M);d(i,N,M,M);}i=N;D=M;}g[p.s]=o;for(k<<4;k;k--)q(Y*X+
Y,R(5));while(n=o->a(o)){if(!n->c){o->n=n->n;free(n);n=o->n;}o=n;}
endwin();if(p.h<=0)printf("You have died!\n");return 0;}
Steven
<SNIPs Code with +2 Gnu Debugging Axe>
You know what you could do... (just an idea...)
Raise your size limit to maybe 5KB and see what the smallest size for some
procedural generation of Monsters is...
Like I said though... it may be a wee bit suicidal
--
lochok
-----
L:FP E+ T+ R- P++ D- G+ F:ADoM RL--- RLA-
W:M Q- AI+ GFX- SFX+++ RN+ PO--- Hp++ Re+ S+
-----
> I decided to write a roguelike in two days... However, for an extra
> challenge, I decided to have the extra requirement that the source code
> must be less than 2KB in size. Here is the result.
>
> You can move about by using the 'roguelike keyset' from angband. r rests,
> and x exits. There are four different types of monsters, each with
> different behaviour, and you move about a random dungeon. (Unfortunately
> only one level deep with no exit.) The game uses ncurses for the io, and
> is a total of 1976 bytes of C source code.
>
> Here is the source code for those who don't value their sanity:
I don't understand C. I understood little. Maybe that's for the better!
:D
Any way, as I don't understand C, I don't know how to compile that. I
got to the point where I was told that I don't have ncurses.h. Any hints
for where to get that?
Janne )'( Joensuu,
Endoperez
<snip>
You can save 1 byte by including curses.h instead of ncurses.h. That way
it'll be easier to make it work with PDCurses for example ;)
I have compiled your game to Windows executable with keyboard control
changed to numpad (num-lock turned on). Source code is also attached in
the archive.
www.alamak0ta.republika.pl/2DRL.zip
regards,
Jakub
--
"We're just toys in the hands of Xom"
www.graveyard.uni.cc - visit Roguelike Graveyard
www.alamak0ta.republika.pl - my other projects
<snip>
>> #include <stdlib.h>
>> #include <ncurses.h>
>
> <snip>
>
> You can save 1 byte by including curses.h instead of ncurses.h. That way
> it'll be easier to make it work with PDCurses for example ;)
You can save a few more by replacing "F[40]=" with "*F=" on the second line
after the #defines. :-P
Steven
<snip>
> Any way, as I don't understand C, I don't know how to compile that. I
> got to the point where I was told that I don't have ncurses.h. Any hints
> for where to get that?
>
> Janne )'( Joensuu,
> Endoperez
If you have linux, install the libncurses5-dev package, and you'll have
everything you need, provided you have gcc set up properly.
compile with: gcc game.c -o game -lncurses
(Obviously replace game.c with whatever you decide to call the source file.)
If you have a Mac, or Windows, you'll have to investigate getting (n)curses
from the web. Note that the code doesn't actually use any of the extra
features in ncurses, and standard curses will do just fine.
Steven
--
news.
I got to try it using the exe Jakub Debski compiled, below. Thanks for
him, I just hope I spelled his name right...
Interesting, very minimal game. Not that fun to play, but I don't think
that was the actual goal, either. I have seen nothing like that before,
and don't really know how I should react. It's cool, but somehow I doubt
I'll be able to do anything even close to that in many, many years... or
after many, many years of practical studying. Many, many years of actual
coding might do it, though. :P
If you enjoyed reading the 2DRL-2K code, check out the International
Obfuscated C code Competition website www.ioccc.org - all programmers
should see this at some stage.
A.
That's impressive! I keep getting killed by the 'w's...
--
Chris