a discussion we've had at the #rgrd irc channel leads me to announce
the very first "<1kb RL challenge"!
My 967 bytes entry follows (can also be found on http://pastie.org/248821).
It is python code, if you are on windows you will need to install a
windows curses module for Python, e.g. http://adamv.com/dev/python/curses/
----
from curses import *
from random import *
s=initscr()
r=range
m=[40*[' '] for l in r(20)]
d=enumerate
def f(g):
for y in r(20):
for x in r(40):
g(y,x)
def n(y,x):
if random()<0.1:
m[y][x]='#'
f(n)
x,y,c,h=0,0,0,5
o,t,n=ord,s.addstr,randint
w=[[n(0,19),n(0,39),1] for e in r(10)]
def u(y,x):
for i,e in d(w):
if y==e[0] and x==e[1]:
return i
return -1
def v(y,x):
if u(y,x)>0:
w[u(y,x)][2]-=1
return m[y][x]==' '
while(c!=o('q')):
t(0,41,"h: "+str(h))
for j,e in d(w):
m[e[0]][e[1]]=' '
if e[2]<1:
continue
z,q=max(min(w[j][0]+n(-1,1),19),0),max(min(w[j][1]+n(-1,1),39),0)
if(z==y and q==x):
h=h-1
if(m[z][q]==' '):
w[j][0],w[j][1]=z,q
m[e[0]][e[1]]='e'
m[y][x]='@'
f(lambda y,x:t(y,x,m[y][x]))
c=s.getch()
m[y][x]=' '
if o('2')==c and y<19:
if v(y+1,x):
y+=1
if o('8')==c and y>0:
if v(y-1,x):
y-=1
if o('6')==c and x<39:
if v(y,x+1):
x+=1
if o('4')==c and x>0:
if v(y,x-1):
x-=1
if h<1:
break
This severely pushes the definition...not only of 'roguelike', but of
'game'. I like it. :)
Cool, interesting!
We must decide on a final date?
I am in!
SNIP
--
Slashie
http://www.santiagoz.com/blog
http://roguetemple.com
http://slashie.net
This entry doesnt seem to have monsters, what does it need to
implement in order to qualify ?
T.
I might improve this entry later.
To compile this, get MinGW (http://mingw.org/), and run the command
"gcc -o rl rl.c". Use the numpad with numlock on.
and how big is python? can my roguelike just be a dll? with a 1kb
batch file?
is it 1kb of source or 1kb of binary?
-stu
My suggestion is this: we can use any language. We make a separate
file with the I/O functions we want to use. This would not be counted
as part of the source code for scoring purposes.
For scoring, we could have a poll in which we vote for our favorite
roguelikes. After the voting is complete, we divide each roguelike's
votes by its source code size, in bytes. This makes smaller roguelikes
score better. For example, a 10,000-byte roguelike with 100 votes gets
a score of .01, and a 1000-byte roguelike with 50 votes gets a score
of .05.
This is a nice idea but it's going off on a complete tangeant from the
original intent.
I think it should just be what has already been set as a precedent by the
entries so far, which is:
Language and libraries:
Any language, only the language's standard libraries and optionally
curses can be used
Size:
Either the source OR the binary is less than 1kb (1024 bytes)
C# <1kRl
Game "world" (haha) generated on the fly, infinite size (within the limits
of your computer's memory)
Tested under .NET in Windows and Mono in Linux
Press any key except escape to start, arrow keys to move, escape to exit
943 bytes, C#
http://nrkn.com/1kRl/Program.cs
Binary, 6144 byes:
http://nrkn.com/1kRl/1kRl.exe
Code:
using System;using System.Collections.Generic;namespace _1kRl{class Program{
class M{Dictionary<string,char>d=new Dictionary<string,char>();int
p=9,x,y,u,
v;char a='@',w='#',f='.';Random r=new Random();public
M(){x=p;y=p;d[S(x,y)]=a;
ConsoleKey k =
K();while(k!=ConsoleKey.Escape){Console.Clear();u=x;v=y;switch
(k){case ConsoleKey.LeftArrow:x--;break;case
ConsoleKey.RightArrow:x++;break;
case ConsoleKey.UpArrow:y--;break;case
ConsoleKey.DownArrow:y++;break;}if(C(S(
x,y))==w){x=u;y=v;}d[S(u,v)]=f;d[S(x,y)]=a;for(int j=0;j<p*2-1;j++){for(int
i=0;i<p*2-1;i++){Console.Write(C(S(i-p+x,j-p+y)));}Console.WriteLine();}k=K();
}}string S(int x,int y){return String.Format("{0}_{1}",x,y);}int L(String s,
int l){return Convert.ToInt32((s.Split('_'))[l]);}char C(String s){if(
d.ContainsKey(s))return d[s];return d[s]=r.Next(9)<8?f:w;}ConsoleKey K(){
return(Console.ReadKey(true)).Key;}}static void Main(string[]args){M m=new
M();}}}
Collect all the e's (energons) within the lowest amount of turns.
There will always be 10 energons, randomly placed. It wont crash if
you attempt to walk off the edge, and the win condition is collection
of all the energons.
e: Number of energons left
t: Number of turns used so far
Its written in Java and there are 2 versions since the rules seem a
little unclear at this point: Version one uses only input/output
streams: unfortunately Java sucks with input, so you have to press
'enter' after one or more directional keys. Its sad I know. Version 2
has a keyboard class I quicky whipped up that can sit in a seperate
file. It creates a small JFrame that listens to input as long as it
has window focus, but this version still outputs with the standard
output stream to console... Its 1000x easier to use since you dont
have to hit 'enter' all the time, so I recommend people do.
Version 1: 991 bytes
Version 2: 984 bytes
class M{
static char m[][]=new char[10][10];
static int k,X=5,Y=5,x,y,a,b,s,t,e=10;
public static void main(String[] A)throws Exception{
for(;y<10;y++)
for(x=0;x<10;x++){
if(m[x][y]!='e'){
m[x][y]='.';
if(Math.random()<.1&&e>0&&(x!=5&&y!=5)){m[x][y]='e'; e--;}
}
if(x==9&&y==9&&e>0)x=y=0;
}
m[X][Y]='@';
while(true){
e=0;
for(y=0;y<m[0].length;y++){
for(x=0;x<m.length;x++){
System.out.print(m[x][y]);
if(m[x][y]=='e')e++;
}
System.out.println();
}
if(e!=0)System.out.println("t:"+t+" e:"+e+"\n");
else System.out.println("U Win! t:"+t+"\n");
k=System.in.read();
if(e==0)System.exit(0);
m[X][Y]='.';
if(k==50&&Y!=9){Y++;if(e!=0)t++;}
if(k==52&&X!=0){X--;if(e!=0)t++;}
if(k==54&&X!=9){X++;if(e!=0)t++;}
if(k==56&&Y!=0){Y--;if(e!=0)t++;}
m[X][Y]='@';
}
}
}
For version 2, replace the line which reads k=System.in.read(); with
k=F.g(); and use this code in a seperate file:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class F{
public static JFrame frame;
public static Keyboard vKeyboard;
public static int g(){
if(frame == null){
frame = new JFrame();
frame.setSize(10, 10);
vKeyboard = new Keyboard();
frame.addKeyListener(vKeyboard);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
int key = -1;
while(key == -1){
frame.requestFocus();
try{ Thread.sleep(50); }
catch(Exception e){ System.out.println(e); }
key = vKeyboard.key;
vKeyboard.key = -1;
}
return key;
}
}
class Keyboard implements KeyListener{
public int key;
public Keyboard(){
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyPressed(KeyEvent e)
{
key = e.getKeyChar();
}
}
-Numeron
In this form its only 721 bytes :D
class M{static char m[][]=new char[10][10];static int
k,X=5,Y=5,x,y,a,b,s,t,e=10;public static void main(String[] A)throws
Exception{for(;y<10;y++)for(x=0;x<10;x++){if(m[x][y]!='e'){m[x]
[y]='.';if(Math.random()<.1&&e>0&&!(x==5&&y==5)){m[x]
[y]='e';e--;}}if(x==9&&y==9&&e>0)x=y=0;}m[X][Y]='@';while(true)
{e=0;for(y=0;y<m[0].length;y++){for(x=0;x<m.length;x++)
{System.out.print(m[x][y]);if(m[x][y]=='e')e+
+;}System.out.println();}if(e!=0)System.out.println("t:"+t+" e:"+e
+"\n");else System.out.println("U Win! t:"+t
+"\n");k=System.in.read();if(e==0)System.exit(0);m[X]
[Y]='.';if(k==50&&Y!=9){Y++;if(e!=0)t++;}if(k==52&&X!=0){X--;if(e!=0)t+
+;}if(k==54&&X!=9){X++;if(e!=0)t++;}if(k==56&&Y!=0){Y--;if(e!=0)t+
+;}m[X][Y]='@';}}}
If you can find it in there, replace the line which reads
k=System.in.read(); with k=F.g(); to use it with my Keyboard related
classes above.
-Numeron
It does have monsters, they are the e's that move around randomly and
reduce your hp if they hit you.
Whatever you wish, although the original idea was 1kb of source.
C# <1kB RogueLike v2
992 bytes, now with a win condition:
http://nrkn.com/1kRl/v2/
http://nrkn.com/1kRl/v2/Program.cs
http://nrkn.com/1kRl/v2/1kRl.exe
Code (slightly bigger than 992 bytes due to carriage returns added for
convenience when reading from Usenet):
using System;using System.Collections.Generic;namespace _1kRl{class Program{
class M{Dictionary<string,char>d=new Dictionary<string,char>();int p=9,x,y,
u,v,z;char a='@',w='#',f='.',q='$',c;Random r=new Random();public M(){x=y=p;
d[S(x,y)]=a;ConsoleKey k=K();while(k!=ConsoleKey.Escape){Console.Clear();
u=x;v=y;switch(k){case ConsoleKey.LeftArrow:x--;break;case
ConsoleKey.RightArrow:x++;break;case ConsoleKey.UpArrow:y--;break;case
ConsoleKey.DownArrow:y++;break;}c=C(S(x,y));if(c==w){x=u;y=v;}if(c==q){
Console.WriteLine("Win");K();return;}d[S(u,v)]=f;d[S(x,y)]=a;z=p*2-1;for(int
j=0;j<z;j++){for(int i=0;i<z;i++){Console.Write(C(S(i-p+x,j-p+y)));}
Console.WriteLine();}k=K();}}string S(int x,int y){return String.Format(
"{0}_{1}",x,y);}int L(String s,int l){return Convert.ToInt32((s.Split('_'))
[l]);}char C(String s){if(d.ContainsKey(s))return d[s];return d[s]=r.Next(
9999)==9?q:r.Next(9)<8?f:w;}ConsoleKey K(){return(Console.ReadKey(true)
There was a whole method in there that wasn't being called. Duh.
927 bytes
Bugger this, I'm starting a new thread :)
Here is it! http://deveah.googlepages.com/1024biED.exe
Sorry for triple posting, but that H8L1E4 code is: H = health points;
L = the level you're on; E = enemies around you
I hope it's enough
FYI, 967 is with using tabs, i think google groups replaced them with
spaces.
-Ido.
I thought 7DRL was bad enough, but in theory a 7DRL could
become a real roguelike. This 1kb is just a waste of time.
Then don't join the challenge.
Unless you like programming because it's fun
My bad!
Still, the contest should define what the minimum content is for the
entry.
T.
I'm fine with "if you think it's enough it is". It isn't a contest,
it's just a bit of fun. Enjoy the ride and don't worry too much about
the rules.
-Ido.
Just this - the size of the source code must be exactly or under 1024
bytes (1 kb)
What is the minimum content for a roguelike?
I think a '@'. So this is my <1k roguelike (in c)
print("@");
size 11.
But seriously, what would be important in a roguelike:
random generation, turn based, ascii, combat and keyboard input?
I think these characteristics would make minimum content for the
entries. They capture important features of roguelikes, and are
possible to do under 1kb. You could consider to drop the ascii
requirement, but I doubt anybody is able to create a non-ascii <1kb
roguelike.
--
Soyweiser
I would agree with that, and consequently you'll see that the entry
that started this thread has all of these features ;)
This is great fun! I started to write up an implementation in Scala
over my lunch break, but got far too carried away and ended up
hovering near the 3k mark with stupid combat, levelling, and a sorta
infinite dungeon... feature creep, y'know.
I'll be trying again tonight though :)
-Snut
Okay, this was fun!
Here goes the plot
It is been about four million years since the times of The Quest for
the Amulet of Yendor. The planet has been devastated and traces of
civilization are no longer found.
You land your ship near the place the amulet of Yendor is rummored to
be.
Your ship soon becomes unstable and you are ejected; your main oxygen
tank blows into a million pieces, and you are left with a limited and
pretty useless secondary tank.
Having no hope to survive, you jump into the ruins of Yendor, hoping
to find at least 10 pieces of the broken amulet, become God, save
yourself and turn the planet into a happy greenland.
Screenshot: http://slashie.net/share/0KRL2.png
Here goes my 999 bytes entry. It is Java code, and uses libjcsi for
output. (http://sourceforge.net/projects/libjcsi/)
import sz.csi.jcurses.JCursesConsoleInterface;
public class X{
static int xr,yr,xp,yp,xs,ys,xo,yo,v,r,i,e=300,s;
static boolean map[][]=new boolean[20][20];
static int r(){return (int)(Math.random()*19.0d);}
public static void main(String[] p){
while (i < 20){map[r()][r()]=true;i++;}
c.cls();
p(21,1,"Slash1KBRL - LUCK :)!");
o:while(true){
if(xo==xp&yo==yp){xo=21+v;yo=3;r++;}
if(xs==xp&ys==yp){xs=r();ys=r();xp=r();yp=r();xo=r();yo=r();v++;}
yr=0;
while(yr<20){
xr=0;while(xr<20){
p(yr,xr,map[xr][yr]?"#":".");
xr++;}
yr++;}
p(2,22,"L"+v+" R"+r+" E"+e+" ");
p(xp,yp,"@");
p(xs,ys,">");
p(xo,yo,")");
switch(c.inkey().code){
case 112:yp--;break;
case 108:yp++;break;
case 90:xp--;break;
case 93:xp++;break;
case 40:break o;
}e--;
if(e==0){p(2,23,"LOST");break o;}
if(v==20){s=10-r;if(s>0)p(2,23,"LOSER");else p(2,23,"WON "+s);break
o;}
}}
static JCursesConsoleInterface c = new JCursesConsoleInterface();
static void p(int x,int y,String m){
c.print(x, y, m);
}}
When is the deadline? I will post all the games on roguetemple
Thanks, I must hang around the irc channel more often :)
--
Slashie
http://santiagoz.com/blog
http://slashie.net
http://roguetemple.com
The main file is now only 634 bytes, and has more features than the
old one. It now supports diagonal directions, has walls, is much
bigger, and has color!
On Wed, 6 Aug 2008 15:12:44 -0700 (PDT), Ido Yehieli wrote:
> a discussion we've had at the #rgrd irc channel leads me to announce
> the very first "<1kb RL challenge"!
Neat idea!
Someone said a graphical 1krl would probably not be
possible, so I wrote one in FreePascal using Graph. ;-)
Sadly it has certain problems - on my Amiga it runs
but seems to ignore any input, on Win98 (sic) it
displays the map in a Graph window, but doesn't do
anything else, on Linux it works as intended (only
Graph/libvga needs root/suid root).
(Sigh. That means I indeed have to look for another
output method for YARL.)
The only keys are numkeys for movement in four directions
and ESC for quit. Pascal is a bit lengthy, so I didn't
find room for any messages. (The pink dot in the center
is you.) You are considered a winner if there's no
monster left.
-snip-
PROGRAM p;USES Graph;CONST c=319;l=199;f=15;VAR
k:CHAR;d:ARRAY[0..c,0..l]OF SMALLINT;
w,z:ARRAY[0..11]OF SMALLINT;n,u,v,x,y:SMALLINT;BEGIN
x:=f;y:=30001;InitGraph(x,y,'');
FOR x:=0 TO c DO BEGIN d[x,0]:=f;d[x,l]:=f END;FOR y:=0 TO l DO BEGIN
d[0,y]:=f;d[c,y]:=f END;
FOR n:=0 TO 3456 DO d[Random(c),Random(l)]:=f;
FOR n:=0 TO 11 DO BEGIN w[n]:=Random(c);z[n]:=Random(l) END;
FOR x:=0 TO c DO FOR y:=0 TO l DO PutPixel(x,y,d[x,y]);
x:=160;y:=100;PutPixel(x,y,13);REPEAT Read(k);PutPixel(x,y,0);
CASE k OF'8':IF d[x,y-1]<>f THEN DEC(y);'2':IF d[x,y+1]<>f THEN INC(y);
'4':IF d[x-1,y]<>f THEN DEC(x);'6':IF d[x+1,y]<>f THEN INC(x);
END;FOR n:=0 TO 11 DO IF(x=w[n])AND(y=z[n])THEN w[n]:=-1;
PutPixel(x,y,13);FOR n:=0 TO 11 DO BEGIN u:=w[n];v:=z[n];IF u>0 THEN
BEGIN PutPixel(u,v,0);
CASE Random(4)OF 0:IF d[u,v-1]<>f THEN DEC(z[n]);1:IF d[u,v+1]<>f THEN
INC(z[n]);
2:IF d[u-1,v]<>f THEN DEC(w[n]);3:IF d[u+1,v]<>f THEN INC(w[n]);
END;PutPixel(w[n],z[n],4);IF(w[n]=x)AND(z[n]=y)THEN k:=#27;
END END;UNTIL k=#27;CloseGraph;END.
-snap-
Ad Astra!
JuL
--
jyn...@gmx.de / Work like you don't need the money
Jürgen ,,JuL'' Lerch / Dance like no one was watching
/ Love like you've never been hurt
/ - ?
Hi everyone,
I'm a long time lurker, but there was something about this challenge
that intrigued me to see what I could do in 1kb of code. Well I think
the result came out well. It has all the basics, except it is a
survival game rather than one that can be won. It is called "Oh
Rats!", programmed in FreeBASIC. Enjoy.
Source:
http://games.datagrind.com/download/ohrats-1.0.0.bas
Windows Binary:
http://games.datagrind.com/download/ohrats-win32bin-1.0.0.zip
There are people that still use amigas??
Good job, nicest entry I've seen so far. Much better than mine.
-Ido.
So, we need a final date.
I also <b>propose</b> the following:
* All participants have a vote for the winning entry, which they must
spend in someone else's project
* All participants must provide a working executable
* Or working script file ;]
T.
>
> --
> Slashiehttp://santiagoz.com/bloghttp://slashie.nethttp://roguetemple.com
right? i could fit an at-sign that moves around the screen and can
climb up or down stairwells while a ticker keeps track of what 'floor'
they're on in under 1 k. in fact that's probably what everybody will
do. who the hell could lose?
this isn't the 1st most pointless contest i've seen all year, but it
comes close. the other was in writing.
Duh...
The point is to do this PLUS add some unique value, if possible.
Also, it is fun.
It is in fact not what everyone did. Some of the entires are,
surprisingly enough, actual games.
> this isn't the 1st most pointless contest i've seen all year, but it
> comes close.
Then don't participate.
Small bugfix: add cbreak() at into thr 4th line, to get the key
presses immediately. New version (976 bytes): http://pastie.org/250616
-Ido.
Which Monday ? ;0
T.
Yeah, which Monday ! ?
>
> T.
I have released version 2.0 of my entry, further info and downloads
(ready to be executed) here: http://www.santiagoz.com/blog/?p=253
I added:
* Line of Sight (Kind of)
* Solid cells
* Themed Levels (:P)
* Level borders
* Ensured stairs and artifacts are reachable
Here is a pic: http://www.santiagoz.com/blog/wp-content/uploads/2008/08/slash-1krl-luck.png
Here goes my 1023 bytes entry.
import sz.csi.jcurses.*;public class C{int
xr,yr,xp,yp,q,w,xo,yo,v,r,i,e=500;
boolean m[][]=new boolean[20][20];int r(){return(int)
(Math.random()*17+1);}
void a(int x,int y,String h){p(x,y,Math.abs(xp-x)+Math.abs(yp-y)<7?
h:" ",1+
(int)(v/2.0d));}void j(int x,int y){if(!m[xp+x][yp+y]){xp+=x;yp
+=y;}}public
static void main(String[]p){new C();}public C(){for(;i<20;i++)
{m[r()][r()]=
m[0][i]=m[19][i]=m[i][0]=m[i][19]=true;}c.cls();o:for(;;)
{if(xo==xp&yo==yp){
xo=40;yo=3;r++;}if(q==xp&w==yp)
{q=r();w=r();xp=r();yp=r();xo=r();yo=r();v++;
m[q][w]=m[xo][yo]=false;}yr=-1;while(yr++<19){xr=-1;while(xr++<
19)a(xr,yr,m[
xr][yr]?"#":".");}p(2,22,"LUCK! Slash > L"+v+" E"+e+" R"+r+" ",
7);p(xp,yp,
"@",12);a(q,w,">");a(xo,yo,")");switch(c.inkey().code){case
112:j(0,-1);
break;case 108:j(0,1);break;case 90:j(-1,0);break;case
93:j(1,0);break;case
40:break o;}if(--e==0)break o;if(v==21){if(r>=10)p(2,23,"WON "+
(r-10),4);
break o;}}}JCursesConsoleInterface c=new
JCursesConsoleInterface();void p(int
x,int y,String m,int o){c.print(x,y,m,o);}}
Tomorrow...
Yes, Tomorrow at 12:00 CET (GMT+2). Or whenever, just be tomorrow.
Btw, I've launched http://1024brl.googlepages.com
All games will be there after their authors specify in this thread
that "the game is ready".
Mine's ready :p
The latest version, which I think will be the final version:
http://games.datagrind.com/download/ohrats-1.0.3.bas
http://games.datagrind.com/download/ohrats-win32bin-1.0.3.zip
Downloadable via the website as well:
http://games.datagrind.com/index.php?pageid=8
Yup. Actually I'm reading usenet (and therefore writing
this posting) on my A4kD. And there's still uploads to
the Aminet for classical Amigas.
(The condition for YARL is that it should run on Linux,
Windows, and (classical) AmigaOS.)