szdytom 94cd28d403 add playback progress bar
Signed-off-by: szdytom <szdytom@qq.com>
2024-01-20 16:16:26 +08:00

139 lines
3.5 KiB
JavaScript

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);
});
});