Skip to content

Add average score per highest tile to stats feed - #13

Open
mmiermans wants to merge 1 commit into
exp/mozilla-basefrom
exp/mz-perf
Open

Add average score per highest tile to stats feed#13
mmiermans wants to merge 1 commit into
exp/mozilla-basefrom
exp/mz-perf

Conversation

@mmiermans

Copy link
Copy Markdown
Owner

Extends the game stats payload with an avg_score map giving the average final score for each highest-tile value. This lets the stats chart show how the typical score scales as players reach larger tiles.

  • Computed alongside the existing max_tile / score stats in movefeed.php.
  • Only runs when ?stats=1 is requested, so the normal move feed is unaffected.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
🤖 Claude has reviewed this PR — expand after forming your own opinion

Performance

N+1 query problem — the data is already in memory. The initial statsQuery (line 23) already fetches every (max_tile, score) row. The new code then issues one additional SELECT AVG(score) ... WHERE max_tile = X query per distinct tile value, re-scanning the table each time. All the data needed to compute these averages is already available during the first loop.

Accumulate the sum in PHP while iterating the existing result set — zero extra queries:

  $maxTileStats = array();
  $scoreStats = array();
  $scoreSums = array();

  $result = $mysqli->query($statsQuery);
  if (!$result) {
    echo "CALL failed: (" . $mysqli->errno . ") " . $mysqli->error;
  }

  while ($row = $result->fetch_row()) {
    $max_tile = (int)$row[0];
    $score = (int)$row[1];

    if (isset($maxTileStats[$max_tile]))
      $maxTileStats[$max_tile]++;
    else
      $maxTileStats[$max_tile] = 1;

    if (!isset($scoreSums[$max_tile]))
      $scoreSums[$max_tile] = 0;
    $scoreSums[$max_tile] += $score;

    array_push($scoreStats, $score);
  }

  $result->close();

  $avgScorePerTile = array();
  foreach ($maxTileStats as $max_tile => $count) {
    $avgScorePerTile[$max_tile] = (int)round($scoreSums[$max_tile] / $count);
  }

This eliminates the entire foreach + query block (lines 53-62) and scales O(1) in database round-trips regardless of the number of distinct tiles.

Security

The max_tile interpolation in the query string is safe here because the keys originate from (int) casts on line 38 — consistent with the existing codebase pattern (e.g. game_id). No action needed, but worth noting for future maintainers: if this pattern ever accepts external input directly, switch to prepared statements.

Code Quality

No other issues — the new avg_score key integrates cleanly into the existing stats structure.

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.

1 participant