增加一种无正确答案的题目类型
This commit is contained in:
parent
05eb62f749
commit
e4625becf7
22
doc/api.md
22
doc/api.md
@ -48,7 +48,7 @@
|
||||
"刘永福"
|
||||
],
|
||||
"category": "体育-体育", // 类型
|
||||
"type": 1, // 题目类型 1: 普通的文字选择题, 2: 图形
|
||||
"type": 1, // 题目类型 1: 普通的文字选择题, 2: 图形, 3: 问卷式题目
|
||||
"quality": 1 // 题目难度
|
||||
}]
|
||||
}
|
||||
@ -85,10 +85,10 @@
|
||||
gameResult: 0, // 当前局游戏结果 0: 未完成, -1: 失败, 1: 胜利
|
||||
"stats": { // 当局的状态
|
||||
"1111": {
|
||||
"answer": [ // 每一题的结果
|
||||
1,
|
||||
0
|
||||
],
|
||||
"answer": {// 每一题的结果, key为题目的id, 值为answer在答案中的index值, 0为正确值, -1为超时, 其他都为错误
|
||||
"608a3d15e678843dd443fa53": 0,
|
||||
},
|
||||
"total": 2, // 总答题数量
|
||||
"rightCount": 1, // 答对的数量
|
||||
"errorCount": 1, // 答错的数量
|
||||
"comboCount": 0, // 当前连续答对的数量
|
||||
@ -162,7 +162,7 @@
|
||||
"刘永福"
|
||||
],
|
||||
"category": "体育-体育", // 类型
|
||||
"type": 1, // 题目类型 1: 普通的文字选择题, 2: 图形
|
||||
"type": 1, // 题目类型 1: 普通的文字选择题, 2: 图形, 3: 问卷式题目
|
||||
"quality": 1 // 题目难度
|
||||
}]
|
||||
```
|
||||
@ -238,7 +238,7 @@
|
||||
"刘永福"
|
||||
],
|
||||
"category": "体育-体育", // 类型
|
||||
"type": 1, // 题目类型 1: 普通的文字选择题, 2: 图形
|
||||
"type": 1, // 题目类型 1: 普通的文字选择题, 2: 图形, 3: 问卷式题目
|
||||
"quality": 1 // 题目难度
|
||||
}]
|
||||
}
|
||||
@ -273,10 +273,10 @@
|
||||
overtime: 0, // 当前回答是否超时 0: 未超时, 1: 超时
|
||||
"stats": { // 当局的状态
|
||||
"1111": {
|
||||
"answer": [ // 每一题的结果
|
||||
1,
|
||||
0
|
||||
],
|
||||
"answer": {// 每一题的结果, key为题目的id, 值为answer在答案中的index值, 0为正确值, -1为超时, 其他都为错误
|
||||
"608a3d15e678843dd443fa53": 0,
|
||||
},
|
||||
"total": 2, // 总答题数量
|
||||
"rightCount": 1, // 答对的数量
|
||||
"errorCount": 1, // 答错的数量
|
||||
"comboCount": 0, // 当前连续答对的数量
|
||||
|
@ -53,7 +53,7 @@ class ExamController extends BaseController {
|
||||
} else {
|
||||
results = record.transQuestion()
|
||||
for (let _r of record.questions) {
|
||||
history.questions.set(_r._id + '', _r.a1)
|
||||
history.questions.set(_r._id + '', _r.compactRecord(true))
|
||||
}
|
||||
}
|
||||
let stat = new PuzzleStatusClass()
|
||||
@ -101,18 +101,19 @@ class ExamController extends BaseController {
|
||||
}
|
||||
let time = (history.timeone* 1000 - (Date.now() - statMap.timeLast)) / 1000
|
||||
let record = history.questions.get(id)
|
||||
let result = record === answer ? 1 : 0
|
||||
let result = record.answers.indexOf(answer)
|
||||
let overtime = 0
|
||||
if (type == 1) { // type = 1 为客户端上报的超时消息, 直接判负
|
||||
result = 0
|
||||
result = -1
|
||||
overtime = 1
|
||||
} else if (time < 0){
|
||||
result = 0
|
||||
result = -1
|
||||
overtime = 1
|
||||
}
|
||||
statMap.timeLast = Date.now()
|
||||
statMap.answer.set(id, result)
|
||||
if (result == 1) {
|
||||
statMap.total ++
|
||||
if (result == 0) {
|
||||
statMap.rightCount++
|
||||
statMap.comboCount++
|
||||
statMap.maxCombo = Math.max(statMap.maxCombo, statMap.comboCount)
|
||||
@ -128,7 +129,7 @@ class ExamController extends BaseController {
|
||||
history.markModified('members')
|
||||
await history.save()
|
||||
let gameResult = 0
|
||||
let rspData: any = { result, answer: record, stats: history.members, overtime }
|
||||
let rspData: any = { result: result === 0, answer: record.answers[0], stats: history.members, overtime }
|
||||
if (statMap.answer.size >= history.questions.size) {
|
||||
gameResult = 1
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import {
|
||||
import { Shop, validShopId } from '../../models/shop/Shop'
|
||||
import { ShopActivity } from '../../models/shop/ShopActivity'
|
||||
import { GameUser } from '../../models/GameUser'
|
||||
import { BaseConst } from '../../constants/BaseConst'
|
||||
|
||||
|
||||
class PuzzleController extends BaseController {
|
||||
@ -71,7 +70,7 @@ class PuzzleController extends BaseController {
|
||||
let history = new PuzzleSession({ shop: shopId, level })
|
||||
history.members.set(accountid, new PuzzleStatusClass())
|
||||
for (let record of records) {
|
||||
history.questions.set(record.id, record.a1)
|
||||
history.questions.set(record.id, record.compactRecord(true))
|
||||
}
|
||||
history.expire = Date.now() + (cfg.time || 90) * 1000
|
||||
history.type = 0
|
||||
@ -104,12 +103,12 @@ class PuzzleController extends BaseController {
|
||||
throw new ZError(16, 'current question not in current match')
|
||||
}
|
||||
let record = history.questions.get(id)
|
||||
let result = record === answer ? 1 : 0
|
||||
let result = record.answers.indexOf(answer)
|
||||
if (type == 1) { // type = 1 为客户端上报的超时消息, 直接判负
|
||||
result = 0
|
||||
result = -1
|
||||
}
|
||||
if (history.status == 9 || history.hasExpired()) {
|
||||
result = 0
|
||||
result = -1
|
||||
}
|
||||
let statMap = history.members.get(accountid)
|
||||
if (statMap.answer.has(id)) {
|
||||
@ -117,7 +116,8 @@ class PuzzleController extends BaseController {
|
||||
}
|
||||
statMap.timeLast = Date.now()
|
||||
statMap.answer.set(id, result)
|
||||
if (result == 1) {
|
||||
statMap.total ++
|
||||
if (result == 0) {
|
||||
statMap.rightCount++
|
||||
statMap.comboCount++
|
||||
statMap.maxCombo = Math.max(statMap.maxCombo, statMap.comboCount)
|
||||
@ -129,7 +129,7 @@ class PuzzleController extends BaseController {
|
||||
history.markModified('members')
|
||||
let gameResult = 0
|
||||
await history.save()
|
||||
let rspData: any = { result, answer: record, stats: history.members }
|
||||
let rspData: any = { result: result === 0, answer: record.answers[0], stats: history.members }
|
||||
if (mode == 1) {
|
||||
let score = result ? calcPvpScore(history.scheduleKey, statMap.comboCount) : 0
|
||||
await broadcast(history.room, 'answer', {accountid, result, score})
|
||||
@ -204,7 +204,7 @@ class PuzzleController extends BaseController {
|
||||
let records = await Puzzle.randomQuestions(options, count)
|
||||
const results = transformRecord(records)
|
||||
for (let record of records) {
|
||||
history.questions.set(record.id, record.a1)
|
||||
history.questions.set(record.id, record.compactRecord(true))
|
||||
}
|
||||
history.markModified('questions')
|
||||
await history.save()
|
||||
|
@ -7,10 +7,17 @@ import {
|
||||
} from '@typegoose/typegoose'
|
||||
import { BaseModule } from '../Base'
|
||||
import { noJson } from '../../decorators/nojson'
|
||||
import { QCategoryCache } from '../../services/QCategoryCache'
|
||||
import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses'
|
||||
import { CompactPuzzleClass } from '../match/PuzzleSession'
|
||||
|
||||
// @ts-ignore
|
||||
export interface PuzzleClass extends Base, TimeStamps {
|
||||
}
|
||||
|
||||
@dbconn('second')
|
||||
@modelOptions({ schemaOptions: { collection: 'question' } })
|
||||
class PuzzleClass extends BaseModule {
|
||||
export class PuzzleClass extends BaseModule {
|
||||
@prop()
|
||||
public question: string
|
||||
@prop()
|
||||
@ -110,9 +117,31 @@ class PuzzleClass extends BaseModule {
|
||||
{ $match: filters },
|
||||
{ $sample: { size: count } }
|
||||
]).exec()
|
||||
|
||||
}
|
||||
|
||||
public compactRecord(withAnswer: boolean) {
|
||||
let answers = []
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
if (this[`a${ i }`]) {
|
||||
answers.push(this[`a${ i }`])
|
||||
}
|
||||
}
|
||||
let type = new QCategoryCache().getType(this.tag)
|
||||
let subType = new QCategoryCache().getType(this.sub_tag)
|
||||
let result = new CompactPuzzleClass()
|
||||
result.id = this._id+''
|
||||
result.title = this.question
|
||||
|
||||
result.type = 1
|
||||
result.category = type + '-' + subType
|
||||
result.quality = this.quality
|
||||
if (!withAnswer) {
|
||||
answers.randomSort()
|
||||
}
|
||||
result.source = 0
|
||||
result.answers = answers
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
export const Puzzle = getModelForClass(PuzzleClass, { existingConnection: PuzzleClass.db })
|
||||
|
@ -4,6 +4,42 @@ import { BaseModule } from '../Base'
|
||||
import { Severity } from '@typegoose/typegoose/lib/internal/constants'
|
||||
import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses'
|
||||
|
||||
export class CompactPuzzleClass {
|
||||
@prop()
|
||||
id: string
|
||||
@prop()
|
||||
title: string
|
||||
@prop({ type: () => [String] })
|
||||
public answers: string[]
|
||||
//1: 普通的文字选择题, 2: 图形, 3: 问卷式题目
|
||||
@prop()
|
||||
public type: number
|
||||
@prop()
|
||||
public category: string
|
||||
@prop()
|
||||
public quality: number
|
||||
/**
|
||||
* 题目来源
|
||||
* 0: 系统题库
|
||||
* 1: 自定义
|
||||
* @type {number}
|
||||
*/
|
||||
@prop()
|
||||
public source: number
|
||||
|
||||
public toJson() {
|
||||
let answers = this.answers.slice(0)
|
||||
answers.randomSort()
|
||||
return {
|
||||
id: this.id,
|
||||
title: this.title,
|
||||
answers: answers,
|
||||
type: this.type,
|
||||
category: this.category,
|
||||
quality: this.quality
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@modelOptions({
|
||||
options: {allowMixed: Severity.ALLOW}
|
||||
@ -13,6 +49,8 @@ export class PuzzleStatusClass {
|
||||
@prop({ type: Number, default: new Map() })
|
||||
answer: Map<string, number>
|
||||
|
||||
@prop({default: 0})
|
||||
total: number
|
||||
/**
|
||||
* 打对数量
|
||||
* @type {number}
|
||||
@ -81,8 +119,8 @@ export class PuzzleSessionClass extends BaseModule {
|
||||
@prop({ _id: false, type: PuzzleStatusClass, default: new Map() })
|
||||
public members: Map<string, PuzzleStatusClass>
|
||||
|
||||
@prop({ _id: false, type: String, default: new Map() })
|
||||
public questions: Map<string, string>
|
||||
@prop({ _id: false, type: CompactPuzzleClass, default: new Map() })
|
||||
public questions: Map<string, CompactPuzzleClass>
|
||||
|
||||
@prop()
|
||||
public shop: string
|
||||
|
@ -8,6 +8,7 @@ import { BaseModule } from '../Base'
|
||||
import { noJson } from '../../decorators/nojson'
|
||||
import { Severity } from '@typegoose/typegoose/lib/internal/constants'
|
||||
import { Base } from '@typegoose/typegoose/lib/defaultClasses'
|
||||
import { CompactPuzzleClass } from '../match/PuzzleSession'
|
||||
|
||||
export class ShopPuzzleClass extends Base{
|
||||
@prop()
|
||||
@ -20,6 +21,33 @@ export class ShopPuzzleClass extends Base{
|
||||
public a3: string
|
||||
@prop()
|
||||
public a4: string
|
||||
/**
|
||||
* 题目类型: 1: 正常单选题, 2: 图片, 3: 问卷式题目
|
||||
* @type {number}
|
||||
*/
|
||||
@prop()
|
||||
public type: number
|
||||
|
||||
public compactRecord(withAnswer: boolean) {
|
||||
let answers = []
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
if (this[`a${ i }`]) {
|
||||
answers.push(this[`a${ i }`])
|
||||
}
|
||||
}
|
||||
let result = new CompactPuzzleClass()
|
||||
result.id = this._id+''
|
||||
result.title = this.question
|
||||
result.type = 1
|
||||
result.category = '自定义'
|
||||
result.quality = 1
|
||||
if (!withAnswer) {
|
||||
answers.randomSort()
|
||||
}
|
||||
result.source = 1
|
||||
result.answers = answers
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
export class ExamRewardClass extends Base{
|
||||
@ -168,21 +196,7 @@ export class ShopExamClass extends BaseModule {
|
||||
|
||||
public transQuestion() {
|
||||
return this.questions.map(o => {
|
||||
let answers = []
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
if (o[`a${ i }`]) {
|
||||
answers.push(o[`a${ i }`])
|
||||
}
|
||||
}
|
||||
answers.randomSort()
|
||||
return {
|
||||
id: o._id,
|
||||
title: o.question,
|
||||
answers,
|
||||
type: 1,
|
||||
category: '自定义',
|
||||
quality: 1
|
||||
}
|
||||
return o.compactRecord(false)
|
||||
})
|
||||
}
|
||||
public getReward(score: number) {
|
||||
|
@ -26,35 +26,15 @@ export class ShopGameExtClass extends BaseModule {
|
||||
|
||||
@prop()
|
||||
public version: string
|
||||
|
||||
/**
|
||||
* bg_item_icon: 背景图案
|
||||
* game_main_pic: 主页正中间图片
|
||||
* game_single_btn: 主页上单人赛按钮文字
|
||||
* game_multi_btn: 主页上多人赛按钮名字
|
||||
*/
|
||||
@prop({type: mongoose.Schema.Types.Mixed})
|
||||
public cfg: {}
|
||||
|
||||
// /**
|
||||
// * 背景图案
|
||||
// * @type {string}
|
||||
// */
|
||||
// @prop()
|
||||
// public bg_item_icon: string
|
||||
// /**
|
||||
// * 主页正中间图片
|
||||
// * @type {string}
|
||||
// */
|
||||
// @prop()
|
||||
// public game_main_pic: string
|
||||
// /**
|
||||
// * 主页上单人赛按钮文字
|
||||
// * @type {string}
|
||||
// */
|
||||
// @prop()
|
||||
// public game_single_btn: string
|
||||
//
|
||||
// /**
|
||||
// * 主页上多人赛按钮名字
|
||||
// * @type {string}
|
||||
// */
|
||||
// @prop()
|
||||
// public game_multi_btn: string
|
||||
}
|
||||
|
||||
export const ShopGameExt = getModelForClass(ShopGameExtClass, { existingConnection: ShopGameExtClass.db })
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {
|
||||
beginGame,
|
||||
endGame, sendMsg,
|
||||
endGame,
|
||||
sendMsg,
|
||||
sendQuestion,
|
||||
updateRound,
|
||||
updateScore
|
||||
@ -8,7 +9,6 @@ import {
|
||||
import { Puzzle } from '../models/content/Puzzle'
|
||||
import { Schedule } from '../clock/Schedule'
|
||||
import { BaseConst } from '../constants/BaseConst'
|
||||
import { QCategoryCache } from './QCategoryCache'
|
||||
import { PuzzleSession } from '../models/match/PuzzleSession'
|
||||
import { GameEnv } from '../config/GameEnv'
|
||||
import { Shop } from '../models/shop/Shop'
|
||||
@ -22,23 +22,7 @@ import { GameUser } from '../models/GameUser'
|
||||
|
||||
export function transformRecord(records: any[]) {
|
||||
return records.map(o => {
|
||||
let answers = []
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
if (o[`a${ i }`]) {
|
||||
answers.push(o[`a${ i }`])
|
||||
}
|
||||
}
|
||||
answers.randomSort()
|
||||
let type = new QCategoryCache().getType(o.tag)
|
||||
let subType = new QCategoryCache().getType(o.sub_tag)
|
||||
return {
|
||||
id: o._id,
|
||||
title: o.question,
|
||||
answers,
|
||||
type: 1,
|
||||
category: type + '-' + subType,
|
||||
quality: o.quality
|
||||
}
|
||||
return o.compactRecord(false)
|
||||
})
|
||||
}
|
||||
|
||||
@ -98,8 +82,7 @@ export async function sendOneQuestion(history: any) {
|
||||
}
|
||||
const questions:string[] = Array.from(history.questions.keys())
|
||||
let qid: string = questions[history.current]
|
||||
let record = await Puzzle.findById(qid)
|
||||
let qdata: any = transformRecord([record])[0]
|
||||
let qdata = history.questions.get(qid).toJson()
|
||||
qdata.no = history.current
|
||||
await updateRound(roomId, history.current)
|
||||
await sendQuestion(roomId, qdata)
|
||||
@ -110,7 +93,7 @@ export async function sendOneQuestion(history: any) {
|
||||
let datas = []
|
||||
for (let [accountid, data] of subHistory.members) {
|
||||
if (!data.answer.has(qid)) {
|
||||
data.answer.set(qid, 0)
|
||||
data.answer.set(qid, -1)
|
||||
data.errorCount++
|
||||
data.comboCount = 0
|
||||
datas.push({ accountid, score: 0 })
|
||||
|
Loading…
x
Reference in New Issue
Block a user