リクエスト詳細
🐛 バグ報告
対応完了
対象アプリ: 合体ドロップ
ゲームオーバー時の「上位◯%」表示が100%を超える/逆転するケースがある
1. 不具合の内容
pages/rank_check.php の $percentile 関数が `ceil(rank / total * 100)` で計算されているため、参加人数が少ない期間で不自然な値になる。
- 今日その期間で自分より上位のスコアが total 件すべて存在する場合(=自分が最下位)、rank = total + 1 となり、percentile = ceil((total+1)/total*100) は 100 を超える(例: total=1 のとき rank=2 → 200%、total=3 のとき rank=4 → 134%)。「上位200%」「Top 200%」という無意味な表示になる。
- 逆に、その期間で自分が唯一のプレイヤーで単独1位(above=0, total=1: 既存レコード0件+自分が初回など変則ケースを除き、above=1,total=1で自分が2番目のケースなど)の境界でも、rank/total の分母が「自分を含まない既存件数」であるため、1位を取っても percentile が不当に高く出る(例: 既存1件より下回った場合は上記の200%、既存1件を上回った場合は total=1, rank=1 → percentile=100%となり、実際には2人中1位=本来50%相当であるべきところ100%と表示され、最下位のケースと数値が衝突する)。
2. 根拠・発生しそうな条件
pages/rank_check.php 内:
```php
$percentile = static function (int $rank, int $total): ?int {
return $total > 0 ? (int)ceil($rank / $total * 100) : null;
};
```
ここで渡される $total は「自分のスコアを含まない、その期間の既存レコード件数」であり、$rank = $above + 1 は「自分を含めた場合の順位」で、最大 total+1 まで到達しうる。分母に自分を含めていないため、rank が total を超えるケース(自分が最下位)で percentile が100%を超える。特にランキング参加者が少ないモード・平日早朝など該当期間の参加人数が1〜3人程度の場合に顕著に再現する。today/yesterday/weekly/monthly/alltime の全ての percentile 計算で同じ関数を共有しているため、全期間で発生しうる。
3. 期待動作
各期間の「上位◯%」は必ず1〜100の範囲に収まり、順位が悪いほど数値は100に近づき、良いほど小さくなる、という一貫した意味を持つべき。参加人数が少ない場合でも矛盾のない自然な値を表示する。
4. 修正方針
pages/rank_check.php の $percentile 関数の分母を「自分を含めた総人数」に修正する。
```php
$percentile = static function (int $rank, int $total): ?int {
$total_with_self = $total + 1;
if ($total_with_self <= 0) return null;
$p = (int)ceil($rank / $total_with_self * 100);
return max(1, min(100, $p));
}
```
呼び出し側は変更不要($total は既存の集計件数のまま渡す)。既存のレスポンス項目名・キーは変更せず、値の計算式のみ修正するため、フロント側の表示ロジックとの後方互換性は維持される。あわせて念のため 1〜100 にクランプし、将来的な計算誤差でも100%超・0%以下の表示が出ないようにする。
pages/rank_check.php の $percentile 関数が `ceil(rank / total * 100)` で計算されているため、参加人数が少ない期間で不自然な値になる。
- 今日その期間で自分より上位のスコアが total 件すべて存在する場合(=自分が最下位)、rank = total + 1 となり、percentile = ceil((total+1)/total*100) は 100 を超える(例: total=1 のとき rank=2 → 200%、total=3 のとき rank=4 → 134%)。「上位200%」「Top 200%」という無意味な表示になる。
- 逆に、その期間で自分が唯一のプレイヤーで単独1位(above=0, total=1: 既存レコード0件+自分が初回など変則ケースを除き、above=1,total=1で自分が2番目のケースなど)の境界でも、rank/total の分母が「自分を含まない既存件数」であるため、1位を取っても percentile が不当に高く出る(例: 既存1件より下回った場合は上記の200%、既存1件を上回った場合は total=1, rank=1 → percentile=100%となり、実際には2人中1位=本来50%相当であるべきところ100%と表示され、最下位のケースと数値が衝突する)。
2. 根拠・発生しそうな条件
pages/rank_check.php 内:
```php
$percentile = static function (int $rank, int $total): ?int {
return $total > 0 ? (int)ceil($rank / $total * 100) : null;
};
```
ここで渡される $total は「自分のスコアを含まない、その期間の既存レコード件数」であり、$rank = $above + 1 は「自分を含めた場合の順位」で、最大 total+1 まで到達しうる。分母に自分を含めていないため、rank が total を超えるケース(自分が最下位)で percentile が100%を超える。特にランキング参加者が少ないモード・平日早朝など該当期間の参加人数が1〜3人程度の場合に顕著に再現する。today/yesterday/weekly/monthly/alltime の全ての percentile 計算で同じ関数を共有しているため、全期間で発生しうる。
3. 期待動作
各期間の「上位◯%」は必ず1〜100の範囲に収まり、順位が悪いほど数値は100に近づき、良いほど小さくなる、という一貫した意味を持つべき。参加人数が少ない場合でも矛盾のない自然な値を表示する。
4. 修正方針
pages/rank_check.php の $percentile 関数の分母を「自分を含めた総人数」に修正する。
```php
$percentile = static function (int $rank, int $total): ?int {
$total_with_self = $total + 1;
if ($total_with_self <= 0) return null;
$p = (int)ceil($rank / $total_with_self * 100);
return max(1, min(100, $p));
}
```
呼び出し側は変更不要($total は既存の集計件数のまま渡す)。既存のレスポンス項目名・キーは変更せず、値の計算式のみ修正するため、フロント側の表示ロジックとの後方互換性は維持される。あわせて念のため 1〜100 にクランプし、将来的な計算誤差でも100%超・0%以下の表示が出ないようにする。
💬 返信 (3)
🛠 開発を開始しました (バグ修正 (vegetable-drop))
ご要望ありがとうございます。AI 開発ワーカーが実装を開始します。
通常 5〜30 分で Pull Request を作成し、レビュー後にリリースされます。
ご要望ありがとうございます。AI 開発ワーカーが実装を開始します。
通常 5〜30 分で Pull Request を作成し、レビュー後にリリースされます。
📝 開発が完了しました
ご要望いただいた内容の実装が完了し、最終チェック段階に入りました。
レビュー (自動) → リリース、の流れで進みます。
もう少々お待ちください。
ご要望いただいた内容の実装が完了し、最終チェック段階に入りました。
レビュー (自動) → リリース、の流れで進みます。
もう少々お待ちください。
✅ リリース完了のお知らせ
ご要望いただいた「合体ドロップ」を実装し、リリースいたしました。
【ご利用方法】
ダッシュボード: https://www.aiapps.jp/?action=dashboard
アプリ詳細: https://www.aiapps.jp/apps/show.php?slug=vegetable-drop
デモ環境は 1 時間以内に自動構築されます:
https://www.aiapps.jp/demo/vegetable-drop/
ご利用ありがとうございます!
ご要望いただいた「合体ドロップ」を実装し、リリースいたしました。
【ご利用方法】
ダッシュボード: https://www.aiapps.jp/?action=dashboard
アプリ詳細: https://www.aiapps.jp/apps/show.php?slug=vegetable-drop
デモ環境は 1 時間以内に自動構築されます:
https://www.aiapps.jp/demo/vegetable-drop/
ご利用ありがとうございます!
Echo
Iris