Complete Flash Sokoban game in less than 2KB
Some days ago I blogged about 6 games you must be able to make in less than a day.
Among these games I included Sokoban, and since I don’t remember if I’ve ever tried to make a complete Sokoban game, I did it today.
In less than a day and, above all, in less than 2KB!!
And don’t expect an incomplete prototype… my Sokoban game features:
* 10 levels
* Tiles of different color and shape
* Shared objects to save the games
* Eye-candy effects (being only 2KB!!) to show completed levels and current level
* Copyable level moves to publish your own level solution
* In game instructions
* No external files or other tricks to reduce file size.
As said, in less than 2KB. My latest build is 2,002 bytes that’s less than 2,048.
This is the source code, that wasn’t written with readability or performance in mind, just aiming to stay under 2KB… just an exercise:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
package { import flash.display.Sprite; import flash.events.KeyboardEvent; import flash.text.TextField; import flash.net.SharedObject; public class s extends Sprite { var m:Array=[[[1,1,1,1],[1,0,0,1,1,1,1,1],[1,0,2,0,0,3,0,1],[1,0,3,0,0,2,4,1],[1,1,1,0,0,1,1,1],[0,0,1,1,1,1]],[[0,0,1,1,1,1],[0,0,1,0,0,1],[1,1,1,0,0,1,1,1],[1,0,3,5,2,4,0,1],[1,0,0,0,0,0,0,1],[1,1,1,1,1,1,1,1]],[[0,0,1,1,1,1],[1,1,1,0,0,1],[1,0,0,5,4,1],[1,0,0,3,2,1,1],[1,1,1,0,0,0,1],[0,0,1,0,0,0,1],[0,0,1,1,1,1,1]],[[0,1,1,1,1,1,1,1],[1,1,0,4,0,0,0,1],[1,0,3,2,0,0,0,1],[1,0,2,3,1,1,1,1],[1,1,0,0,1],[0,1,0,0,1],[0,1,1,1,1,0]],[[1,1,1,1,1,1,1],[1,0,0,0,2,4,1,1,1],[1,0,0,5,5,5,0,0,1],[1,0,0,0,3,0,0,0,1],[1,1,1,1,1,1,0,0,1],[0,0,0,0,0,1,1,1,1]],[[0,0,1,1,1,1],[0,0,1,0,0,1],[0,0,1,0,0,1],[1,1,1,0,4,1,1],[1,0,5,3,2,0,1],[1,0,0,0,0,0,1],[1,1,0,0,1,1,1],[0,1,1,1,1,0,0]],[[0,0,1,1,1,1],[0,0,1,0,0,1,1,1],[1,1,1,2,3,2,0,1],[1,0,0,3,2,3,0,1],[1,0,0,0,4,1,1,1],[1,0,0,0,0,1],[1,1,1,1,1,1]],[[1,1,1,1],[1,0,0,1],[1,0,4,1],[1,2,3,1,1,1],[1,0,0,0,0,1],[1,2,3,1,0,1],[1,1,0,0,0,1],[0,1,1,1,1,1]],[[1,1,1,1,1,1,1],[1,0,0,1,0,0,1],[1,2,3,1,0,0,1],[1,6,3,0,0,0,1],[1,2,3,0,0,0,1],[1,1,1,1,1,1,1]],[[1,1,1,1,1,1,1,1],[1,0,0,1,0,0,0,1],[1,0,0,0,0,0,0,1],[1,3,3,3,1,1,1,1],[1,6,2,0,2,1],[1,1,1,1,1,1]]]; public var l,h:int=0; public var p,r:Array; public var f:Sprite=new Sprite(); public var g,o:Sprite; public var u:TextField = new TextField(); public var c:SharedObject=SharedObject.getLocal("s"); public function s():void { if (c.data.l==undefined) { c.data.l="0000000000"; } for (var i:int=0; i<10; i++) { g=new Sprite(); g.graphics.beginFill(0x00ff00); g.alpha=0.2+0.8*c.data.l.charAt(i); g.graphics.drawRect(0,0,9,9); g.x=130+i*11; g.y=35; g.name="g"+i; addChild(g); } o = new Sprite(); o.graphics.beginFill(0xff0000); o.graphics.drawRect(0,0,3,3); addChild(o); o.y=38; u.text="ARROWS KEYS: MOVE\n0-9: SELECT LEVEL\nCOMPLETED LEVELS:\nLEVEL MOVES: "; u.width=490; addChild(u); addChild(f); d(l); stage.addEventListener(KeyboardEvent.KEY_UP, k); } public function d(l:int):void { o.x=133+l*11; var n:int; r=new Array(); for (var i:int=0; i<m[l].length; i++) { r[i]=new Array(); for (var j:int=0; j<m[l][i].length; j++) { n=m[l][i][j]; r[i][j]=n; if (n) { if (n<5) { q(n,i,j); } else { q(2,i,j); q(n-2,i,j); } } } } } public function q(n:int,i:int,j:int):void { u.text=u.text.substr(0,67); f.y=64; var t:Sprite; var c:Array=[0x000000,0xff0000,0x00ff00,0x0000ff]; t = new Sprite(); t.graphics.beginFill(c[n-1]); t.graphics.drawRoundRect(0,0,32,32,(n-1)*20); t.x=j*32; t.y=i*32; f.addChild(t); if (n==2) { f.setChildIndex(t,0); } if (n==3) { t.name="d"+i+"_"+j; } if (n==4) { p=[i,j]; r[i][j]-=4; t.name="b"; } } public function k(e:KeyboardEvent):void { h=e.keyCode; switch (h) { case 37 : w(-1,0); break; case 38 : w(0,-1); break; case 39 : w(1,0); break; case 40 : w(0,1); break; default : if (h>47&&h<58) { l=h-48; removeChild(f); f = new Sprite(); addChild(f); d(l); } } } public function w(a:int,b:int):void { var v:Boolean=false; var _z:String="RULD"; var d:String=""; if (r[p[0]+b][p[1]+a]==0||r[p[0]+b][p[1]+a]==2) { v=true; } else { if ((r[p[0]+b][p[1]+a]==3||r[p[0]+b][p[1]+a]==5)&&(r[p[0]+2*b][p[1]+2*a]==0||r[p[0]+2*b][p[1]+2*a]==2)) { d=f.getChildByName("d"+(p[0]+b)+"_"+(p[1]+a)).name; v=true; } } if (v) { u.appendText(_z.charAt(h-37)); f.getChildByName("b").x+=32*a; f.getChildByName("b").y+=32*b; p[0]+=b; p[1]+=a; if (d!="") { f.getChildByName(d).x+=32*a; f.getChildByName(d).y+=32*b; f.getChildByName(d).name="d"+(p[0]+1*b)+"_"+(p[1]+1*a); r[p[0]][p[1]]-=3; r[p[0]+b][p[1]+a]+=3; d=""; if (r.toString().indexOf(2)==-1) { c.data.l=c.data.l.substr(0,l)+"1"+c.data.l.substr(l+1); getChildByName("g"+l).alpha=1; } } } } } } |
This class was compiled with “Compress movie” checked and “Include XMP metadata” unchecked
And this is the result:
Move with arrow keys, select levels with 0-9, leave a comment with your solutions… and try to give me an idea about another game to make it fit under 2KB.
If you want to check file size, save this file and see…
They can be easily customized to meet the unique requirements of your project.














This post has 25 comments
AnotherGuest
Pac-man can probably be done in a few KBs…not sure it can be as small as 2KB but still, an interesting challenge, isn’t it ?
Easier : checkers.
Andreas Renberg
How about Snake? I’m pretty sure it could fit under 2kb.
Shawn
On Sokoban: I notice that when you move right, the “level moves” indicates left and verse visa… Other than that, amazing! Also, it seems a bit awkward that Stages 1, 2 and 7 are harder than stages 8 and 9. (I’ve cleared all but 7 so far, that one makes me scratch my head.)
On other possibilities: Can’t space invaders be crammed into a few K?
grapefrukt
Yes! I love this bytehunting stuff, so I amused myself by seeing if I could slim your code down even more. I managed to shave 131 bytes off, that’s 6.5% smaller.
I put both our versions on wonderfl, mostly to get the nice diff.
your original version: http://wonderfl.net/c/4oMt
my, slightly smaller, version: http://wonderfl.net/c/5PAV
I think there’s a few more bytes to save if one could get rid of all those getChildByName calls, but that’ll require a bit more of a rewrite.
Keep up the nice work!
Emanuele Feronato
Yeah, removing the “switch” was a great idea
Colin Diam
1st Level…
RRRULRRRDLULLDDRULURDLLLURRDRRRUULDRDUDLLLUR
Josh
I think Frogger would be a good one to try and do in under 2k
Yago
There’s a bug, when I finished the first level debugger says:
TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo (it’s in spanish, I think it could be traduced as “Can’t get access to a null object”).
at s/w()
at s/k()
Any way, great game and incredible that 2Kbs optimization!! I still remember that little man with frozen arms moving blocks in the oldest version… Ciao!!
Alon
There is no restart mechanism =D I will add one and post it if someone wants.
Emanuele Feronato
You can restart a level simply pressing the relative 0-9 key…
Bruno
You could shrink it a little more by removing the first if in w() method by making
var v:Boolean=(r[p[0]+b][p[1]+a]==0||r[p[0]+b][p[1]+a]==2);
along with grapefrukt’s removal of the switch statement.
Anyway, great code! I follow your blog since a while ago, and your codes are always inspiring.
Yarden Refaeli
You shouldn’t use one-letter names… Even when you want a lightweight game…
Nice game!
Nigel
I can’t get past the first level :(
Ezell Burke
This is really great it inspires me to challenge myself. I am thinking of writing a graphical zork-like game.
Wolfos
normally it’s fun,but this game is impossible to beat.
Lev Blake
Hi Emanuele
Great coding tuitions, shall try them.
I finished all the levels on this, with 5 being the trickiest for me.
The coding IS clever, but even more than that the content, ie the puzzles you set, is fiendish!!! How did you work out the layout and problems for each level? Think you need to be a mathematical genius :-)
Cum se inventeaza un joc? (2) « Gramo
[...] acum ajung la problema mea. Cum am inventat jocul asta? E clar ca seamana cu Sokoban (vezi si aici), nu? La un nivel mai abstract, seamana cu toate jocurile care nu se desfasoara intr-un spatiu [...]
Pepe
Could someone explain the variables? 4 the noobs pls! That would be great.!
Vingador
It doesnt working for me, sorry.
Im using Adobe Flash Professional with AS3. Are this game for AS3 or AS2?
Thanks and i will wait for an answer.
Cyclone
I have a shorter solution: RRURRRDLULLDDRULURDLLLURRDRRRUULDRDLLLUR
Anonymous
LVL0:RRRURRDLULLDLLURRRLDDRURRUULDRDLLLUR
LVL1:RDRUDRRULLLUURDLDDLLUR
Mike
I am with Nigel on this one, I can not get past the first level either. To do this in less than a day and have 10 levels is good going.
Simon Gleizes
:
[0]:RRRURRDLULLDLLURRRLDDRURRUULDRDLLLUR
[1]:DRRUDRRULLLUURDLDDLLUR
[2]:RDRRULLDLDDRULURUULDDURRRDLLDDLLURDRUU
[3]:DDRDDLURURULLLRRDDLURUULLDRURDULLLLDRR
[4]:RRRDDLLLRRRUULLLDURRRDDLLURLLLLDDRULURRURRDDRRUULLRRDLDLLLULLDDRULUR
[5]:DDRUDRRULLULUURDDDRDDLULURUULD
[6]:URUULDDRDRRULDLULULLDRRRDDLURULUURDDLDDRRRUULDDLLURLURLULLDRURRDDLURULDDDRR RULLDLUDRRRUULDLU
[7]:RDDLUDLLDDRRUDLLUURRURUULDDDLLDDRRURUUDDLDLLUURRURDLUUURD
[8]:LLDLURRRDLLRRUUULDRDDLLURDRUDLLULLDRRRLLLUUURDLDRRR
[9]:UDLLUDRRULUURDLLDRDLUURRDULLLULLDRRRDRRUULDD
I know, I know…6 is a bit long, haha. Great game and nicely done making it ~2KB!!
Simon Gleizes
Much shorter solutions to 3, 6, 7, 8, and 9:
[3]: DDRRULLLRRDDDLUURUULLDRLULLDRRURRD
[6]:URUULDDRDRRULDLULULLDRRRDDLURULUURDDLDRUULLLDRURRDDLURULDDDRRRUULRDLLDLURU
(!!!)
[7]: RDDLLLDDRRUDLLUURRURUULDDDLLDDRRURUUDDLDLLUURRURDULUURD
[8]: LLDLURRRDLLRRUUULDRDDLLURDRULLLLUURDLDRRRLLLDRRR
[9]: UDLLUDRRULULLRRURDDLULDULULLDRRRDRRUULDD
mahongquan
I made a classic sokoban game ,It is on base of source code from your flash game making book.
and I add solved methods in game,thus it is good news for sokoban newbie.