"error", "leaderboard" => [], "user_rank" => null ]; // --------------------------------------------------------- // 1. Ambil Top 10 Global (DIPERBAIKI) // Ditambahkan "user_id ASC" agar urutannya PASTI (Konsisten) // Jika skor sama, user dengan ID lebih kecil (daftar duluan) akan di atas // --------------------------------------------------------- $query = "SELECT username, score FROM leaderboard ORDER BY score DESC, user_id ASC LIMIT 10"; $result = $conn->query($query); if ($result && $result->num_rows > 0) { while ($row = $result->fetch_assoc()) { $response['leaderboard'][] = $row; } } // --------------------------------------------------------- // 2. Ambil Ranking User Login (DIPERBAIKI) // --------------------------------------------------------- if (isset($_SESSION['user_id'])) { $my_id = $_SESSION['user_id']; // Ambil score user saat ini $scoreQuery = $conn->prepare("SELECT username, score FROM leaderboard WHERE user_id = ?"); $scoreQuery->bind_param("i", $my_id); $scoreQuery->execute(); $scoreResult = $scoreQuery->get_result(); if ($scoreRow = $scoreResult->fetch_assoc()) { $myScore = $scoreRow['score']; $myUsername = $scoreRow['username']; // --- LOGIKA BARU --- // Hitung ranking dengan Tie-Breaker. // Rank = Jumlah orang yang skornya LEBIH BESAR // DITAMBAH Jumlah orang yang skornya SAMA tapi ID-nya LEBIH KECIL (dia di atas kita) $rankQuery = $conn->prepare(" SELECT COUNT(*) as rank_above FROM leaderboard WHERE score > ? OR (score = ? AND user_id < ?) "); // Kita bind 3 parameter: score, score, id $rankQuery->bind_param("iii", $myScore, $myScore, $my_id); $rankQuery->execute(); $rankResult = $rankQuery->get_result(); $rankRow = $rankResult->fetch_assoc(); // Rank adalah jumlah orang di atas kita + 1 $myRank = $rankRow['rank_above'] + 1; $response['user_rank'] = [ "username" => $myUsername, "score" => $myScore, "rank" => $myRank ]; } } $response['status'] = "success"; echo json_encode($response); $conn->close(); ?>