for(_='-1~%(w~)Z&&YfZYgZX]=Ww*V=[U0,0SVg+fR[RQmQ]P,PUS]OE(N,gKNw)J=JK=JGMath.F+H+H)BC(fA)|A@?0:=0;==eUS,S]+=Y(e[+k.slice(p=ll[r]R+VH?(W,++function(fK){=return );)2*N2)~t.length L=f,y=gBfor(Vy+L]R]><bigQ+VP[0]+P[1]];gg<w;g)ff<w;f)=t[ ~][i],var ,h,lU],mU],p,t,u=v,w,L,y;setInterval(if(!h){w=11>v?4+v:15;h=v;o1>o;){o=1E5;tU]=X~O;ii<w-8;)VJ+JW~;i--oYi<h;)if(fG,!(8<||0>||iY!YN1E3)||(k=(H=N2,r=R,I=R-VH-k,]))){;N10)Y0+VH];gH,fki||(;AKB0<I]YI]!=):!N5)Yi=~):(W,i),}}!AG)L=f;y=g}f=2]-i];g=3]-1];32]Y lmLyht=t0,~)R+?0<R+t[ ]Ul),m),L,y,h],mQ+Ug,f]):(,Lf,yg,=-2uP[0]|P[1]YXY!((f+g+u/4)%2)n=l,n?(--h,l=n~,):1>nl=,m>n?[S]:P,)Oi="<pre><b><center>"i0>=?".#\\u263b"[-]:,fw~i"<br>"b.innerHTML=i+v;},16CpQ]fLYgy?1:(pQW1)&A+1K@~K@K~@K+1)};b.onkeydown=f.keyCode%37W1};EFfloor(1E6*Frandom())%f};';G=/[^ -?CEHILMT[-}]/.exec(_);)with(_.split(G))_=join(shift());eval(_)
///////////////////////////////////////////////////////////////
//
// The Digit Dilemma
// By Frank Force 2019
//
///////////////////////////////////////////////////////////////
var playerControls = [0,0,0,0], pieceCount, playArea = [], moveArea = [], playAreaFill, rewind, frameCount = 0, level = 0, size, playerX, playerY;
setInterval(
function(x,y)
{
if (!pieceCount) // go up a level when there are no pieces left
{
size = ++level<11?4+level:15;
pieceCount = level;
for(o=0;o<1;)
{
// generate puzzle
o = 100000;
rewind = [];
// clear playfield
for(y=0;y<size;++y)
for(x=0;x<size;++x)
playArea[size*y+x] = x%(size-1)&&y%(size-1)?0:-1,moveArea[size*y+x] = [0,0];
// add random blockers
for(i=0;++i<size-8;)
playArea[size*R(size)+R(size)]=-1;
for(i=0;--o&&i<pieceCount;)
{
// get a random piece
x = R(size);
y = R(size);
if (playArea[size*y+x] > 8 || playArea[size*y+x] < 0 || i && !playArea[size*y+x] && R(1000))
continue; // try again if -1 or 9 (to prevent 10s) or if empty and not first and large chance
// random direction
j = R(2)?0:R(2)*2-1;
k = j?0:R(2)*2-1;
// save location
r = size*y+x;
q = size*y+x - size*j-k;
// must be empty on push side
if (playArea[size*y+x + size*j+k])
continue;
// move farther with randomness
for(;R(10)&&playArea[size*y+x + size*j+k + size*j+k]==0;y+=j,x+=k);
// check that it is possble to get to pushing location using fill function
playAreaFill = playArea.slice();
if (!i) // first piece must set player pos
playerX = x+k+k,playerY = y+j+j;
if (!C(x+k+k,y+j+j))
continue;
// make move
if (playArea[q] > 0 && playArea[q] != playArea[r])
playArea[size*y+x + size*j+k] = playArea[r],playArea[r] = 0; // bump into a piece
else if (!R(5) && i)
playArea[size*y+x + size*j+k] = playArea[r],playArea[r] = -1; // push into blocker (not for first piece)
else
playArea[size*y+x + size*j+k] = ++playArea[r],i++; // split
playerX = x+k+k,playerY = y+j+j;
}
}
// randomize player start (can be removed if more space is needed)
for(playAreaFill = playArea.slice();!C(x = R(size),y = R(size));playAreaFill = playArea.slice());
playerX = x;
playerY = y;
}
// player controls
x = playerControls[2] - playerControls[i = 0];
y = playerControls[3] - playerControls[1];
if (playerControls[32] && rewind.length)
{
// rewind
playArea = rewind[rewind.length-1][i++];
moveArea = rewind[rewind.length-1][i++];
playerX = rewind[rewind.length-1][i++];
playerY = rewind[rewind.length-1][i++];
pieceCount = rewind[rewind.length-1][i++];
rewind = rewind.slice(0, -1);
}
// player movement
// check if moving into empty space or push a number
if (!playArea[size*y+x + size*playerY+playerX])
{
// empty space
playArea[size*playerY+playerX] = 0;
playerX+=x;
playerY+=y;
playArea[size*playerY+playerX] = -2;
}
else if (playArea[size*y+x + size*playerY+playerX] > 0)
{
// push number
rewind[rewind.length] = [playArea.slice(), moveArea.slice(), playerX, playerY, pieceCount];
moveArea[size*y+x + size*playerY+playerX] = [y,x];
}
// update moves
++frameCount;
for(y=0;y<size;++y)
for(x=0;x<size;++x)
{
if ((moveArea[size*y+x][0] | moveArea[size*y+x][1]) && x%(size-1) && y%(size-1) && !((x+y+frameCount/4)%2))
{
n = playArea[size*y+x + size*moveArea[size*y+x][0]+moveArea[size*y+x][1]];
if (n==playArea[size*y+x])
{
// hit same number, join
--pieceCount;
playArea[size*y+x + size*moveArea[size*y+x][0]+moveArea[size*y+x][1]] = n-1;
playArea[size*y+x] = 0;
}
else if (n < 1)
{
// open or wall, move into it
playArea[size*y+x + size*moveArea[size*y+x][0]+moveArea[size*y+x][1]] = playArea[size*y+x];
moveArea[size*y+x + size*moveArea[size*y+x][0]+moveArea[size*y+x][1]] = n<0?[0,0]:moveArea[size*y+x];
playArea[size*y+x] = 0;
}
moveArea[size*y + x] = [0,0];
}
}
i = "<pre><big><big><big><big><big><big><big><b><center>";
for(y=0;y<size;++y)
for(x=0;x<size;++x)
{
//i += "<font style='color:hsl("+ 30*playArea[size*y+x] + ",99%,50%)'>"
i += playArea[size*y+x]<=0? ".#☻"[-playArea[size*y+x]] : playArea[size*y+x];
if (x==(size-1))
i += "<br>";
}
b.innerHTML = i + level;
playerControls = [0,0,0,0];
},16);
// check if it is possible to get to player pos
C=function(x,y)
{
return playAreaFill[size*y+x]?0:
x == playerX && y == playerY?1:
(playAreaFill[size*y+x] = 1)&C(x+1,y)|C(x-1,y)|C(x,y-1)|C(x,y+1);
}
b.onkeydown = function(x,y) {playerControls[x.keyCode%37]=1;}
R=function(x,y){return Math.floor(Math.random() * 1E6) % x;}
/*
********************
* * * * * * * * * **
** ** ** ** ** *
* * * * * *
**** **** ****
* * * * * **
** ** ** *
* * * *
******** 1 ****
* * * * * **
** ** ** *
* * 1 * *
**** ****
* * * **
** ** *
* * *
******* ******** *
* * * * * * * * *
** ** ☻** ** *
********************
*/