增加一种无正确答案的题目类型

This commit is contained in:
zhl 2021-05-25 19:49:01 +08:00
parent 05eb62f749
commit e4625becf7
8 changed files with 137 additions and 92 deletions

View File

@ -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, // 当前连续答对的数量

View File

@ -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
}

View File

@ -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()

View File

@ -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 })

View File

@ -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

View File

@ -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) {

View File

@ -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 })

View File

@ -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 })