리더보드 조회 기능 추가

- 요청한 유저와 같은 급수의 유저에서 랭킹 불러옴
- 승수와 패수를 이용해 승률을 계산
- 승률이 높은 유저부터 정렬
This commit is contained in:
fiore 2025-03-12 15:32:20 +09:00
parent fc3bc665b5
commit f341c9d8bb

View File

@ -1,4 +1,5 @@
var express = require('express');
const {ObjectId} = require("mongodb");
var router = express.Router();
// 랭킹 조회
@ -11,20 +12,45 @@ router.get("/", async function (req, res, next) {
var database = req.app.get('database');
var users = database.collection('users');
var allUsers = await users
.find({ }, { projection: { username:1, nickname: 1, score: 1 } })
.sort({ score: -1 }) // 점수가 높은 순으로 정렬
// 요청 유저 정보 확인
var userId = req.session.userId;
const user = await users.findOne({_id: ObjectId.createFromHexString(userId) });
var userRating = user.rating;
// 동일한 rating을 가진 유저들만 필터링
var sameRatingUsers = await users
.find({ rating: userRating }, { projection: { username: 1, nickname: 1, score: 1, win: 1, lose: 1, profileImageIndex:1, rating: 1 } })
.toArray();
var result = allUsers.map((user) => (
{
// 승률 계산 및 정렬
var result = sameRatingUsers.map((user) => {
const totalGames = (user.win || 0) + (user.lose || 0);
const winRate = totalGames > 0 ? ((user.win || 0) / totalGames * 100) : 0;
return {
username: user.username,
nickname: user.nickname,
score: user.score || 0,
win: user.win || 0,
lose: user.lose || 0,
winRate: parseFloat(winRate.toFixed(2)), // 소수점 2자리까지 표시
totalGames: totalGames,
imageindex: user.profileImageIndex,
};
})
.sort((a, b) => {
// 승률이 같은 경우 총 게임 수가 많은 사람이 위에 오도록 정렬
if (b.winRate === a.winRate) {
return b.totalGames - a.totalGames;
}
))
return b.winRate - a.winRate; // 승률 내림차순 정렬
});
res.json({ leaderboardDatas : result ?? [] });
res.json({
rating: userRating,
leaderboardDatas : result ?? []
});
} catch(err) {
console.error(err);
res.status(500).send("서버 오류가 발생했습니다.");