Skip to content

fix(cheat-detection): align complexity-speed with each move's own think time - #942

Open
abdulwaarith0 wants to merge 1 commit into
OpenKnight-Foundation:mainfrom
abdulwaarith0:fix/940-cheat-detection-thinktime-alignment
Open

fix(cheat-detection): align complexity-speed with each move's own think time#942
abdulwaarith0 wants to merge 1 commit into
OpenKnight-Foundation:mainfrom
abdulwaarith0:fix/940-cheat-detection-thinktime-alignment

Conversation

@abdulwaarith0

Copy link
Copy Markdown
Contributor

What & why

Fixes #940.

CheatDetectionEngine.scoreComplexitySpeed() correlated complex-position moves with the wrong think times. complexMoveIndices held indices into playerMoves, but the code read thinkTimes[idx]. Those two arrays live in different index spaces:

  • thinkTimes (from computeThinkTimes) starts at move 1 and is compacted by the elapsed > 0 && elapsed < 300000 filter, so thinkTimes[i] is the gap before playerMoves[i + 1] — not the think time of playerMoves[i].

Result: every complex move was matched to a neighbour's think time (systematic off-by-one), and higher-index complex moves were silently skipped by the idx < thinkTimes.length guard — corrupting the complexitySpeed component of the suspicion score that's shown live during play (useCheatDetectionapp/play/[slug]/page.tsx).

Fix

Compute each complex move's think time directly from its own previous move's timestamp (playerMoves[i].timestamp - playerMoves[i - 1].timestamp, for i >= 1), instead of indexing into the compacted thinkTimes array. The first move has no preceding own move, so it's excluded.

Tests

Adds frontend/__tests__/cheatDetection.test.ts (vitest):

  • A slow-complex / fast-simple scenario that asserts complexitySpeed === 0 — this fails on the old off-by-one code (which pulled the fast gap onto a complex move) and passes now.
  • A genuinely-fast-in-complex-positions scenario that asserts complexitySpeed > 0.

Both new tests pass locally (vitest run __tests__/cheatDetection.test.ts), and the change is isolated to cheatDetection.ts.

…nk time

scoreComplexitySpeed collected complex-position indices from playerMoves but
read think times via thinkTimes[idx]. Those arrays are in different index
spaces: thinkTimes starts at move 1 and is compacted by an elapsed filter, so
thinkTimes[i] is the gap before playerMoves[i+1], not the think time of
playerMoves[i]. The heuristic therefore matched each complex move to a
neighbour's think time (systematic off-by-one) and silently dropped higher-index
complex moves via the length guard.

Compute each complex move's think time directly from its own previous move's
timestamp instead of indexing the compacted array. Add vitest coverage.

Closes OpenKnight-Foundation#940
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FE: Cheat-detection scoreComplexitySpeed reads misaligned think times (index mismatch)

1 participant