diff --git a/src/index.html b/src/index.html
index 2546a6c..81adcff 100644
--- a/src/index.html
+++ b/src/index.html
@@ -20,6 +20,7 @@
+
diff --git a/src/main.js b/src/main.js
index b253951..32cd266 100644
--- a/src/main.js
+++ b/src/main.js
@@ -8,4 +8,6 @@ window.addEventListener('DOMContentLoaded', () => document.fonts.ready.then(() =
const grid = new Grid(gridCanvas);
const agent = new Agent(agentCanvas);
const products = new Products(productsCanvas);
+
+ window.products = products;
}));
\ No newline at end of file
diff --git a/src/modules/agent.js b/src/modules/agent.js
index 3cb730e..75aa379 100644
--- a/src/modules/agent.js
+++ b/src/modules/agent.js
@@ -4,15 +4,22 @@ class Agent extends AgentController {
const cycle = async () => {
- await this.takeFromStore(Product.RANDOM_FROM_REGISTRY(), Math.floor(Math.random() * 40) + 10);
- const randomPlace = Grid.instance.randomPlace();
- await this.deliver(randomPlace.x, randomPlace.y);
+ // await this.takeFromStore(Product.RANDOM_FROM_REGISTRY(), Math.floor(Math.random() * 40) + 10);
+ // const randomPlace = Grid.instance.randomPlace();
+ // await this.deliver(randomPlace.x, randomPlace.y);
+ const jobRequest = window.products.getJobRequest();
+ if (jobRequest) {
+ console.log(jobRequest);
+ const requiredAmount = 50 - jobRequest.amount;
+ await this.takeFromStore(jobRequest.product, requiredAmount);
+ await this.deliver(jobRequest.x, jobRequest.y);
+ }
await waitFor(2000);
cycle();
};
- cycle();
+ setTimeout(() => cycle(), 2000);
}
@@ -32,6 +39,7 @@ class Agent extends AgentController {
*/
async deliver(x, y) {
await this.moveTo(x, y);
+ window.products.exchange(x, y, this.ownedProduct, 50);
this.ownedProductAmount = 0;
this.ownedProduct = Product.REGISTRY.empty;
}
@@ -41,7 +49,8 @@ class Agent extends AgentController {
* @param {*} product
*/
async takeFromStore(product, amount) {
- await this.moveTo(6, 8);
+ await this.moveTo(9, 8);
+ await waitFor(1000);
this.ownedProductAmount = amount;
this.ownedProduct = product;
}
diff --git a/src/modules/agentController.js b/src/modules/agentController.js
index 8502906..d9dd7d6 100644
--- a/src/modules/agentController.js
+++ b/src/modules/agentController.js
@@ -48,10 +48,11 @@ class AgentController {
let nearestPoint = this.currentPath[this.currentPathIndex];
if (nearestPoint) {
- const requiredRotation = this.findRequiredRotation(nearestPoint);
- await this.rotate({ z: requiredRotation });
- if (!nearestPoint.options || !nearestPoint.options.isShelf) {
- await this.moveInLine(nearestPoint);
+ if (nearestPoint.action == PATHFINDING_ACTION.MOVE) {
+ await this.moveInLine(nearestPoint.state.position);
+ }
+ if (nearestPoint.action == PATHFINDING_ACTION.ROTATE) {
+ await this.rotate({ z: nearestPoint.state.rotation });
}
nearestPoint = this.currentPath[++this.currentPathIndex];
@@ -134,9 +135,6 @@ class AgentController {
*/
rotate(rotation) {
return new Promise((resolve, reject) => {
- // console.log(this.rotation); // 270
- // console.log(rotation); // 0
-
if (this.rotation.z == rotation.z) {
resolve();
}
@@ -172,7 +170,6 @@ class AgentController {
moveTo(x, y) {
this.currentPath = this.findPathTo(x, y, this.position.x, this.position.y);
- console.log(this.currentPath);
return this.updateAgentPosition();
}
@@ -181,8 +178,8 @@ class AgentController {
this.ctx.beginPath();
this.ctx.strokeWidth = 5;
this.ctx.strokeStyle = 'red';
- this.ctx.moveTo(path[i].x * 100 + 50, path[i].y * 100 + 50);
- this.ctx.lineTo(path[i + 1].x * 100 + 50, path[i + 1].y * 100 + 50);
+ this.ctx.moveTo(path[i].state.position.x * 100 + 50, path[i].state.position.y * 100 + 50);
+ this.ctx.lineTo(path[i + 1].state.position.x * 100 + 50, path[i + 1].state.position.y * 100 + 50);
this.ctx.stroke();
}
}
@@ -230,44 +227,13 @@ class AgentController {
}
findPathTo(dx, dy, sx, sy) {
- const grid = JSON.parse(JSON.stringify(Grid.instance.grid));
- const queue = [];
- const lastPoint = [];
-
- if (grid[dx][dy] === GRID_FIELD_TYPE.SHELF) {
- if(grid[dx][dy + 1] === GRID_FIELD_TYPE.PATH) {
- lastPoint.push({ x: dx, y: dy, options: { isShelf: true } });
- dy++;
- } else if(grid[dx][dy - 1] === GRID_FIELD_TYPE.PATH) {
- lastPoint.push({ x: dx, y: dy, options: { isShelf: true } });
- dy--;
+ if (Grid.instance.getGrid()[dx][dy] == GRID_FIELD_TYPE.SHELF || Grid.instance.getGrid()[dx][dy] == GRID_FIELD_TYPE.STORAGE) {
+ if (Grid.instance.getGrid()[dx][dy - 1] == GRID_FIELD_TYPE.PATH) {
+ return Pathfinding.search({ position: { x: sx, y: sy }, rotation: this.rotation.z }, { position: { x: dx, y: dy - 1 }, rotation: 180 });
}
+ return Pathfinding.search({ position: { x: sx, y: sy }, rotation: this.rotation.z }, { position: { x: dx, y: dy + 1 }, rotation: 0 });
}
-
- queue.push({ x: sx, y: sy, path: [] });
-
- while(queue.length) {
- const { x, y, path } = queue.shift();
- path.push({ x, y });
-
- if (x === dx && y === dy) {
- return [...path, ...lastPoint];
- }
- if (grid[x][y - 1] === GRID_FIELD_TYPE.PATH) {
- queue.push({ x, y: y - 1, path: [...path] });
- }
- if (grid[x][y + 1] === GRID_FIELD_TYPE.PATH) {
- queue.push({ x, y: y + 1, path: [...path] });
- }
- if (grid[x - 1] && grid[x - 1][y] === GRID_FIELD_TYPE.PATH) {
- queue.push({ x: x - 1, y, path: [...path] });
- }
- if (grid[x + 1] && grid[x + 1][y] === GRID_FIELD_TYPE.PATH) {
- queue.push({ x: x + 1, y, path: [...path] });
- }
-
- grid[x][y] = -1;
- }
+ return Pathfinding.search({ position: { x: sx, y: sy }, rotation: this.rotation.z }, { position: { x: dx, y: dy }, rotation: this.rotation.z });
}
clearCanvas() {
diff --git a/src/modules/pathfinding.js b/src/modules/pathfinding.js
new file mode 100644
index 0000000..2a1f5b1
--- /dev/null
+++ b/src/modules/pathfinding.js
@@ -0,0 +1,100 @@
+/**
+ * @typedef IPosition
+ * @property {number} x
+ * @property {number} y
+ *
+ * @typedef {Object} IState
+ * @property {number} rotation
+ * @property {IPosition} position
+ */
+
+const PATHFINDING_ACTION = {
+ ROTATE: 0,
+ MOVE: 1,
+}
+
+
+class Pathfinding {
+ static search(state, expectedState) {
+ return Pathfinding.graphSearch({ state }, { state: expectedState })
+ }
+
+
+ static graphSearch(node, expectedNode, fringe = [], explored = []) {
+ fringe.push(node);
+
+ while(true) {
+ if (fringe.length == 0) {
+ return false;
+ }
+
+ const elem = fringe.shift();
+
+ if (Pathfinding.reached(elem.state, expectedNode.state)) {
+ return Pathfinding.buildPath(node, elem);
+ }
+
+ explored.push(elem);
+
+ for (const successor of this.successor(elem)) {
+ if (explored.every(n => !Pathfinding.reached(n.state, successor.state))) {
+ fringe.push(successor);
+ }
+ }
+ }
+ }
+
+
+ static successor(node) {
+ const list = [];
+ const grid = Grid.instance.getGrid();
+
+ list.push({
+ state: { ...node.state, rotation: (node.state.rotation + 270) % 360 },
+ action: PATHFINDING_ACTION.ROTATE,
+ parent: node
+ });
+ list.push({
+ state: { ...node.state, rotation: (node.state.rotation + 90) % 360 },
+ action: PATHFINDING_ACTION.ROTATE,
+ parent: node
+ });
+
+ const direction = Pathfinding.getVectorFromRotation(node.state.rotation);
+ const prediction = { x: node.state.position.x + direction.x, y: node.state.position.y + direction.y }
+
+ if (grid[prediction.x] && grid[prediction.x][prediction.y] == GRID_FIELD_TYPE.PATH) {
+ list.push({
+ state: { ...node.state, position: prediction },
+ action: PATHFINDING_ACTION.MOVE,
+ parent: node
+ });
+ }
+
+ return list;
+ }
+
+ static buildPath(node, expectedNode) {
+ const result = [];
+ let currentElement = expectedNode;
+
+ while(!Pathfinding.reached(currentElement.state, node.state)) {
+ result.unshift(currentElement);
+ currentElement = currentElement.parent;
+ }
+ return result;
+ }
+
+ static reached(state, expectedState) {
+ return state.rotation == expectedState.rotation && state.position.x == expectedState.position.x && state.position.y == expectedState.position.y;
+ }
+
+ static getVectorFromRotation(rotation) {
+ switch (rotation) {
+ case 0: return { x: 0, y: -1 };
+ case 90: return { x: 1, y: 0 };
+ case 180: return { x: 0, y: 1 };
+ case 270: return { x: -1, y: 0 };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/modules/products.js b/src/modules/products.js
index 07e18d9..8af2572 100644
--- a/src/modules/products.js
+++ b/src/modules/products.js
@@ -130,6 +130,8 @@ class Products {
const amount = this.gridProductsAmount[x][y]
this.gridProducts[x][y] = incomingProduct
this.gridProductsAmount[x][y] = incomingAmount
+ this.clearCanvas();
+ this.drawProducts();
return { product, amount }
}