Navigate the maze and gather mana avoiding the green slime and merrily discharge digestive juices.
for(_=']=NmNG40FF*E,EbD0;C=4CZ--,Y160X&&WW(V==U #A[]||C+g+E( "+H()?1:-1>m=p+J[returne+Ef+" =3if();l+Ek--;)?-1:c.fillStyle=S[;function for( Up]Vt+=Text(""D/3D/2)UR?1:CW>99-yV; k=XCka.localStorage.h kZk lZlvar a=window,b=a.innerHeight/F|0,e,f,g,h,k,l,m,n,p,r=F,t,u,v,w,x=1,y=0,S="#333555222384B4455dA82".split(" "),A,B=A=[]{ 200*(Math.random()-.5)|0}t=u=Cvar J=[F,-F,-1,1,0],LM(R){R=R.which;g7UR39h8URFu2x|r){x?y++:(y=1,w)kN>9+9*y?2:Ce=f=2Cu=2+y;v=u+y2>k]VvvYk]),uuYX0-kN5)N6;F!=rW13!=R);x=r=CB=[]}p=ef+hu+g+hW0<pWX0>pW2!=p]){53,w++35uWw) wYn=2Cnn%4]+J[n%5],t+Um]?9:0,u=B[GG1;m=;GB[mpN6;e+=g;f+=h;L={};3U]&!L[]){g=e-l;h=f-k;2>g*g+h*hVNr=4p=;h=1<hhCg=1<ggCnZ m=lk+hn--W1<m];)%4];pNB[pm];L[G1}x=!L[m]}]],Rect(l*b,k*b,b,b6];c.font=(2*b|0)+"px Arial";t>=~~V=tManawLevelyScoretBest,9D-9r?(t=0,Sad):xVJoy,t+=20)}d.onkeydown=M;M(d';G=/[-U-ZC-GN]/.exec(_);)with(_.split(G))_=join(shift());eval(_)
Zm9yKF89J109Tm1ORzQwRkYqRSxFYkQwO0M9NENaLS0sWTE2MFgmJldXKFY9PVUgIx9BWx5dfHxDHh0rZytFKBwgIisbSCgpGj8xOi0xPhltPXArSlsYcmV0dXJuF2UrRWYWKyIgIBU9MxRpZigTKTsSbCtFaxEtLTspED8tMToPYy5maWxsDg5TdHlsZT1TWww7ZnVuY3Rpb24gC2ZvcigJVR5wXVZ0Kz0IDlRleHQoIgciRC8zRC8yKQZVUj8xOkMFVxo+OTkteVYEOwlrPVhDaxADYS5sb2NhbFN0b3JhZ2UuaAIJa1prEAlsWmwQAXZhciBhPXdpbmRvdyxiPWEuaW5uZXJIZWlnaHQvRnwwLGUsZixnLGgsayxsLG0sbixwLHI9Rix0LHUsdix3FCx4PTEseT0wLFM9IiMzMzMfNTU1HzIyMh8zODQfQjQ0HzU1ZB9BODIiLnNwbGl0KCIgIiksQSxCPUE9W10LGnsXIDIwMCooTWF0aC5yYW5kb20oKS0uNSl8MH10PXU9Q3ZhciBKPVtGLC1GLC0xLDEsMF0sTAtNKFIpe1I9Ui53aGljaDtnFDdVUg8zOQVoFDhVUg9GBXUUMgUTeHxyKXt4P3krKzooeT0xLHcUKQMea04aPjkrOSp5PzI6Q2U9Zj0yQ3U9Mit5O3Y9dSt5AzI+HmtdVnYEdlkea10UKSx1BHVZHlgwLWtONSkSHhZONjsTRiE9clcxMyE9UikXO3g9cj1DQj1bXX1wPWUcZitoEhN1K2craFcwPHBXWDA+cFcyIT0ecF0pezUIMyx3KysSMwg1EhN1V3cpCXdZbj0yQ24QGG4lNF0rSltuJTVdLHQrFFUebV0/OTowLHU9QltHHkcxO209FjseR0JbbR1wTjY7ZSs9ZztmKz1oO0w9e307ARMzVR4RXSYhTFsRXSl7Zz1lLWw7aD1mLWs7Mj5nKmcraCpoVh4WTnI9NBJwPRE7aD0xPGgZaA9DZz0xPGcZZw9DbloJbT1sHGsraBJuLS1XMTwebV07KRgaJTRdOx5wTkJbcB1tXRQ7TFtHMX14PSFMW21dfQEMHhFdXSwOUmVjdChsKmIsaypiLGIsYhIMNl07Yy5mb250PSgyKmJ8MCkrInB4IEFyaWFsIjt0Pj1+fgJWAj10EgdNYW5hG3cVTGV2ZWwbeRVTY29yZRt0FUJlc3QbAiw5RC05EnI/KHQ9MCwHU2FkBik6eFYHSm95Bix0Kz0yMCl9ZC5vbmtleWRvd249TTtNKGQSJztHPS9bAS0fVS1aQy1HTl0vLmV4ZWMoXyk7KXdpdGgoXy5zcGxpdChHKSlfPWpvaW4oc2hpZnQoKSk7ZXZhbChfKQ==
// Bitmage - js1k 2017
//
// You are a yellow bitmage exploring dungeons. You love finding delicious blue
// mana that you consume hoping to grow stronger. As a member of the
// kingdom of fungi you are able to secrete an acidic venom that digests all
// material around you. A useful skill in these areas.
//
// Lately the green slime have been getting on your nerves. They do not obey
// the same rules as you and too often they are hostile. It is time to teach
// them a lesson!
//
// "Green slime are the most tricky part about being a bitmage. They follow
// me everywhere I go, impossible to get rid of. I am not sure they want to
// harm me but experience has taught me to take no chances. Sometimes
// confronting them head on is the best approach."
//
// Objective
//
// Avoid crossing the green slime, collect mana
// and see if you can get the highest score.
//
// Controls
//
// Arrows keys to move
// Space to cast digestive secretion spell
// Enter to continue
//
// Scoring
//
// Find mana: 3 points
// Confront slime: 5 points
// Blast slime 9 points
// Complete level: 20 points
//
// TODO
//
// * Better AI
// * wrap around properly
// * Deterministic randomness
// * Place enemies better
// * Colors
// * Save more bytes
var win = window
var height = win.innerHeight
var w = 40
var g = height / w | 0
var x
var y
var dx
var dy
var i
var j
var ii
var jj
var pos
var died = w
var points
var bomb
var baddies
var mana = 3
var completed = 1
var level = 0
// floor boom wall enemy died bomb player
var colors = ['#333', '#555', '#222', '#384', '#B44', '#55d', '#A82']
var dungeon
var bg = dungeon = []
function r1 () {
return 200 * (Math.random() - 0.5) | 0
}
points = bomb = 0
var args = [w, -w, -1, 1, 0]
var moved
const FLOOR = 0
const BOOM = 1
const WALL = 2
const ENEMY = 3
const DIED = 4
const BOMB = 5
const PLAYER = 6
function xx (ev) {
// Player
ev = ev.which
dx = ev == 37 ? -1 : ev == 39 ? 1 : 0
dy = ev == 38 ? -1 : ev == w ? 1 : 0
bomb = ev == 32 ? 1 : 0
if (completed | died) {
if (completed) level ++
else level = 1, mana = 3
// make dungeon
i = w * w
for (;i--;) dungeon[i] = r1() > 9 + 9 * level ? WALL : FLOOR
x = y = w / 2
// place baddies and bombs
bomb = 2 + level
baddies = bomb + level
i = w * w
// at higher levels bombs and baddies become more separated
for (;i--;) if (dungeon[i] < WALL) {
if (baddies && r1() > 99 - level) baddies--, dungeon[i] = ENEMY
if (bomb && r1() > 99 - level) bomb--, dungeon[w * w - i] = BOMB
}
dungeon[x + y * w] = PLAYER
if (died != w && ev != 13) return
completed = died = 0
bg = []
}
pos = x + dx + (y + dy) * w
if (bomb + dx + dy && pos > 0 && pos < w*w && dungeon[pos] != WALL) {
if (dungeon[pos] == BOMB) points += 3, mana ++
if (dungeon[pos] == ENEMY) points += 5
if (bomb && mana) {
mana--
jj = 20
for (;jj--;)
ii = pos + args[jj % 4] + args[jj % 5],
points += dungeon[ii] == ENEMY ? 9 : 0,
bomb = bg[ii] = dungeon[ii] = BOOM
}
ii = x + y * w
dungeon[ii] = bg[ii] || FLOOR
dungeon[pos] = PLAYER
x = x + dx
y = y + dy
moved = {}
for (i = w; i--;) {
for (j = w; j--;) {
if (dungeon[j + i * w] == ENEMY & !moved[j + i * w]) {
// move enemy
dx = x - j
dy = y - i
if (dx * dx + dy * dy < 2) dungeon[x + y * w] = died = DIED
pos = j + i * w
dy = dy > 1 ? 1 : dy < -1 ? -1 : 0
dx = dx > 1 ? 1 : dx < -1 ? -1 : 0
jj = w
ii = j + dx + (i + dy) * w
while (jj-- && dungeon[ii] > BOOM) ii = pos + args[r1() % 4]
dungeon[pos] = bg[pos] || FLOOR
dungeon[ii] = ENEMY
moved[ii] = 1
}
}
}
// All baddies killed?
completed = !moved[ii]
}
// Paint stuff
for (i = w; i--;) {
for (j = w; j--;) {
c.fillStyle = colors[dungeon[j + i * w]];
c.fillRect(j * g, i * g, g, g);
}
}
c.fillStyle = colors[6]
c.font = (2 * g | 0) + 'px Arial'
if (points >= ~~win.localStorage.h) win.localStorage.h = points
c.fillText('Mana ' + mana + ' Level ' + level + ' Score ' + points +
' Best ' + win.localStorage.h, 9, w * g - 9)
if (died) points = 0, c.fillText('Sad', g * w / 3, g * w / 2)
else if (completed) c.fillText('Joy', g * w / 3, g * w / 2), points += 20
}
d.onkeydown = xx
xx(d)