feat: add multiple choice questions supported(`type: select`)

master
Riceball LEE 2022-07-19 15:51:55 +08:00
parent dfe574ca84
commit bd3e4294fe
No known key found for this signature in database
GPG Key ID: 10F15E84852CB868
5 changed files with 76 additions and 14 deletions

View File

@ -27,6 +27,20 @@ TODO: 可以在单人游戏增加一个管理密码,只有密码输入正确才
当回答正确后,奖励物品.
还要增加选择题: select(最多9个选项,再多界面放不下)
```yml
quiz:
- title: "?"
type: "select"
options:
- Red
- Blue
- Green
answer: [1,2]
```
需要增加问题类别: 计算类型,自动出计算题
除法余数的处理? 如果有余数只允许最后一个操作符是除法.

View File

@ -84,6 +84,13 @@ quiz:
type: calc
forceInt: true # the result must be an integer
answer: "(Nn*n+n)/(Nn-n)"
- title: "howto select?"
type: "select"
options:
- Red
- Blue
- Green
answer: [1,2]
```
1. The `answer` supports the [Lua string pattern](https://www.lua.org/pil/20.2.html) enclosed in "/" slashes.
@ -95,3 +102,6 @@ quiz:
* `[1-39]`: the set(range) of numbers(from 1 to 3) and number 9
* `[+-*/]`: the set(range) of operations.
* Note: The division operation must be the last!
3. Multiple choice questions supported(`type: select`)
* `options`: list items to be selected.
* `answer`: the sequence number of the correct option.

View File

@ -125,6 +125,10 @@ local function execute(s, useMod)
return v
end
math.randomseed(os.clock()*100000000000)
for i=1,math.random(3,15) do
math.random()
end
return {
remove_dup_str = remove_dup_str,

View File

@ -62,25 +62,37 @@ local function setUsedTime(playerName, value)
end
quiz.setUsedTime = setUsedTime
local function get_formspec(player_name, title, desc)
local text = esc(S("Hi, @1", player_name) .. "," .. S("the challenge begins!"))
title = esc(title or "")
if desc then desc = esc(desc or "") end
local question = esc(S("Question"))
local answer = esc(S("Answer"))
local function get_formspec(player_name, quiz)
player_name = esc(S("Hi, @1", player_name) .. "," .. S("the challenge begins!"))
local title = esc(quizzes.getTitle(quiz) or "")
local desc = esc(quiz.desc or "")
local questionStr = esc(S("Question"))
local answerStr = esc(S("Answer"))
local formspec = {
"formspec_version[4]",
"size[10,9]",
"label[0,0.2;", text, "]",
"box[0.4,1.1;9.2,4.25;#999999]",
"textarea[0.4,1.1;9.2,4.25;;",question, ";" , title, "]",
"field[0.4,6;9.2,0.9;answer;", answer, ";]",
"textarea[0.4,1.1;9.2,4.25;;",questionStr, ";" , title, "]",
}
if desc then formspec[#formspec+1] = "label[0.4,7.2;".. desc .."]" end
if desc then formspec[#formspec+1] = "label[1.8,0.9;(".. desc ..")]" end
formspec[#formspec+1] = "button_exit[3.2,8;3.5,0.8;ok;Ok]"
local options = quiz.options
if quiz.type == "select" and options then
local x = 0.5
local y = 5.9
for i=1,#options do
x = x + (i-1) % 3 * 3.5
y = y + math.modf((i-1) % 3) * 0.6
formspec[#formspec+1] = "checkbox[".. x .. "," .. y .. ";opt".. i .. ";" .. options[i] .. "]"
end
else
formspec[#formspec+1] = "field[0.4,6;9.2,0.9;answer;" .. answerStr .. ";]"
end
-- table.concat is faster than string concatenation - `..`
return table.concat(formspec, "")
end
-- local motddesc = conf("get", "desc") or "terms"
@ -198,7 +210,20 @@ local function grantPriv(playerName)
end
end
local function checkAnswer(playerName, answer, quiz)
local function checkAnswer(playerName, fields, quiz)
local answer
local options = quiz.options
if quiz.type == "select" and #options then
answer = {}
for i=1, #options do
if fields["opt" .. i] then
table.insert(answer, i)
end
end
else
answer = fields.anwser
end
-- local playerName = aPlayer:get_player_name()
local result, errmsg = quizzes.check(playerName, answer, quiz)
if errmsg then
@ -253,13 +278,13 @@ local function openQuizView(playerName)
if fields.quit == minetest.FORMSPEC_SIGTIME then
local vQuiz, vErrmsg = quizzes.getCurrent(playerName)
if vQuiz and not vErrmsg then
minetest.update_form(playerName, get_formspec(playerName, quizzes.getTitle(vQuiz), vQuiz.desc))
minetest.update_form(playerName, get_formspec(playerName, vQuiz))
return
end
-- local result = checkAnswer(playerName, fields.answer, vQuiz)
end
dialogClosed = true
checkAnswer(playerName, fields.answer, quiz)
checkAnswer(playerName, fields, quiz)
-- minetest.update_form(playerName, get_formspec(playerName, quiz.title, quiz.desc))
-- elseif fields.answer and quiz.answer == fields.answer then
-- minetest.get_form_timer(playerName).stop()
@ -270,7 +295,7 @@ local function openQuizView(playerName)
end
if (type(quiz) == "table") then
dialogClosed = false
minetest.create_form(nil, playerName, get_formspec(playerName, quizzes.getTitle(quiz), quiz.desc), on_close)
minetest.create_form(nil, playerName, get_formspec(playerName, quiz), on_close)
-- minetest.get_form_timer(playerName).start(1)
return true
end

View File

@ -9,6 +9,8 @@ local settings = quiz.settings
local toBool = dofile(MOD_PATH .. "to_bool.lua")
local playerAttrs = dofile(MOD_PATH .. "player_attrs.lua")
local calcType = dofile(MOD_PATH .. "calc_type.lua")
local isArrayEqu = dofile(MOD_PATH .. "is_array_equ.lua")
local Quizzes = {}
-- record player last answered time
local lastAnswered = {}
@ -131,7 +133,7 @@ local function check(playerName, answer, quiz)
if quiz then
local attrs = player:get_meta()
local quizId= id(quiz)
if (type(answer) == "string") and answer ~= "" then
if answer ~= "" then
local vRealAnswer = quiz.answer
local vType = quiz["type"] or type(vRealAnswer)
if vType == "number" then
@ -150,6 +152,13 @@ local function check(playerName, answer, quiz)
else
answer = tonumber(answer)
end
elseif vType == "select" then
answer = table.concat(answer, ",")
if type(vRealAnswer) == "table" then
vRealAnswer = table.concat(table.sort(vRealAnswer), ",")
else
vRealAnswer = "" .. vRealAnswer
end
end
local ok = false
if vType == "string" and string.sub(vRealAnswer, 1, 1) == "/" and string.sub(vRealAnswer, -1) == "/" then