Merge pull request #4 from Solitai7e/master

node algo refactor attempt
This commit is contained in:
ad 2021-01-31 18:57:26 +04:00 committed by GitHub
commit 9b6e2775cc
3 changed files with 165 additions and 327 deletions

View file

@ -1,10 +1,5 @@
import nodeSelector, { getNode, getNodeById, getNodeHud } from "./nodeSelector"; import nodeSelector, { getNode, getNodeById, getNodeHud } from "./nodeSelector";
import { import { findNode } from "./utils/nodeUtils";
findNodeDown,
findNodeLeft,
findNodeRight,
findNodeUp,
} from "./utils/nodeUtils";
const handleMainSceneEvent = (gameContext: any) => { const handleMainSceneEvent = (gameContext: any) => {
let event; let event;
@ -34,18 +29,17 @@ const handleMainSceneEvent = (gameContext: any) => {
case "RIGHT": case "RIGHT":
const keyPressToLower = keyPress.toLowerCase(); const keyPressToLower = keyPress.toLowerCase();
const fn = keyPressToLower === "left" ? findNodeLeft : findNodeRight; const nodeData = findNode.apply(null, [
keyPressToLower,
const nodeData = fn.apply(null, [
nodeMatrixIndices, nodeMatrixIndices,
level, level,
currentSite, currentSite,
gameProgress, gameProgress
]); ]);
if (nodeData) { if (nodeData) {
return { return {
event: nodeData.didRotate event: nodeData.didMove
? `site_${keyPressToLower}` ? `site_${keyPressToLower}`
: "change_node", : "change_node",
siteRotY: siteRotY:
@ -60,12 +54,12 @@ const handleMainSceneEvent = (gameContext: any) => {
case "UP": case "UP":
case "DOWN": case "DOWN":
const keyp = keyPress.toLowerCase(); const keyp = keyPress.toLowerCase();
const tt = keyp === "up" ? findNodeUp : findNodeDown; const t = findNode.apply(null, [
const t = tt.apply(null, [ keyp,
nodeMatrixIndices, nodeMatrixIndices,
level, level,
currentSite, currentSite,
gameProgress, gameProgress
]); ]);
if (t) { if (t) {
return { return {

View file

@ -10,8 +10,7 @@ import level_y_values from "../resources/level_y_values.json";
import node_huds from "../resources/node_huds.json"; import node_huds from "../resources/node_huds.json";
import filterInvisibleNodes from "./utils/filterInvisibleNodes"; import filterInvisibleNodes from "./utils/filterInvisibleNodes";
import { import {
findNodeLeft, findNode,
findNodeRight,
getVisibleNodesMatrix, getVisibleNodesMatrix,
} from "./utils/nodeUtils"; } from "./utils/nodeUtils";
@ -389,20 +388,13 @@ const nodeSelector = (context: NodeSelectorContext) => {
switch (context.action) { switch (context.action) {
case "site_left": case "site_left":
case "site_right": case "site_right":
const t = const t = findNode(
context.action === "site_right" context.action === "site_right" ? "right" : "left",
? findNodeRight( context.nodeMatrixIndices,
context.nodeMatrixIndices, context.level,
context.level, context.currentSite,
context.currentSite, context.gameProgress
context.gameProgress );
)
: findNodeLeft(
context.nodeMatrixIndices,
context.level,
context.currentSite,
context.gameProgress
);
move = context.action === "site_left" ? "left" : "right"; move = context.action === "site_left" ? "left" : "right";
newNodeData = findNodeHorizontal( newNodeData = findNodeHorizontal(

View file

@ -42,324 +42,176 @@ export const getVisibleNodesMatrix = (
); );
}; };
const generateRowPrecedence = (rowIdx: number) => { function reorder<T>(array: T[], order: number[]): T[]
switch (rowIdx) { {
case 0: return order.map(i => array[i]);
return [0, 1, 2]; }
case 1:
return [1, 0, 2]; function RowPrecedence(rowIdx: number): number[]
case 2: {
return [2, 1, 0]; switch (rowIdx) {
default: default: case 0: return [0, 1, 2];
return [0, 1, 2]; case 1: return [1, 0, 2];
} case 2: return [2, 1, 0];
}
}; };
export const findNodeLeft = ( function ColPrecedence(colIdx: number): number[]
nodeMatrixIndices: { {
switch (colIdx) {
default: case 0: return [0, 1, 2, 3];
case 1: return [1, 0, 2, 3];
case 2: return [2, 1, 3, 0];
case 3: return [3, 2, 1, 0];
}
}
function getNodesMatrixWithIndices
(
matrixIdx: number,
activeLevel: number,
currentSite: string,
gameProgress: any
)
: any[][]
{
return getVisibleNodesMatrix(
matrixIdx,
activeLevel,
currentSite,
gameProgress
)
.map(
(r, i) => r.map(
(n, j) => n ? {
node: n,
matrixIndices: {
matrixIdx,
rowIdx: i,
colIdx: j
}
} : null
)
);
}
interface NodeMatrixIndices {
matrixIdx: number; matrixIdx: number;
rowIdx: number; rowIdx: number;
colIdx: number; colIdx: number;
}, }
function findNode_current
(
direction: string,
{matrixIdx, rowIdx, colIdx}: NodeMatrixIndices,
level: number, level: number,
currentSite: string, currentSite: string,
gameProgress: any gameProgress: any
) => { )
const { matrixIdx, rowIdx, colIdx } = nodeMatrixIndices; : any | undefined
{
const visibleNodes = getVisibleNodesMatrix( const nodes = getNodesMatrixWithIndices(
matrixIdx, matrixIdx,
level, level,
currentSite, currentSite,
gameProgress gameProgress
); );
const precedence = generateRowPrecedence(rowIdx); const filters: any = {
left: () => reorder(nodes, RowPrecedence(rowIdx))
.flatMap(r => r.slice(0, colIdx).reverse()),
let chosenNode; right: () => reorder(nodes, RowPrecedence(rowIdx))
let matrixIndices; .flatMap(r => r.slice(colIdx + 1)),
loop: for (let col = colIdx - 1; col > -1; col--) {
for (let i = 0; i < 3; i++) {
const current = visibleNodes[precedence[i]][col];
if (current) {
chosenNode = current;
matrixIndices = {
matrixIdx: matrixIdx,
rowIdx: precedence[i],
colIdx: col,
};
break loop;
}
}
}
if (chosenNode) { up: () => nodes.slice(0, rowIdx).reverse()
return { .flatMap(r => reorder(r, ColPrecedence(colIdx))),
node: chosenNode,
matrixIndices: matrixIndices,
didRotate: false,
};
} else {
const newMatrixIdx = matrixIdx + 1 > 8 ? 1 : matrixIdx + 1;
const visibleNodes = getVisibleNodesMatrix(
newMatrixIdx,
level,
currentSite,
gameProgress
);
loop: for (let col = 0; col < 4; col++) { down: () => nodes.slice(rowIdx + 1)
for (let i = 0; i < 3; i++) { .flatMap(r => reorder(r, ColPrecedence(colIdx)))
const current = visibleNodes[precedence[i]][col]; };
if (current) {
chosenNode = current;
matrixIndices = {
matrixIdx: newMatrixIdx,
rowIdx: precedence[i],
colIdx: col,
};
break loop;
}
}
}
if (chosenNode) const chosen = filters[direction]().find((e: any) => e);
return { if (chosen) return {...chosen, didMove: false};
node: chosenNode, }
matrixIndices: matrixIndices,
didRotate: true,
};
}
};
export const findNodeRight = ( function findNode_next
nodeMatrixIndices: { (
matrixIdx: number; direction: string,
rowIdx: number; {matrixIdx, rowIdx, colIdx}: NodeMatrixIndices,
colIdx: number;
},
level: number, level: number,
currentSite: string, currentSite: string,
gameProgress: any gameProgress: any
) => { )
const { matrixIdx, rowIdx, colIdx } = nodeMatrixIndices; : any | undefined
{
const funcs: any = {
left: {
getMatrix: () => getNodesMatrixWithIndices(
matrixIdx + 1 > 8 ? 1 : matrixIdx + 1,
level,
currentSite,
gameProgress
),
const visibleNodes = getVisibleNodesMatrix( filter: (ns: any[]) => ns.flat()
matrixIdx, },
level,
currentSite, right: {
gameProgress getMatrix: () => getNodesMatrixWithIndices(
matrixIdx - 1 < 1 ? 8 : matrixIdx - 1,
level,
currentSite,
gameProgress
),
filter: (ns: any[]) => ns.flatMap(r => [...r].reverse())
},
up: {
getMatrix: () => getNodesMatrixWithIndices(
matrixIdx,
level + 1,
currentSite,
gameProgress
),
filter: (ns: any[]) => ns
.reverse()
.flatMap(r => reorder(r, ColPrecedence(colIdx)))
},
down: {
getMatrix: () => getNodesMatrixWithIndices(
matrixIdx,
level - 1,
currentSite,
gameProgress
),
filter: (ns: any[]) => ns
.flatMap(r => reorder(r, ColPrecedence(colIdx)))
}
};
const {getMatrix, filter} = funcs[direction];
const chosen = filter(getMatrix()).find((e: any) => e);
if (chosen) return {...chosen, didMove: true};
}
export function findNode(...args: [
string,
NodeMatrixIndices,
number,
string,
any
])
: any | undefined
{
return (
findNode_current(...args) ??
findNode_next(...args)
); );
}
const precedence = generateRowPrecedence(rowIdx);
let chosenNode;
let matrixIndices;
loop: for (let col = colIdx + 1; col < 4; col++) {
for (let i = 0; i < 3; i++) {
const current = visibleNodes[precedence[i]][col];
if (current) {
chosenNode = current;
matrixIndices = {
matrixIdx: matrixIdx,
rowIdx: precedence[i],
colIdx: col,
};
break loop;
}
}
}
if (chosenNode) {
return { node: chosenNode, didRotate: false, matrixIndices: matrixIndices };
} else {
const newMatrixIdx = matrixIdx - 1 < 1 ? 8 : matrixIdx - 1;
const visibleNodes = getVisibleNodesMatrix(
newMatrixIdx,
level,
currentSite,
gameProgress
);
loop: for (let col = 3; col > -1; col--) {
for (let i = 0; i < 3; i++) {
const current = visibleNodes[precedence[i]][col];
if (current) {
chosenNode = current;
matrixIndices = {
matrixIdx: newMatrixIdx,
rowIdx: precedence[i],
colIdx: col,
};
break loop;
}
}
}
if (chosenNode)
return {
node: chosenNode,
matrixIndices: matrixIndices,
didRotate: true,
};
}
};
const generateColPrecedence = (colIdx: number) => {
switch (colIdx) {
case 0:
return [0, 1, 2, 3];
case 1:
return [1, 0, 2, 3];
case 2:
return [2, 1, 3, 0];
case 3:
return [3, 2, 1, 0];
default:
return [0, 1, 2, 3];
}
};
export const findNodeUp = (
nodeMatrixIndices: {
matrixIdx: number;
rowIdx: number;
colIdx: number;
},
level: number,
currentSite: string,
gameProgress: any
) => {
const { matrixIdx, rowIdx, colIdx } = nodeMatrixIndices;
const visibleNodes = getVisibleNodesMatrix(
matrixIdx,
level,
currentSite,
gameProgress
);
const precedence = generateColPrecedence(colIdx);
let chosenNode;
let matrixIndices;
loop: for (let row = rowIdx - 1; row > -1; row--) {
for (let i = 0; i < 4; i++) {
const current = visibleNodes[row][precedence[i]];
if (current) {
chosenNode = current;
matrixIndices = {
matrixIdx: matrixIdx,
rowIdx: row,
colIdx: precedence[i],
};
break loop;
}
}
}
if (chosenNode) {
return { node: chosenNode, didMove: false, matrixIndices: matrixIndices };
} else {
const visibleNodes = getVisibleNodesMatrix(
matrixIdx,
level + 1,
currentSite,
gameProgress
);
loop: for (let row = 2; row > -1; row--) {
for (let i = 0; i < 4; i++) {
const current = visibleNodes[row][precedence[i]];
if (current) {
chosenNode = current;
matrixIndices = {
matrixIdx: matrixIdx,
rowIdx: row,
colIdx: precedence[i],
};
break loop;
}
}
}
if (chosenNode)
return {
node: chosenNode,
matrixIndices: matrixIndices,
didMove: true,
};
}
};
export const findNodeDown = (
nodeMatrixIndices: {
matrixIdx: number;
rowIdx: number;
colIdx: number;
},
level: number,
currentSite: string,
gameProgress: any
) => {
const { matrixIdx, rowIdx, colIdx } = nodeMatrixIndices;
const visibleNodes = getVisibleNodesMatrix(
matrixIdx,
level,
currentSite,
gameProgress
);
const precedence = generateColPrecedence(colIdx);
let chosenNode;
let matrixIndices;
loop: for (let row = rowIdx + 1; row < 3; row++) {
for (let i = 0; i < 4; i++) {
const current = visibleNodes[row][precedence[i]];
if (current) {
chosenNode = current;
matrixIndices = {
matrixIdx: matrixIdx,
rowIdx: row,
colIdx: precedence[i],
};
break loop;
}
}
}
if (chosenNode) {
return { node: chosenNode, didMove: false, matrixIndices: matrixIndices };
} else {
const visibleNodes = getVisibleNodesMatrix(
matrixIdx,
level - 1,
currentSite,
gameProgress
);
loop: for (let row = 0; row < 3; row++) {
for (let i = 0; i < 4; i++) {
const current = visibleNodes[row][precedence[i]];
if (current) {
chosenNode = current;
matrixIndices = {
matrixIdx: matrixIdx,
rowIdx: row,
colIdx: precedence[i],
};
break loop;
}
}
}
if (chosenNode)
return {
node: chosenNode,
matrixIndices: matrixIndices,
didMove: true,
};
}
};