sudoku leader board fixed

This commit is contained in:
2026-05-15 23:21:31 +08:00
parent f1f906be55
commit 5567bf572f
4 changed files with 109 additions and 17 deletions

View File

@@ -7,6 +7,7 @@ export interface ISudokuRecord extends Document {
username: string;
fullname: string;
difficulty: SudokuDifficulty;
gameMode: 'standard' | 'irregular';
timeSeconds: number;
won: boolean;
createdAt: Date;
@@ -17,6 +18,7 @@ export interface ISudokuLeaderboardRecord {
userId: mongoose.Types.ObjectId;
username: string;
fullname: string;
gameMode: 'standard' | 'irregular';
bestTime: number;
totalGames: number;
wonGames: number;
@@ -43,6 +45,12 @@ const sudokuRecordSchema = new Schema<ISudokuRecord>({
enum: ['easy', 'medium', 'hard'],
required: true
},
gameMode: {
type: String,
enum: ['standard', 'irregular'],
required: true,
default: 'standard'
},
timeSeconds: {
type: Number,
required: true,
@@ -56,25 +64,41 @@ const sudokuRecordSchema = new Schema<ISudokuRecord>({
timestamps: true
});
sudokuRecordSchema.index({ userId: 1, difficulty: 1 });
sudokuRecordSchema.index({ difficulty: 1, won: 1, timeSeconds: 1 });
sudokuRecordSchema.index({ userId: 1, difficulty: 1, gameMode: 1 });
sudokuRecordSchema.index({ difficulty: 1, won: 1, gameMode: 1, timeSeconds: 1 });
sudokuRecordSchema.statics.getLeaderboard = function(
difficulty: SudokuDifficulty,
gameMode: 'standard' | 'irregular' | 'all',
skipCount: number,
pageSize: number
): mongoose.Aggregate<ISudokuLeaderboardRecord[]> {
const match: any = {
difficulty
};
if (gameMode === 'standard') {
match.$or = [
{ gameMode: 'standard' },
{ gameMode: { $exists: false } }
];
} else if (gameMode === 'irregular') {
match.gameMode = 'irregular';
}
return this.aggregate([
{
$match: {
difficulty
}
$match: match
},
{
$group: {
_id: '$userId',
_id: {
userId: '$userId',
gameMode: { $ifNull: ['$gameMode', 'standard'] }
},
username: { $first: '$username' },
fullname: { $first: '$fullname' },
gameMode: { $first: { $ifNull: ['$gameMode', 'standard'] } },
bestTime: {
$min: {
$cond: [{ $eq: ['$won', true] }, '$timeSeconds', null]
@@ -92,7 +116,7 @@ sudokuRecordSchema.statics.getLeaderboard = function(
},
{
$addFields: {
userId: '$_id',
userId: '$_id.userId',
winRate: {
$multiply: [
{ $cond: [{ $eq: ['$totalGames', 0] }, 0, { $divide: ['$wonGames', '$totalGames'] }] },