import { Vec2 } from './vec2.js'; import { N, SQR_TYPE, Maze, AnalyzeContext, State } from './pushbox.js'; class BoardSquare { constructor(attach_element) { this.e = attach_element ?? document.createElement('div'); this.e.classList.add('fixtl', 'maze-sqr'); this.e.style.top = '0'; this.e.style.left = '0'; this.type = null; } moveTo(x, y) { this.e.style.top = `${4 * x}vh`; this.e.style.left = `${4 * y}vh`; return this; } moveToV(v) { return this.moveTo(v.x, v.y); } setType(type) { if (this.type) { this.e.classList.remove(`sqr-${this.type}`); } this.type = type; this.e.classList.add(`sqr-${this.type}`); return this; } }; class BoardUI { constructor() { this.maze = document.getElementById('maze'); this.target = new BoardSquare(document.getElementById('target')); this.box = new BoardSquare(document.getElementById('box')); this.player = new BoardSquare(document.getElementById('player')); this.squares = []; } drawMaze(maze) { while (this.maze.hasChildNodes()) { this.maze.removeChild(this.maze.lastChild); } this.squares = []; for (let i = 0; i < N; ++i) { for (let j = 0; j < N; ++j) { let sqr = new BoardSquare(); sqr.moveTo(i, j); if (maze.get(i, j) == SQR_TYPE.WALL) { sqr.setType('wall'); } else { sqr.setType('space'); } this.maze.appendChild(sqr.e); } } this.target.moveToV(maze.target); } updateState(state) { this.player.moveToV(state.player); this.box.moveToV(state.box); } }; document.addEventListener('DOMContentLoaded', () => { const charmap_input = document.getElementById('maze_charmap'); const analyze_button = document.getElementById('analyze'); const analyze_status_element = document.getElementById('analyze-status'); let board = new BoardUI(); let maze = null, analyze_res = null; let current_worker = null; function resetAnalyze() { document.getElementById('analyze-status').innerHTML = 'Not Analyzed'; document.getElementById('analyze-steps').innerHTML = 'N/A'; analyze_res = null; } function importMaze(charmap_val) { let charmp = charmap_val.split('\n').map(x => x.trimEnd()); maze = Maze.fromCharMap(charmp); board.drawMaze(maze); board.updateState(maze.init); analyze_button.disabled = false; resetAnalyze(); } if (localStorage.getItem('charmap-cache') != null) { charmap_input.value = localStorage.getItem('charmap-cache'); importMaze(charmap_input.value); } else { analyze_button.disabled = true; } document.getElementById('charmap_import').addEventListener('click', function() { localStorage.setItem('charmap-cache', charmap_input.value); importMaze(charmap_input.value); }); analyze_button.addEventListener('click', function() { resetAnalyze(); if (current_worker != null) { current_worker.terminate(); current_worker = null; analyze_button.innerHTML = 'Analyze'; return; } if (maze == null) { return; } current_worker = new Worker('solver.js?v=7', { type: 'module' }); analyze_status_element.innerHTML = 'Dispatching'; analyze_button.innerHTML = 'Stop'; current_worker.onmessage = (msg_r) => { let msg = msg_r.data; if (msg.what === 'started') { analyze_status_element.innerHTML = 'Running'; } else if (msg.what == 'done') { analyze_res = msg.value; console.log(analyze_res); analyze_status_element.innerHTML = 'Done'; document.getElementById('analyze-steps').innerHTML = analyze_res.step.toString(); current_worker.terminate(); current_worker = null; analyze_button.innerHTML = 'Analyze'; } }; current_worker.postMessage(maze); }); });