feat: scaffold mvp shell and content runtime
This commit is contained in:
74
js/gameplay/difficulty/overlap-graph.js
Normal file
74
js/gameplay/difficulty/overlap-graph.js
Normal file
@@ -0,0 +1,74 @@
|
||||
function getPieceArea(piece) {
|
||||
return piece.width * piece.height
|
||||
}
|
||||
|
||||
function overlapArea(left, right) {
|
||||
const overlapWidth = Math.max(0, Math.min(left.x + left.width, right.x + right.width) - Math.max(left.x, right.x))
|
||||
const overlapHeight = Math.max(0, Math.min(left.y + left.height, right.y + right.height) - Math.max(left.y, right.y))
|
||||
|
||||
return overlapWidth * overlapHeight
|
||||
}
|
||||
|
||||
function overlapsCenterZone(lower, upper) {
|
||||
const centerWidth = lower.width * 0.5
|
||||
const centerHeight = lower.height * 0.5
|
||||
const centerBox = {
|
||||
x: lower.x + lower.width * 0.25,
|
||||
y: lower.y + lower.height * 0.25,
|
||||
width: centerWidth,
|
||||
height: centerHeight,
|
||||
}
|
||||
|
||||
return overlapArea(centerBox, upper) > 0
|
||||
}
|
||||
|
||||
export function buildOverlapGraph(pieces) {
|
||||
const graph = Object.fromEntries(pieces.map((piece) => [piece.id, []]))
|
||||
|
||||
for (let leftIndex = 0; leftIndex < pieces.length; leftIndex += 1) {
|
||||
for (let rightIndex = 0; rightIndex < pieces.length; rightIndex += 1) {
|
||||
if (leftIndex === rightIndex) {
|
||||
continue
|
||||
}
|
||||
|
||||
const blocker = pieces[leftIndex]
|
||||
const blocked = pieces[rightIndex]
|
||||
|
||||
if (blocker.layer <= blocked.layer) {
|
||||
continue
|
||||
}
|
||||
|
||||
const ratio = overlapArea(blocker, blocked) / getPieceArea(blocked)
|
||||
|
||||
if (ratio >= 0.2 && overlapsCenterZone(blocked, blocker)) {
|
||||
graph[blocker.id].push(blocked.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return graph
|
||||
}
|
||||
|
||||
export function getClickablePieces(boardState) {
|
||||
const pieces = (boardState.pieces ?? []).filter((piece) => !piece.removed)
|
||||
const indegree = Object.fromEntries(pieces.map((piece) => [piece.id, 0]))
|
||||
const graph = boardState.overlapGraph ?? {}
|
||||
|
||||
for (const blockedIds of Object.values(graph)) {
|
||||
for (const blockedId of blockedIds) {
|
||||
if (blockedId in indegree) {
|
||||
indegree[blockedId] += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pieces.filter((piece) => indegree[piece.id] === 0)
|
||||
}
|
||||
|
||||
export function rebuildGraphAfterShuffle(boardState) {
|
||||
return buildOverlapGraph(boardState.pieces ?? [])
|
||||
}
|
||||
|
||||
export function rebuildGraphAfterUndo(boardState) {
|
||||
return buildOverlapGraph(boardState.pieces ?? [])
|
||||
}
|
||||
Reference in New Issue
Block a user