AB.clockTick = 100, AB.maxSteps = 1e3, AB.screenshotStep = 50;
const show3d = !0,
TEXTURE_AGENT = "/uploads/drummk2/Laurie_Strode.jpg",
TEXTURE_ENEMY = "/uploads/drummk2/Michael_Myers.jpg",
TEXTURE_MAZE = "/uploads/starter/latin.jpg",
TEXTURE_PATH = "/uploads/drummk2/Pool_Of_Blood.jpg",
TEXTURE_WALL = "/uploads/drummk2/Dark_Brick_Wall.jpg",
MUSIC_BACK = "/uploads/drummk2/Creepy.mp3",
SOUND_ALARM = "/uploads/starter/air.horn.mp3",
gridsize = 50,
NOBOXES = Math.trunc(gridsize * gridsize / 8),
squaresize = 100,
MAXPOS = gridsize * squaresize,
SKYCOLOR = 14548957,
startRadiusConst = .8 * MAXPOS,
maxRadiusConst = 10 * MAXPOS,
wallCutOff = AB.randomFloatAtoB(0, .6);
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"];
function Square(e, t, i, n) {
this.uniqueId, this.i = e, this.j = t, this.f = 0, this.g = 0, this.h = 0, this.neighbors = [], this.previous = void 0, this.squareType = i, this.isWall = n, this.show = function() {
shape = new THREE.BoxGeometry(squaresize, BOXHEIGHT, squaresize), thecube = new THREE.Mesh(shape), this.squareType == GRID_WALL ? thecube.material = new THREE.MeshBasicMaterial({
map: wall_texture
}) : this.squareType == GRID_MAZE && (thecube.material = new THREE.MeshBasicMaterial({
map: maze_texture
})), thecube.position.copy(translate(this.i, this.j)), ABWorld.scene.add(thecube)
}, this.highlight = function(e) {
if (e) shape = new THREE.BoxGeometry(squaresize, .001, squaresize), thecube = new THREE.Mesh(shape), thecube.material = new THREE.MeshBasicMaterial({
map: path_texture
}), thecube.position.copy(translate(this.i, this.j)), ABWorld.scene.add(thecube), this.uniqueId = thecube.uuid;
else {
var t = ABWorld.scene.getObjectByProperty("uuid", this.uniqueId);
ABWorld.scene.remove(t), this.uniqueId = null
}
}, this.addNeighbors = function(e) {
this.i < gridsize - 1 && this.neighbors.push(e[this.i + 1][this.j]), this.i > 0 && this.neighbors.push(e[this.i - 1][this.j]), this.j < gridsize - 1 && this.neighbors.push(e[this.i][this.j + 1]), this.j > 0 && this.neighbors.push(e[this.i][this.j - 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, theagent, theenemy, wall_texture, agent_texture, enemy_texture, maze_texture, path_texture, ei, ej, ai, aj, badsteps, goodsteps, GRID = new Array(gridsize),
closedSet = [],
openSet = [],
path = [];
function loadResources() {
var e = new THREE.TextureLoader,
t = new THREE.TextureLoader,
i = new THREE.TextureLoader,
n = 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()
}), i.load(TEXTURE_ENEMY, function(e) {
e.minFilter = THREE.LinearFilter, enemy_texture = e, asynchFinished() && initScene()
}), n.load(TEXTURE_MAZE, function(e) {
e.minFilter = THREE.LinearFilter, maze_texture = e, asynchFinished() && initScene()
}), s.load(TEXTURE_PATH, function(e) {
e.minFilter = THREE.LinearFilter, path_texture = e, asynchFinished() && initScene()
})
}
function asynchFinished() {
return wall_texture && agent_texture && enemy_texture && maze_texture && path_texture
}
function occupied(e, t) {
return ei === e && ej === t || (ai === e && aj === t || (GRID[e][t].squareType === GRID_WALL || GRID[e][t].squareType === GRID_MAZE))
}
function translate(e, t) {
var i = new THREE.Vector3;
return i.y = 0, i.x = e * squaresize - MAXPOS / 2, i.z = t * squaresize - MAXPOS / 2, i
}
function initScene() {
var e, t, i;
for (e = 0; e < gridsize; e++) GRID[e] = new Array(gridsize);
for (e = 0; e < gridsize; e++)
for (t = 0; t < gridsize; t++) 0 === e || e === gridsize - 1 || 0 === t || t === gridsize - 1 ? (GRID[e][t] = new Square(e, t, GRID_WALL, !0), GRID[e][t].show()) : GRID[e][t] = new Square(e, t, GRID_BLANK, !1);
for (var n = 1; n <= NOBOXES; n++) e = AB.randomIntAtoB(1, gridsize - 2), t = AB.randomIntAtoB(1, gridsize - 2), GRID[e][t] = new Square(e, t, GRID_MAZE, !0), GRID[e][t].show();
for (e = 0; e < gridsize; e++)
for (t = 0; t < gridsize; t++) GRID[e][t].addNeighbors(GRID);
do {
e = AB.randomIntAtoB(1, gridsize - 2), t = AB.randomIntAtoB(1, gridsize - 2)
} while (occupied(e, t));
ei = e, ej = t, i = new THREE.BoxGeometry(squaresize, BOXHEIGHT, squaresize), (theenemy = new THREE.Mesh(i)).material = new THREE.MeshBasicMaterial({
map: enemy_texture
}), ABWorld.scene.add(theenemy), drawEnemy();
do {
e = AB.randomIntAtoB(1, gridsize - 2), t = AB.randomIntAtoB(1, gridsize - 2)
} while (occupied(e, t));
ai = e, aj = t, i = new THREE.BoxGeometry(squaresize, BOXHEIGHT, squaresize), (theagent = new THREE.Mesh(i)).material = new THREE.MeshBasicMaterial({
map: agent_texture
}), ABWorld.scene.add(theagent), drawAgent(), 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)
}
function heuristic(e, t) {
return Math.abs(e.i - t.i) + Math.abs(e.j - t.j)
}
function determineNextStep() {
console.log("Determining the ideal move from (" + ei + ", " + ej + ").");
for (const e of path) e.highlight(!1);
closedSet.splice(0, closedSet.length), openSet.splice(0, openSet.length), path.splice(0, path.length);
var e = GRID[ei][ej];
for (openSet.push(e); openSet.length > 0;) {
for (var t = 0, i = 0; i < openSet.length; i++) openSet[i].f < openSet[t].f && (t = i);
var n = openSet[t],
s = GRID[ai][aj];
if (n === s) {
for (var a = n; a.previous !== e;) a.highlight(!0), path.push(a), a = a.previous;
return console.log("Search complete - moving to (" + a.i + ", " + a.j + ")."), a
}
openSet.splice(openSet.indexOf(n), 1), closedSet.push(n);
var r = n.neighbors;
for (i = 0; i < r.length; i++) {
var o = r[i];
if (!closedSet.includes(o) && !o.isWall) {
var u = n.g + heuristic(o, n),
d = !1;
openSet.includes(o) ? u < o.g && (o.g = u, d = !0) : (o.g = u, d = !0, openSet.push(o)), d && (o.h = heuristic(o, s), o.f = o.g + o.h, o.previous = n)
}
}
}
}
function moveLogicalEnemy() {
var e = determineNextStep();
occupied(e.i, e.j) || (ei = e.i, ej = e.j)
}
function moveLogicalAgent(e) {
var t = ai,
i = aj;
e == ACTION_LEFT ? t-- : e == ACTION_RIGHT ? t++ : e == ACTION_UP ? i++ : e == ACTION_DOWN && i--, occupied(t, i) || (ai = t, aj = i)
}
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), 38 == e.keyCode && moveLogicalAgent(ACTION_DOWN), 39 == e.keyCode && moveLogicalAgent(ACTION_RIGHT), 40 == e.keyCode && moveLogicalAgent(ACTION_UP), 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 + " x = (" + t.toString() + ") a = (" + e + ") ")
}
function updateStatusAfter() {
var e = AB.world.getState(),
t = goodsteps / AB.step * 100;
AB.msg(" y = (" + e.toString() + ") <br> Bad steps: " + badsteps + " Good steps: " + goodsteps + " 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), 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.msg(AB.abortRun ? "<br> <font color=red> <B> Agent trapped. Final score zero. </B> </font>" : "<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
};
var backmusic = AB.backgroundMusic(MUSIC_BACK);
function musicPlay() {
backmusic.play()
}
function musicPause() {
backmusic.pause()
}
function soundAlarm() {
new Audio(SOUND_ALARM).play()
}