const direction=[[-1,0],[1,0],[0,1],[0,-1],[0,0]];
class Node{
constructor(t,i,e,s){
this.move=i,
this.value=null,
this.treeValue=this.value,
this.player=e,
this.state=t,
this.child=[]
}
addDepth(t){
var i,e,s,h=0;
if(this.child.length)
for(s=0;s<this.child.length;++s)
this.child[s].addDepth(t);
else if(this.player)
for(h=0;h<5;++h)
i=this.state[0]+direction[h][0],
e=this.state[1]+direction[h][1],
1===t.get(i,e)||i===this.state[2]&&e===this.state[3]||this.child.push(new Node([i,e,this.state[2],this.state[3]],h,!this.player,t));
else
for(h=0;h<5;++h)
i=this.state[2]+direction[h][0],
e=this.state[3]+direction[h][1],
1==t.get(i,e)||i===this.state[2]&&e===this.state[3]||this.child.push(new Node([this.state[0],this.state[1],i,e],h,!this.player,t))
}
getBest(t,i=-500,e=500){
if(null===this.value&&(this.value=t.distance(this.state)),!this.child.length)
return[this.value,this.move];
var s,h,r;
if(this.player)
for(s=[-500,0],h=0;h<this.child.length;++h)
(r=this.child[h].getBest(t,i,e))[0]>s[0]&&(s=[r[0],this.child[h].move]);
else
for(s=[500,0],h=0;h<this.child.length;++h)
(r=this.child[h].getBest(t,i,e))[0]<s[0]&&(s=[r[0],this.child[h].move]);
return this.treeValue=s[0],s
}
}
function Mind(){
this.newRun=function(){
this.map= new function(){
this.map=[],
this.dict={};
for(var t=0;t<20;++t){
this.map.push([]);
for(var i=0;i<20;++i)
0===t||19===t||0===i||19===i?this.map[t].push(1):this.map[t].push(2)
}
function e(t,i){
return Math.abs(t[0]-i[0])+Math.abs(t[1]-i[1])
}
this.set=function(t,i,e){
1===e&&1!==this.map[i][t]&&(this.dict={}),
this.map[i][t]=e},
this.get=function(t,i){
return this.map[i][t]
},
this.print=function(){
for(var t=0;t<this.map.length;++t)
console.log(t,this.map[t].join(" "))
},
this.UpdateDict=function(t){
for(var i in t)
if(t.hasOwnProperty(i))
for(var e=i,s=t[i],h=0;void 0!==s;){
h+=1;
var r=[s,e];
r.sort(),(r=r[0]+r[1])in this.dict&&!(this.dict[r]>h)||(this.dict[r]=h),s=t[s]}
},
this.Astar=function(t,i){
const s=function(t){
return t[0]==this[0]&&t[1]==this[1]
};
var h=[],r=[t],n={},a={};
n[t.toString()]=0,a[t.toString()]=e(t,i);
var o={};
const l=[[-1,0],[1,0],[0,-1],[0,1]];
for(;r.length;){
var c,d=r[0],u=a[d.toString()],f=0;
for(c=1;c<r.length;++c)
u>a[r[c].toString()]&&(u=a[r[c].toString()],
d=r[c],f=c);
if(r.splice(f,1),h.push(d),d[0]==i[0]&&d[1]==i[1])
return this.UpdateDict(o),n[d];
for(c=0;c<l.length;++c)
if(u=[d[0]+l[c][0],d[1]+l[c][1]],1!=this.map[u[1]][u[0]]){
if(h.find(s,u))continue;
if(f=n[d.toString()]+1,r.find(s,u)){
if(void 0!==n[u.toString()]&&n[u.toString()]>=f)continue}
else r.push(u);
o[u.toString()]=d.toString(),n[u.toString()]=f,a[u.toString()]=f+e(u,i)
}
}
return 900
},
this.distance=function(t){
if(Math.abs(t[0]-t[2])<2&&Math.abs(t[1]-t[3])<2)
return e([t[0],t[1]],[t[2],t[3]]);
var i=[[t[0],t[1]].toString(),[t[2],t[3]].toString()];
i.sort();
var s=i[0]+i[1];
return void 0===this.dict[s]&&(this.dict[s]=this.Astar([t[0],t[1]],[t[2],t[3]])),this.dict[s]}
},
this.dir=0,this.last=[0,0]},
this.setWall=function(t){
return t[0]==this.last[0]&&t[1]==this.last[1]&&4!==this.dir&&(x=t[0]+direction[this.dir][0],y=t[1]+direction[this.dir][1],x!=this.last[3]&&y!=this.last[4]&&(this.map.set(x,y,1),!0))}
,
this.moveTree=function(t){
var i,e=!0;for(i=0;i<this.tree.child.length;++i)
if(this.tree.child[i].state[0]==t[0]&&this.tree.child[i].state[1]==t[1]){
this.tree=this.tree.child[i],
e=!1;
break;
}
if(e) return!1;
for(e=!0,i=0;i<this.tree.child.length;++i)
if(this.tree.child[i].state[2]==t[2]&&this.tree.child[i].state[3]==t[3]){
this.tree=this.tree.child[i],e=!1;
break
}
return!e
},
this.reset=function(t){
this.tree=new Node(t,4,!0,this.map),
this.tree.addDepth(this.map),
this.tree.addDepth(this.map),
this.tree.addDepth(this.map),
this.tree.addDepth(this.map),
this.tree.addDepth(this.map),
this.tree.addDepth(this.map)},
this.choose=function(){
var t;
this.tree.child.sort((t=this.map,function(i,e){
return i.treeValue>5&&e.treeValue>5&&t.get(i.state[0],i.state[1])>t.get(e.state[0],e.state[1])?-1:i.treeValue>e.treeValue?-1:(i.treeValue,e.treeValue,1)
})),
this.dir=this.tree.child[0].move
},
this.getAction=function(t){
return this.map.set(t[0],t[1],0),
0===this.last[0]||this.setWall(t),
this.reset(t),
this.last=t,
this.tree.getBest(this.map),
this.choose(),
this.tree.treeValue<4?console.error(this.tree):console.log(this.tree),
console.log(this.dir),
this.dir
},
this.endRun=function(){
}
}