单人游戏结束时, 返回排行榜

This commit is contained in:
zhl 2021-05-11 16:03:06 +08:00
parent 5596f1d2f5
commit c6932fb7eb
5 changed files with 69 additions and 14 deletions

View File

@ -80,7 +80,8 @@
```js
{
result: 1 //答题结果 1: 正确, 0 : 错误
result: 1, //答题结果 1: 正确, 0 : 错误
gameResult: 0, // 当前局游戏结果 0: 未完成, -1: 失败, 1: 胜利
"stats": { // 当局的状态
"1111": {
"answer": [ // 每一题的结果
@ -90,7 +91,9 @@
"rightCount": 1, // 答对的数量
"errorCount": 1, // 答错的数量
"comboCount": 0, // 当前连续答对的数量
"maxCombo": 1 // 当局连续答对的最大数量
"maxCombo": 1, // 当局连续答对的最大数量
"score": 10, // 当局胜利后的得分
"gameResult": 0 // 当局的游戏结果, 单人的话和上一层gameResult相同
}
}
}

View File

@ -21,16 +21,28 @@ import { Schedule } from '../../clock/Schedule'
import {
calcPvpScore,
calcSingleScore,
checkSingleFinish, fetchLevelCfg, fetchSinglePuzzleType,
checkSingleFinish, fetchLevelCfg, fetchSinglePuzzleType, getRank,
startGame,
transformRecord, updateSingleRank
} from '../../services/GameLogic'
import { ObjectId } from 'bson'
import { Shop } from '../../models/shop/Shop'
import { isObjectId } from '../../utils/string.util'
import {
getAccountRank,
getAccountScore,
getRankList
} from '../../services/Rank'
class PuzzleController extends BaseController {
@role('anon')
@router('get /api/test')
async test(req) {
let vl =await getAccountScore('11', '22')
return {vl}
}
@role('anon')
@router('post /api/:accountid/puzzle/list')
async list(req, res) {
@ -112,6 +124,7 @@ class PuzzleController extends BaseController {
history.markModified('members')
let gameResult = 0
await history.save()
let rspData: any = { result, answer: record.a1, stats: history.members }
if (mode == 1) {
let score = result ? calcPvpScore(history.scheduleKey, statMap.comboCount) : 0
await broadcast(history.room, 'answer', {accountid, result, score})
@ -138,9 +151,13 @@ class PuzzleController extends BaseController {
}
history.markModified('members')
await history.save()
let {rankList, userRank } = await getRank({shop: history.shop, level: history.level, accountId: accountid, mode: 0, skip: 0, limit: 20})
rspData.rankList = rankList
rspData.userRank = userRank
}
}
return { result, answer: record.a1, stats: history.members, gameResult }
rspData.gameResult = gameResult
return rspData
}
@role('anon')

View File

@ -1,7 +1,7 @@
export class BaseConst{
public static readonly COMPOUND = 'compound'
public static readonly MISSION = 'mission'
public static readonly RANK_SCORE = 'rank_score'
public static readonly RANK_SCORE = 'r'
// 多人答题时间
public static readonly MATCH_ANSWER_TIME = 10000
// 游戏结束后房间自动解散时间

View File

@ -15,6 +15,12 @@ import { PuzzleRank } from '../models/match/PuzzleRank'
import { Shop } from '../models/shop/Shop'
import { mission_vo } from '../config/parsers/mission_vo'
import { ShopActivity } from '../models/shop/ShopActivity'
import {
getAccountRank,
getAccountScore,
getRankList,
updateRank
} from './Rank'
export function transformRecord(records: any[]) {
@ -116,7 +122,9 @@ export function calcPvpScore(timeKey: string, combo: number) {
const cfg = new GameEnv()
return cfg.pvpBaseScore + time / 100 * cfg.pvpTimeRate + combo * cfg.pvpComboRate
}
export function rankKey(shop: string, level: number, mode: number) {
return `${shop}_${mode}_${level}`
}
/**
*
* @param {string} shop id
@ -132,15 +140,34 @@ export async function updateSingleRank({shop, level, accountId, score, session,
level: number,
accountId: string,
score: number,
mode: number
mode: number,
session: string}) {
const key = rankKey(shop, level, mode)
await updateRank(accountId, score, key)
// let record = (await PuzzleRank.findOrCreate({shop, level, accountId, mode})).doc
// if (record.score < score) {
// record.score = score
// record.session = session
// await record.save()
// }
}
let record = (await PuzzleRank.findOrCreate({shop, level, accountId, mode})).doc
if (record.score < score) {
record.score = score
record.session = session
await record.save()
export async function getRank({shop, level, accountId, mode, skip, limit }
: {shop: string,
level: number,
accountId: string,
mode: number, skip: number, limit: number}) {
// let records = await PuzzleRank.find({shop, level, mode}).limit(limit).skip(skip).sort({'score': -1})
const key = rankKey(shop, level, mode)
let datas: any = await getRankList(skip, limit, key)
// let scoreMap: Map<any, number> = new Map()
let rankList: [any[]] = [[]]
for (let i = 0, l = datas.length; i < l; i += 2) {
// scoreMap.set(datas[i], datas[i + 1] << 0)
rankList.push([datas[i], datas[i + 1] << 0])
}
let userRank = (await getAccountRank(accountId, key)) || 999
return {rankList, userRank}
}
/**

View File

@ -19,7 +19,10 @@ function generateRankKey(subKey?: string) {
*/
export async function updateRank(accountId: string, score: number, subKey?: string) {
let scoreL = parseFloat(`${score | 0}.${MAX_TIME - Date.now()}`)
await new RedisClient().zadd(generateRankKey(subKey), scoreL, accountId)
let scoreOld = await getAccountScore(accountId, subKey)
if (score > scoreOld) {
await new RedisClient().zadd(generateRankKey(subKey), scoreL, accountId)
}
}
/**
@ -49,7 +52,12 @@ export async function getAccountRank(accountId: string, subKey?: string) {
* @return {Promise<unknown>}
*/
export async function getAccountScore(accountId: string, subKey?: string) {
return await new RedisClient().zscore(generateRankKey(subKey), accountId)
let score = await new RedisClient().zscore(generateRankKey(subKey), accountId)
if (score) {
return (+score)<<0
} else {
return 0
}
}
/**