Code viewer for World: A* Showcase Hunter and Pra...

// Cloned by Chandrabhanu Singh Rawat on 8 Nov 2022 from World "A* Showcase Hunter and Pray (clone by Deniss Strods)" by Deniss Strods 
// Please leave this clone trail here.
 
AB.clockTick=100,AB.maxSteps=1e3,AB.screenshotStep=50;const show3d=0,TEXTURE_WALL="/uploads/starter/door.jpg",TEXTURE_MAZE="/uploads/nikolif2/wall.png",TEXTURE_AGENT="/uploads/starter/pacman.jpg",TEXTURE_ENEMY="/uploads/starter/ghost.3.png",MUSIC_BACK="/uploads/starter/Defense.Line.mp3",SOUND_ALARM="/uploads/starter/air.horn.mp3",gridsize=20,QUADRANT_DIVISION=Math.floor(gridsize/5),ALLOW_DIAGONAL_MOVES=!1,EMULATE_GAME=!1,EMULATE_GAME_COUNT=100,EMULATED_GAME_STEPS=500,SMART_AGENT=!0,NOBOXES=Math.trunc(gridsize*gridsize/3),squaresize=100,MAXPOS=gridsize*squaresize,SKYCOLOR=14548957,startRadiusConst=.8*MAXPOS,maxRadiusConst=10*MAXPOS;ABHandler.MAXCAMERAPOS=maxRadiusConst,ABHandler.GROUNDZERO=!0;const SKYBOX_ARRAY=["/uploads/starter/sky_pos_z.jpg","/uploads/starter/sky_neg_z.jpg","/uploads/starter/sky_pos_y.jpg","/uploads/starter/sky_neg_y.jpg","/uploads/starter/sky_pos_x.jpg","/uploads/starter/sky_neg_x.jpg"];class GridItem{constructor(e,t,o){this.positionX=e,this.positionY=t,this.itemType=o,this.g=0,this.h=0,this.f=0,this.previousGridItem=void 0,this.neighbors=[],this.visited=!1}}const ACTION_LEFT=0,ACTION_RIGHT=1,ACTION_UP=2,ACTION_DOWN=3,ACTION_STAYSTILL=4,GRID_BLANK=0,GRID_WALL=1,GRID_MAZE=2;var BOXHEIGHT;const GRID=new Array(gridsize),AGENT_GRID=new Array(gridsize);let quadrants=[];var theagent,theenemy,wall_texture,agent_texture,enemy_texture,maze_texture,ei,ej,ai,aj,badsteps,goodsteps;function loadResources(){var e=new THREE.TextureLoader,t=new THREE.TextureLoader,o=new THREE.TextureLoader,s=new THREE.TextureLoader;e.load(TEXTURE_WALL,function(e){e.minFilter=THREE.LinearFilter,wall_texture=e,asynchFinished()&&initScene()}),t.load(TEXTURE_AGENT,function(e){e.minFilter=THREE.LinearFilter,agent_texture=e,asynchFinished()&&initScene()}),o.load(TEXTURE_ENEMY,function(e){e.minFilter=THREE.LinearFilter,enemy_texture=e,asynchFinished()&&initScene()}),s.load(TEXTURE_MAZE,function(e){e.minFilter=THREE.LinearFilter,maze_texture=e,asynchFinished()&&initScene()})}function asynchFinished(){return!!(wall_texture&&agent_texture&&enemy_texture&&maze_texture)}function occupied(e,t){return ei==e&&ej==t||(ai==e&&aj==t||(GRID[e][t].itemType==GRID_WALL||GRID[e][t].itemType==GRID_MAZE))}function translate(e,t){var o=new THREE.Vector3;return o.y=0,o.x=e*squaresize-MAXPOS/2,o.z=t*squaresize-MAXPOS/2,o}const createQuadrants=e=>{const t=e.length/QUADRANT_DIVISION,o=[];for(let e=1;e<=t;e++)for(let s=1;s<=t;s++)o.push({xStart:(e-1)*QUADRANT_DIVISION,xEnd:e*QUADRANT_DIVISION,yStart:(s-1)*QUADRANT_DIVISION,yEnd:s*QUADRANT_DIVISION});return o},getGirdItemNeighbours=(e,t)=>{const o=[],{positionX:s,positionY:i}=e,n=gridsize-1;return s<n&&o.push(t[s+1][i]),s>0&&o.push(t[s-1][i]),i<n&&o.push(t[s][i+1]),i>0&&o.push(t[s][i-1]),o},dryRunMove=(e,t)=>(moveLogicalAgent(AB.mind.getAction([ai,aj,ei,ej]),!0,t),e%2==0&&moveLogicalEnemy(!0),badstep()?badsteps++:goodsteps++,!!agentBlocked()&&(goodsteps=0,!0)),dryRunSetup=()=>{quadrants=createQuadrants(GRID),badsteps=0,goodsteps=0;for(let e=0;e<gridsize;e++)GRID[e]=[...new Array(gridsize).keys()].map(t=>{return new GridItem(e,t,0===e||e===gridsize-1||0===t||t===gridsize-1?GRID_WALL:GRID_BLANK)}),AGENT_GRID[e]=[...new Array(gridsize).keys()].map(t=>{return new GridItem(e,t,0===e||e===gridsize-1||0===t||t===gridsize-1?GRID_WALL:GRID_BLANK)});for(let e=0;e<gridsize;e++)for(let t=0;t<gridsize;t++){const o=GRID[e][t];o.neighbors=getGirdItemNeighbours(o,GRID);const s=AGENT_GRID[e][t];s.neighbors=getGirdItemNeighbours(s,AGENT_GRID)}let e,t;for(let o=1;o<=NOBOXES;o++)e=AB.randomIntAtoB(1,gridsize-2),t=AB.randomIntAtoB(1,gridsize-2),GRID[e][t].itemType=GRID_MAZE,AGENT_GRID[e][t].itemType=GRID_MAZE;do{e=AB.randomIntAtoB(1,gridsize-2),t=AB.randomIntAtoB(1,gridsize-2)}while(occupied(e,t));ei=e,ej=t;do{e=AB.randomIntAtoB(1,gridsize-2),t=AB.randomIntAtoB(1,gridsize-2)}while(occupied(e,t));ai=e,aj=t},emulateGame=(e,t)=>{dryRunSetup();for(var o=0;o<e;o++){if(dryRunMove(o,t))return{status:"BLOCKED",badsteps:badsteps,goodsteps:goodsteps,steps:o+1}}return{status:"RAN_OUT_OF_STEPS",badsteps:badsteps,goodsteps:goodsteps,steps:e}};function initScene(){if(EMULATE_GAME){let t=0,o=0;for(var e=0;e<EMULATE_GAME_COUNT;e++){const s=emulateGame(EMULATED_GAME_STEPS,SMART_AGENT),{status:i,badsteps:n,goodsteps:r,steps:a}=s;"BLOCKED"===i?o++:t++,console.log(`Game ${e+1}: `,`${i}, bad-steps:${n}, good-steps:${r}, total-steps:${a}`)}console.log(`Total games: ${EMULATE_GAME_COUNT}, pray-blocked:${o}, gamse-draw:${t}`),AB.abortRun=!0}quadrants=createQuadrants(GRID);const t=(e,t,o)=>{const s=new THREE.BoxGeometry(squaresize,BOXHEIGHT,squaresize),i=new THREE.Mesh(s);return i.material=new THREE.MeshBasicMaterial({map:o}),i.position.copy(translate(e,t)),ABWorld.scene.add(i),i};for(e=0;e<gridsize;e++)GRID[e]=[...new Array(gridsize).keys()].map(o=>{const s=0===e||e===gridsize-1||0===o||o===gridsize-1?GRID_WALL:GRID_BLANK;return s===GRID_WALL&&t(e,o,wall_texture),new GridItem(e,o,s)}),AGENT_GRID[e]=[...new Array(gridsize).keys()].map(t=>{return new GridItem(e,t,0===e||e===gridsize-1||0===t||t===gridsize-1?GRID_WALL:GRID_BLANK)});for(e=0;e<gridsize;e++)for(var o=0;o<gridsize;o++){const t=GRID[e][o];t.neighbors=getGirdItemNeighbours(t,GRID);const s=AGENT_GRID[e][o];s.neighbors=getGirdItemNeighbours(s,AGENT_GRID)}for(var s=1;s<=NOBOXES;s++)e=AB.randomIntAtoB(1,gridsize-2),o=AB.randomIntAtoB(1,gridsize-2),GRID[e][o].itemType=GRID_MAZE,AGENT_GRID[e][o].itemType=GRID_MAZE,t(e,o,maze_texture);do{e=AB.randomIntAtoB(1,gridsize-2),o=AB.randomIntAtoB(1,gridsize-2)}while(occupied(e,o));ei=e,ej=o,theenemy=t(e,o,enemy_texture),drawEnemy();do{e=AB.randomIntAtoB(1,gridsize-2),o=AB.randomIntAtoB(1,gridsize-2)}while(occupied(e,o));ai=e,aj=o,theagent=t(e,o,agent_texture),drawAgent();const i=new THREE.ImageUtils.loadTexture("uploads/smythc44/floor.jpg");i.wrapS=i.wrapT=THREE.RepeatWrapping,i.repeat.set(10,10);const n=squaresize*gridsize,r=new THREE.MeshBasicMaterial({map:i,side:THREE.DoubleSide}),a=new THREE.PlaneGeometry(n,n,0,0),d=new THREE.Mesh(a,r),u=squaresize/2*-1;d.position.y=u,d.position.x=u,d.position.z=u,d.rotation.x=Math.PI/2,ABWorld.scene.add(d),ABWorld.scene.background=(new THREE.CubeTextureLoader).load(SKYBOX_ARRAY,function(){ABWorld.render(),AB.removeLoading(),AB.runReady=!0})}function drawEnemy(){theenemy.position.copy(translate(ei,ej)),ABWorld.lookat.copy(theenemy.position)}function drawAgent(){theagent.position.copy(translate(ai,aj)),ABWorld.follow.copy(theagent.position)}const drawTheSphere=(e,t,o)=>{const s=new THREE.MeshBasicMaterial({color:o,transparent:!0,opacity:.5}),i=new THREE.Mesh(new THREE.SphereGeometry(40,32,16),s);return i.position.copy(translate(e,t)),ABWorld.scene.add(i),i},heuristicFunction=(e,t,o,s)=>Math.sqrt(Math.pow(e-o,2)+Math.pow(t-s,2))*(Math.abs(e-o)+Math.abs(t-s)),aStarShortestPathFinder=(e,t,o,s,i,n=!1)=>{e.forEach(e=>{e.forEach(e=>{e.g=0,e.h=0,e.f=0,e.previousGridItem=void 0,e.visited=!1})});const r=(e,t)=>{const o=e.indexOf(t);-1!==o&&e.splice(o,1)},a=e[s][i],d=e[t][o],u=[a],c=[];let A=[];for(;u.length;){let e=0;for(let t=0;t<u.length;t++)u[t].f<u[e].f&&(e=t);const t=u[e];if(t===d){var p=t;for(A.push(p);p.previousGridItem;)A.push(p.previousGridItem),p=p.previousGridItem;A=A.filter(e=>e!==a&&e!==d);break}r(u,t),c.push(t),t.neighbors.forEach(e=>{const{positionX:o,positionY:s}=e,i=!!n&&(o===ei&&s===ej);if(!c.includes(e)&&!e.itemType&&!i){const i=t.g+heuristicFunction(o,s,t.positionX,t.positionY);let n=!1;u.includes(e)?i<e.g&&(e.g=i,n=!0):(e.g=i,n=!0,u.push(e)),n&&(e.h=heuristicFunction(o,s,d.positionX,d.positionY),e.f=e.g+e.h,e.previousGridItem=t)}})}return{closedSet:c,path:A}};let closedSet,path,drawnSelectedNodes=[];function moveLogicalEnemy(e=!1){const{closedSet:t,path:o}=aStarShortestPathFinder(GRID,ai,aj,ei,ej),s=o[o.length-1];if(e||(drawnSelectedNodes.forEach(e=>{ABWorld.scene.remove(e),e.geometry.dispose(),e.material.dispose()}),drawnSelectedNodes=t.map(e=>o.includes(e)?drawTheSphere(e.positionX,e.positionY,16711680):drawTheSphere(e.positionX,e.positionY,65280))),s){const{positionX:e,positionY:t}=s;ei=e,ej=t}}const quadrantMidlePoint=(e,t,o,s)=>{return{x:Math.floor((e+t)/2),y:Math.floor((o+s)/2)}},checkMidPointAndAdjust=({x:e,y:t},o)=>{if(!o[e][t].itemType)return{x:e,y:t};const s=QUADRANT_DIVISION,i=o.length,n=i-e>0?e:e+i-e,r=i-t>0?t:t+i-t;for(let e=0;e<s;e++)for(let t=0;t<s;t++){const s=e+n,i=t+r,a=o[s][i];if(a&&!a.itemType)return{x:s,y:i}}},calculateDestenationPath=(e,t,o,s,i,n)=>{const r=i.map(i=>{const{xEnd:r,xStart:a,yEnd:d,yStart:u}=i;let c=quadrantMidlePoint(r,a,d,u);c=checkMidPointAndAdjust(c,n);const{path:A}=aStarShortestPathFinder(n,c.x,c.y,e,t,!0);let p=1e5;A.forEach(e=>{const{positionX:t,positionY:i}=e,n=heuristicFunction(t,i,o,s);p>n&&(p=n)});const l=heuristicFunction(c.x,c.y,o,s)/1e3,g=p/100*2,E=l+g;return{quadrant:i,calculatedClosestDistanceOnPath:g,distanceToTheEnemy:l,heuristics:A.length<1?-1:E,path:A}}).sort((e,t)=>e.heuristics>t.heuristics?1:t.heuristics>e.heuristics?-1:0);return r[r.length-1].path},getAgentPath=(e,t,o,s,i,n)=>calculateDestenationPath(e,t,o,s,i,n);let drawnSelectedNodesAgent=[];function moveLogicalAgent(e,t=!1,o=!0){var s=ai,i=aj;if(!o)return e==ACTION_LEFT?s--:e==ACTION_RIGHT?s++:e==ACTION_UP?i++:e==ACTION_DOWN&&i--,void(occupied(s,i)||(ai=s,aj=i));const n=getAgentPath(ai,aj,ei,ej,quadrants,AGENT_GRID);t||(drawnSelectedNodesAgent.forEach(e=>{ABWorld.scene.remove(e),e.geometry.dispose(),e.material.dispose()}),drawnSelectedNodesAgent=n.map(e=>drawTheSphere(e.positionX,e.positionY,16761600)));const r=n[n.length-1];if(r&&1!==n.length){const{positionX:e,positionY:t}=r;ai=e,aj=t}}var OURKEYS=[37,38,39,40];function ourKeys(e){return OURKEYS.includes(e.keyCode)}function keyHandler(e){return!AB.runReady||(!ourKeys(e)||(37==e.keyCode&&moveLogicalAgent(ACTION_LEFT,!1,SMART_AGENT),38==e.keyCode&&moveLogicalAgent(ACTION_DOWN,!1,SMART_AGENT),39==e.keyCode&&moveLogicalAgent(ACTION_RIGHT,!1,SMART_AGENT),40==e.keyCode&&moveLogicalAgent(ACTION_UP,!1,SMART_AGENT),e.stopPropagation(),e.preventDefault(),!1))}function badstep(){return Math.abs(ei-ai)<2&&Math.abs(ej-aj)<2}function agentBlocked(){return occupied(ai-1,aj)&&occupied(ai+1,aj)&&occupied(ai,aj+1)&&occupied(ai,aj-1)}function updateStatusBefore(e){var t=AB.world.getState();AB.msg(" Step: "+AB.step+" &nbsp; x = ("+t.toString()+") &nbsp; a = ("+e+") ")}function updateStatusAfter(){var e=AB.world.getState(),t=goodsteps/AB.step*100;AB.msg(" &nbsp; y = ("+e.toString()+") <br> Bad steps: "+badsteps+" &nbsp; Good steps: "+goodsteps+" &nbsp; Score: "+t.toFixed(2)+"% ",2)}AB.world.newRun=function(){AB.loadingScreen(),AB.runReady=!1,badsteps=0,goodsteps=0,BOXHEIGHT=squaresize,ABWorld.init3d(startRadiusConst,maxRadiusConst,14548957),loadResources(),document.onkeydown=keyHandler},AB.world.getState=function(){return[ai,aj,ei,ej]},AB.world.takeAction=function(e){updateStatusBefore(e),moveLogicalAgent(e,!1,SMART_AGENT),AB.step%2==0&&moveLogicalEnemy(),badstep()?badsteps++:goodsteps++,drawAgent(),drawEnemy(),updateStatusAfter(),agentBlocked()&&(AB.abortRun=!0,goodsteps=0,musicPause(),soundAlarm())},AB.world.endRun=function(){musicPause(),AB.abortRun?AB.msg(" <br> <font color=red> <B> Agent trapped. Final score zero. </B> </font>   ",3):AB.msg(" <br> <font color=green> <B> Run over. </B> </font>   ",3)},AB.world.getScore=function(){var e=goodsteps/AB.maxSteps*100;return Math.round(100*e)/100};const backmusic=AB.backgroundMusic(MUSIC_BACK);function musicPlay(){backmusic.play()}function musicPause(){backmusic.pause()}function soundAlarm(){new Audio(SOUND_ALARM).play()}