psi/src/view/products.js

184 lines
4.9 KiB
JavaScript
Raw Normal View History

function filterReduce2D(array, reducer, filter, init) {
let result = init;
for (let row of array)
for (let element of row)
if (filter(element))
result = reducer(result, element);
return result;
}
2021-03-21 17:51:35 +01:00
class Products {
2021-04-19 11:41:53 +02:00
static instance
2021-03-28 22:54:59 +02:00
constructor(canvas) {
2021-04-19 11:11:22 +02:00
const { random, floor } = Math
2021-03-28 22:54:59 +02:00
2021-04-19 11:11:22 +02:00
this.gridProducts = []
2021-03-28 22:54:59 +02:00
this.gridProductsAmount = []
this.min = 50;
2021-03-28 22:54:59 +02:00
for (let i = 0; i < 20; ++i) {
2021-04-19 11:11:22 +02:00
const gridProductsColumn = []
const gridProductsAmountColumn = []
2021-03-28 22:54:59 +02:00
for (let j = 0; j < 9; ++j) {
2021-04-19 14:39:16 +02:00
if (j % 3 !== 1 && (i+1) % 7 !== 0) {
2021-04-19 11:11:22 +02:00
gridProductsColumn.push(Product.RANDOM_FROM_REGISTRY());
const amount = floor(random() * 51);
gridProductsAmountColumn.push(amount);
this.min = this.min > amount ? amount : this.min;
2021-04-19 11:11:22 +02:00
} else {
gridProductsColumn.push('');
gridProductsAmountColumn.push('');
}
2021-03-28 22:54:59 +02:00
}
2021-04-26 21:37:29 +02:00
2021-04-19 11:11:22 +02:00
this.gridProducts.push(gridProductsColumn);
this.gridProductsAmount.push(gridProductsAmountColumn);
2021-03-28 22:54:59 +02:00
}
2021-03-21 17:51:35 +01:00
this.ctx = canvas.getContext('2d');
this.setCanvasSize(canvas);
this.update();
2021-04-19 11:41:53 +02:00
Products.instance = this
2021-03-21 17:51:35 +01:00
}
setCanvasSize (canvas) {
canvas.width = 2000;
canvas.height = 900;
2021-04-26 21:37:29 +02:00
}
2021-03-21 17:51:35 +01:00
update(){
this.clearCanvas();
this.drawProducts();
}
drawProducts () {
for (let [x, line] of Grid.instance.grid.entries()) {
2021-03-21 17:51:35 +01:00
for (let [y, type] of line.entries()) {
if (type === GRID_FIELD_TYPE.SHELF) {
2021-03-28 22:54:59 +02:00
let v = this.drawValue(x, y);
2021-04-26 21:37:29 +02:00
this.product(x * 100, y * 100, v, x, y);
2021-03-21 17:51:35 +01:00
}
}
}
}
2021-03-28 22:54:59 +02:00
drawValue(x, y) {
2021-03-21 17:51:35 +01:00
let fontSize = 20;
this.ctx.font = `${fontSize}px Montserrat`;
this.ctx.textAlign = "left";
this.ctx.fillStyle = 'white';
2021-03-28 22:54:59 +02:00
let number = this.gridProductsAmount[x][y];
this.ctx.fillText(number, (x * 100) + 10, (y * 100) + 90);
2021-03-21 17:51:35 +01:00
return number;
}
2021-03-28 22:54:59 +02:00
product(x, y, v, productsKey, productsValue) {
2021-03-21 17:51:35 +01:00
let fontSize = 40;
this.ctx.font = `900 ${fontSize}px "Font Awesome 5 Free"`;
2021-03-21 17:51:35 +01:00
this.ctx.textAlign = "center";
2021-04-26 21:37:29 +02:00
2021-04-19 11:11:22 +02:00
// make color of icon on white -> red spectrum, where
// white - full shelf
// red - empty shelf
const t = Math.cbrt
v = (v - this.min) / (50 - this.min);
let color = Math.floor(t(v) * 255).toString(16)
2021-04-19 11:11:22 +02:00
if (color.length == 1)
color = "0" + color
2021-04-26 21:37:29 +02:00
this.ctx.fillStyle = `#ff${color}${color}`;
2021-04-19 11:11:22 +02:00
2021-03-21 17:51:35 +01:00
let productsColumn = this.gridProducts[productsKey];
let prdct = productsColumn[productsValue];
2021-04-19 11:11:22 +02:00
this.ctx.font = '900 40px "Font Awesome 5 Free"';
this.ctx.textAlign = 'center';
this.ctx.fillText(prdct.icon, x+50, y+60);
2021-03-21 17:51:35 +01:00
}
2021-04-26 21:37:29 +02:00
2021-03-21 17:51:35 +01:00
clearCanvas() {
this.ctx.clearRect(0, 0, 2000, 900);
}
2021-04-26 21:37:29 +02:00
2021-03-28 22:54:59 +02:00
getProductAt(x, y) {
return {
item: this.gridProducts[x][y],
count: this.gridProductsAmount[x][y]
}
}
2021-04-19 11:41:53 +02:00
/**
2021-04-26 21:37:29 +02:00
*
* @param {(product: Product, amount: number, i: number, j: number, end: () => bool) => bool} filter
* @returns
2021-04-19 11:41:53 +02:00
*/
filter(filter) {
const list = []
for (let i = 0; i < 20; ++i) {
for (let j = 0; j < 9; ++j) {
let mustEnd = false
let end = (val = false) => (mustEnd = true, val)
const product = this.gridProducts[i][j]
const amount = this.gridProductsAmount[i][j]
2021-04-26 21:37:29 +02:00
if (typeof(product) !== 'string'
2021-04-19 11:41:53 +02:00
&& filter(product, amount, i, j, end)) {
list.push({ product, amount: Number(amount), x: i, y: j })
}
if (mustEnd)
return list
}
}
return list
}
2021-04-19 11:11:22 +02:00
/**
2021-04-26 21:37:29 +02:00
* @param {Product} incomingProduct
* @param {number} incomingAmount
2021-04-19 11:41:53 +02:00
* @returns {{product: Product; amount: number} | null } Old shelf content
2021-04-19 11:11:22 +02:00
*/
exchange(x, y, incomingProduct, incomingAmount) {
const product = this.gridProducts[x][y];
const amount = this.gridProductsAmount[x][y];
this.gridProducts[x][y] = incomingProduct;
this.gridProductsAmount[x][y] = incomingAmount;
this.min = filterReduce2D(this.gridProductsAmount, (p, c) => Math.min(p, c),
x => typeof x === 'number', 50);
2021-04-19 13:30:57 +02:00
this.clearCanvas();
this.drawProducts();
return { product, amount };
}
2021-04-19 11:41:53 +02:00
/**
* @param {Product} incomingProduct
* @param {number} incomingAmount
* @returns {{product: Product; amount: number} | null } Old shelf content or leftover
*/
interact(x, y, incomingProduct, incomingAmount) {
const { max, min } = Math
const amount = this.gridProductsAmount[x][y]
if (this.gridProducts[x][y].equals(incomingProduct) && amount < 50) {
this.gridProductsAmount[x][y] = min(incomingAmount, 50)
return { product: incomingProduct, amount: max(0, (amount + incomingAmount) - 50) }
}
return this.exchange(x, y, incomingProduct, incomingAmount)
}
getJobRequest() {
2021-04-26 21:37:29 +02:00
const maybeProduct = this.filter((_product, amount, _i, _j, end) => amount < 50).sort((a, b) => {
return a.amount - b.amount
})
2021-04-19 11:41:53 +02:00
return maybeProduct.length === 0 ? null : maybeProduct[0]
}
findAvailableLocationsFor(product) {
return this.filter((p, amount) => product.equals(p) && amount < 50)
}
2021-04-26 21:37:29 +02:00
}