improvements
This commit is contained in:
parent
5b1584e300
commit
47597143fb
7 changed files with 147 additions and 104 deletions
|
|
@ -99,7 +99,6 @@ public class OptimalPathFinder {
|
||||||
paths.add(newPath);
|
paths.add(newPath);
|
||||||
takenPaths.add(newPath);
|
takenPaths.add(newPath);
|
||||||
pointsAdded = true;
|
pointsAdded = true;
|
||||||
// System.out.println("add " + newPath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
body {
|
body {
|
||||||
background-color: green;
|
background-color: black;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
|
|
@ -12,16 +13,25 @@ canvas {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
color: greenyellow;
|
color: greenyellow;
|
||||||
background: black;
|
background: black;
|
||||||
position: absolute;
|
position: fixed;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 20%;
|
width: 20%;
|
||||||
height: 10em;
|
height: 12em;
|
||||||
border: 2px solid darkgray;
|
border: 2px solid darkgray;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#slider {
|
||||||
|
position: absolute;
|
||||||
|
left: calc(50% - 1.5em);
|
||||||
|
top: -.2em;
|
||||||
|
color: lightgray;
|
||||||
|
cursor: row-resize;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
#prompt {
|
#prompt {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
@ -40,9 +50,9 @@ canvas {
|
||||||
#command_history {
|
#command_history {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: greenyellow;
|
color: greenyellow;
|
||||||
position: absolute;
|
position: fixed;
|
||||||
bottom: 1.5em;
|
bottom: 1.5em;
|
||||||
max-height: 20em;
|
max-height: 11em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-y: visible;
|
overflow-y: visible;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,10 @@
|
||||||
<link rel="stylesheet" href="css/style.css">
|
<link rel="stylesheet" href="css/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="myCanvas" width="500px" height="500px"></canvas>
|
<canvas id="gridCanvas" width="1000px" height="1000px"></canvas>
|
||||||
|
|
||||||
<div id="console">
|
<div id="console">
|
||||||
|
<!-- <div id="slider">⩵</div>-->
|
||||||
<div id="command_history">
|
<div id="command_history">
|
||||||
<div id="bottom"></div>
|
<div id="bottom"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -18,7 +19,5 @@
|
||||||
|
|
||||||
<script src="js/grid.js"></script>
|
<script src="js/grid.js"></script>
|
||||||
<script src="js/console.js"></script>
|
<script src="js/console.js"></script>
|
||||||
<script src="js/scanner.js"></script>
|
|
||||||
<script src="js/parser.js"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
@ -3,14 +3,86 @@ const command_history_element = document.getElementById('command_history');
|
||||||
let command_history = [''];
|
let command_history = [''];
|
||||||
let command_history_index = 0;
|
let command_history_index = 0;
|
||||||
let token_index = 0;
|
let token_index = 0;
|
||||||
const bindings = {};
|
const bindings = {
|
||||||
const state = {};
|
"N": {
|
||||||
|
is_binding: true,
|
||||||
|
name: "N",
|
||||||
|
},
|
||||||
|
"t": {
|
||||||
|
is_binding: true,
|
||||||
|
name: "t",
|
||||||
|
},
|
||||||
|
"T": {
|
||||||
|
is_binding: true,
|
||||||
|
name: "T",
|
||||||
|
},
|
||||||
|
"x": {
|
||||||
|
is_binding: true,
|
||||||
|
name: "x",
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
is_binding: true,
|
||||||
|
name: "y",
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
is_binding: true,
|
||||||
|
name: "color",
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
const state = {
|
||||||
|
"N": 100,
|
||||||
|
"t": 50,
|
||||||
|
"T": 1000,
|
||||||
|
"x": 50,
|
||||||
|
"y": 50,
|
||||||
|
color: "red",
|
||||||
|
};
|
||||||
|
// const slider = document.getElementById('slider');
|
||||||
|
const console_element = document.getElementById('console');
|
||||||
|
let slider_start_Y, slider_start_height;
|
||||||
|
clear();
|
||||||
|
|
||||||
|
const fly = function () {
|
||||||
|
let N = state['N'];
|
||||||
|
let t = state['t'];
|
||||||
|
let T = state['T'];
|
||||||
|
let x = state['x'];
|
||||||
|
let y = state['y'];
|
||||||
|
|
||||||
|
fetch(`/api/path/${N}/${t}/${T}/${x}/${y}`, {
|
||||||
|
method: 'GET'
|
||||||
|
}).then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json();
|
||||||
|
} else {
|
||||||
|
throw new Error('Server response wasn\'t OK');
|
||||||
|
}
|
||||||
|
}).then(path => {
|
||||||
|
const canvasElement = document.getElementById("gridCanvas");
|
||||||
|
const canvas = canvasElement.getContext('2d');
|
||||||
|
const factor = 1000 / N;
|
||||||
|
canvas.beginPath();
|
||||||
|
canvas.moveTo(7 + path.points[0].x * factor, 2 + path.points[0].y * factor);
|
||||||
|
for (let i = 1; i < path.points.length; i++) {
|
||||||
|
canvas.lineTo(8 + path.points[i].x * factor, 5 + path.points[i].y * factor);
|
||||||
|
}
|
||||||
|
canvas.strokeStyle = state['color'];
|
||||||
|
canvas.stroke();
|
||||||
|
command_history_element.innerText += `${path.value}\n`;
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log('Fetching failed', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const keywords = {
|
const keywords = {
|
||||||
'true': true,
|
'true': true,
|
||||||
'false': false,
|
'false': false,
|
||||||
'pi': Math.PI,
|
'pi': Math.PI,
|
||||||
'PI': Math.PI,
|
'PI': Math.PI,
|
||||||
'e': Math.E
|
'e': Math.E,
|
||||||
|
'fly': fly,
|
||||||
|
'clear': clear,
|
||||||
}
|
}
|
||||||
|
|
||||||
let tokens;
|
let tokens;
|
||||||
|
|
@ -25,12 +97,6 @@ const adjust_input_element_height = function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// command_input_element.onkeypress = function handle_key_input(event) {
|
|
||||||
// if (event.key === 'Enter') {
|
|
||||||
// event.preventDefault();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
command_input_element.onkeyup = function handle_key_input(event) {
|
command_input_element.onkeyup = function handle_key_input(event) {
|
||||||
adjust_input_element_height();
|
adjust_input_element_height();
|
||||||
if (event.key === 'c' && event.ctrlKey) {
|
if (event.key === 'c' && event.ctrlKey) {
|
||||||
|
|
@ -63,7 +129,7 @@ const handle_enter = function () {
|
||||||
adjust_input_element_height();
|
adjust_input_element_height();
|
||||||
|
|
||||||
if (command.length > 0) {
|
if (command.length > 0) {
|
||||||
command_history_element.innerText += command + "\n";
|
command_history_element.innerText += `>${command}\n`;
|
||||||
command_input_element.value = '';
|
command_input_element.value = '';
|
||||||
command_history_index = command_history.length;
|
command_history_index = command_history.length;
|
||||||
|
|
||||||
|
|
@ -72,23 +138,14 @@ const handle_enter = function () {
|
||||||
let value = evaluate(statement);
|
let value = evaluate(statement);
|
||||||
|
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
let binding;
|
if (typeof value === 'function') {
|
||||||
if (value.is_binding) { // if it's declaration work with the initializer
|
value.apply();
|
||||||
binding = value.name; // but we also need the name of the bound variable
|
} else {
|
||||||
value = state[value.name]; // lookup the value for the binding
|
if (value.is_binding) {
|
||||||
|
value = state[value.name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (value.is_visual) {
|
|
||||||
//
|
|
||||||
// } else {
|
|
||||||
// if (binding && bindings[binding].previous && bindings[binding].previous.is_visual) {
|
|
||||||
// label(bindings[binding].previous, '@' + bindings[binding].previous.id);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (value.description) {
|
|
||||||
// value = value.description;
|
|
||||||
// }
|
|
||||||
command_history_element.innerText += value.toString() + "\n";
|
command_history_element.innerText += value.toString() + "\n";
|
||||||
|
}
|
||||||
command_history.push(command);
|
command_history.push(command);
|
||||||
command_history_element.scrollTo(0, command_history_element.scrollHeight);
|
command_history_element.scrollTo(0, command_history_element.scrollHeight);
|
||||||
}
|
}
|
||||||
|
|
@ -138,6 +195,8 @@ const evaluate = function (expr) {
|
||||||
return logical_and(evaluate(expr.left), evaluate(expr.right));
|
return logical_and(evaluate(expr.left), evaluate(expr.right));
|
||||||
case token_types.OR:
|
case token_types.OR:
|
||||||
return logical_or(evaluate(expr.left), evaluate(expr.right));
|
return logical_or(evaluate(expr.left), evaluate(expr.right));
|
||||||
|
case token_types.CIRCUMFLEX:
|
||||||
|
return power(evaluate(expr.left), evaluate(expr.right));
|
||||||
}
|
}
|
||||||
throw {message: 'illegal binary operator'};
|
throw {message: 'illegal binary operator'};
|
||||||
}
|
}
|
||||||
|
|
@ -211,7 +270,7 @@ function add_sub() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function mult_div() {
|
function mult_div() {
|
||||||
let expr = unary();
|
let expr = pow();
|
||||||
|
|
||||||
while (match([token_types.AND, token_types.SLASH, token_types.STAR, token_types.DOT])) {
|
while (match([token_types.AND, token_types.SLASH, token_types.STAR, token_types.DOT])) {
|
||||||
let operator = previous_token();
|
let operator = previous_token();
|
||||||
|
|
@ -222,6 +281,17 @@ function mult_div() {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pow() {
|
||||||
|
let expr = unary();
|
||||||
|
|
||||||
|
if (match([token_types.CIRCUMFLEX])) {
|
||||||
|
let operator = previous_token();
|
||||||
|
let right = unary();
|
||||||
|
expr = {type: 'binary', left: expr, operator: operator, right: right};
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
function unary() {
|
function unary() {
|
||||||
if (match([token_types.NOT, token_types.MINUS])) {
|
if (match([token_types.NOT, token_types.MINUS])) {
|
||||||
let operator = previous_token();
|
let operator = previous_token();
|
||||||
|
|
@ -376,6 +446,8 @@ const scan = function (command) {
|
||||||
return token_types.STAR;
|
return token_types.STAR;
|
||||||
case '/':
|
case '/':
|
||||||
return token_types.SLASH;
|
return token_types.SLASH;
|
||||||
|
case '^':
|
||||||
|
return token_types.CIRCUMFLEX;
|
||||||
case '>':
|
case '>':
|
||||||
if (expect('=')) {
|
if (expect('=')) {
|
||||||
return token_types.GREATER_OR_EQUAL;
|
return token_types.GREATER_OR_EQUAL;
|
||||||
|
|
@ -460,13 +532,6 @@ const scan = function (command) {
|
||||||
return is_digit(char) || char === '.'; // no scientific notation for now
|
return is_digit(char) || char === '.'; // no scientific notation for now
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_reference() {
|
|
||||||
while (current_char() === '@' || is_digit(current_char())) {
|
|
||||||
advance();
|
|
||||||
}
|
|
||||||
return command.substring(word_start_index, current_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_number() {
|
function parse_number() {
|
||||||
while (is_part_of_number(current_char())) {
|
while (is_part_of_number(current_char())) {
|
||||||
advance();
|
advance();
|
||||||
|
|
@ -516,6 +581,7 @@ const token_types = {
|
||||||
PLUS: {type: 'plus'},
|
PLUS: {type: 'plus'},
|
||||||
STAR: {type: 'star'},
|
STAR: {type: 'star'},
|
||||||
SLASH: {type: 'slash'},
|
SLASH: {type: 'slash'},
|
||||||
|
CIRCUMFLEX: {type: 'circonflex'},
|
||||||
EQUALS: {type: 'equals'},
|
EQUALS: {type: 'equals'},
|
||||||
EQUALS_EQUALS: {type: 'equals_equals'},
|
EQUALS_EQUALS: {type: 'equals_equals'},
|
||||||
NOT_EQUALS: {type: 'not_equals'},
|
NOT_EQUALS: {type: 'not_equals'},
|
||||||
|
|
@ -563,34 +629,6 @@ const logical_or = function (left, right) {
|
||||||
return left || right;
|
return left || right;
|
||||||
}
|
}
|
||||||
|
|
||||||
const create_2d_id_matrix = function () {
|
const power = function (left, right) {
|
||||||
return {
|
return Math.pow(left, right);
|
||||||
data: [[1, 0], [0, 1]],
|
|
||||||
id: index_sequence++,
|
|
||||||
is_visual: true,
|
|
||||||
is_vector: false, // for type comparison
|
|
||||||
is_matrix: true,
|
|
||||||
type: 'matrix', // for showing type to user
|
|
||||||
is_new: true, // to determine view action
|
|
||||||
visible: true,
|
|
||||||
toString: function () {
|
|
||||||
return `matrix@${this.id}`;
|
|
||||||
},
|
|
||||||
hide: function () {
|
|
||||||
return hide(this);
|
|
||||||
},
|
|
||||||
label: function (text) {
|
|
||||||
return label(this, text);
|
|
||||||
},
|
|
||||||
show: function () {
|
|
||||||
return show(this);
|
|
||||||
},
|
|
||||||
equals: function (other) {
|
|
||||||
return (this.id === other.id || (this.type === other.type && this.data === other.data)); // TODO
|
|
||||||
},
|
|
||||||
row: function (index) {
|
|
||||||
return this.data[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,32 +1,29 @@
|
||||||
let canvas = document.getElementById('myCanvas');
|
let canvasElement = document.getElementById('gridCanvas');
|
||||||
let ctx;
|
let canvas = canvasElement.getContext('2d');
|
||||||
if (canvas.getContext) {
|
|
||||||
ctx = canvas.getContext('2d');
|
|
||||||
|
|
||||||
// draw here
|
function clear() {
|
||||||
ctx.fillStyle = 'green';
|
canvas.fillStyle = 'black';
|
||||||
ctx.fillRect(0, 0, 500, 500);
|
canvas.fillRect(0, 0, 1000, 1000);
|
||||||
} else {
|
|
||||||
console.log("Canvas not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch('/api/grid/100', {
|
fetch('/api/grid/100', {
|
||||||
method: 'GET' // or 'POST'
|
method: 'GET'
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
return response.json(); // Here we're using JSON but you can use other formats such as blob, text etc.
|
return response.json();
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Server response wasn\'t OK');
|
throw new Error('Server response wasn\'t OK');
|
||||||
}
|
}
|
||||||
}).then((grid) => {
|
}).then((grid) => {
|
||||||
const cell_factor = 500 / grid.size;
|
const cell_factor = 1000 / grid.size;
|
||||||
ctx.font = `5px Arial`;
|
canvas.font = `8px Arial`;
|
||||||
ctx.fillStyle = "grey"
|
canvas.strokeStyle = "green"
|
||||||
|
canvas.strokeWidth = 1;
|
||||||
for (let r = 0; r < grid.size; r++) {
|
for (let r = 0; r < grid.size; r++) {
|
||||||
for (let c = 0; c < grid.size; c++) {
|
for (let c = 0; c < grid.size; c++) {
|
||||||
ctx.fillText("" + grid.grid[r][c], 5 + c * cell_factor, r * cell_factor);
|
canvas.strokeText("" + grid.grid[r][c], 5 + c * cell_factor, 8 + r * cell_factor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log('Fetching failed', err);
|
console.log('Fetching failed', err);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@ public class PathFinderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testBestPath100() {
|
public void testBestPath100() {
|
||||||
Grid grid = Grid.fromFile("grids/100.txt");
|
Grid grid = Grid.fromFile("grids/100.txt");
|
||||||
Path path = new OptimalPathFinder().findOptimalPath(grid, 100, 8, 10000, 50, 50);
|
Path path = new OptimalPathFinder().findOptimalPath(grid, 100, 10, 100, 50, 50);
|
||||||
System.out.println(path);
|
System.out.println(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue