我正在制作一个测验应用。该应用程序使用.json文件作为'数据库'的问题和答案。这个.json文件如下所示......
{
"id" : "1",
"question": "Earth is a:",
"answers": [
"Planet",
"Meteor",
"Star",
"Asteroid"
],
"difficulty": "1"
}
......只是继续讨论500多个问题。
我使用以下代码随机显示问题:
let randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
LoadQuestion(randomNumber)
这项工作很好,但因为它会随机选择问题,我发现问题的重复性过于频繁(即使我有500多个问题!)。
我对此进行了广泛的研究,并认为我读得太多,因为我现在很困惑。我已经阅读了有关保存所提问题索引以及尝试使用NSUserDefault的播种问题。
简而言之,我如何修改代码以实现以下结果之一:
以下是我认为相关的代码:
LoadAllQuestionsAndAnswers()
let randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
LoadQuestion(randomNumber)
func LoadAllQuestionsAndAnswers()
{
let path = NSBundle.mainBundle().pathForResource("content", ofType: "json")
let jsonData : NSData = NSData(contentsOfFile: path!)!
allEntries = (try! NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers)) as! NSArray
//println(allEntries)
}
func LoadQuestion(index : Int)
{
let entry : NSDictionary = allEntries.objectAtIndex(index) as! NSDictionary
let question : NSString = entry.objectForKey("question") as! NSString
let arr : NSMutableArray = entry.objectForKey("answers") as! NSMutableArray
//println(question)
//println(arr)
labelQuestion.text = question as String
let indices : [Int] = [0,1,2,3]
//let newSequence = shuffle(indices)
let newSequence = indices.shuffle()
var i : Int = 0
for(i = 0; i < newSequence.count; i++)
{
let index = newSequence[i]
if(index == 0)
{
// we need to store the correct answer index
currentCorrectAnswerIndex = i
}
let answer = arr.objectAtIndex(index) as! NSString
switch(i)
{
case 0:
buttonA.setTitle(answer as String, forState: UIControlState.Normal)
break;
case 1:
buttonB.setTitle(answer as String, forState: UIControlState.Normal)
break;
case 2:
buttonC.setTitle(answer as String, forState: UIControlState.Normal)
break;
case 3:
buttonD.setTitle(answer as String, forState: UIControlState.Normal)
break;
default:
break;
}
}
buttonNext.hidden = true
// we will need to reset the buttons to reenable them
ResetAnswerButtons()
}
@IBAction func PressedButtonNext(sender: UIButton) {
print("button Next pressed")
let randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
LoadQuestion(randomNumber)
}
答案 0 :(得分:3)
如果我理解你的要求:
实现此目标的一种快捷方法是使用NSUserDefaults
来跟踪PRNG中(伪)随机数的顺序和值。通过这种方式,您可以通过重放以前的骰子卷来实例化关于即时的可用问题数组,并按照正确的顺序从池中删除这些问题。
这也让你可以将PRNG作为一个黑盒子来处理,而不是关心播种和重播。
此外,请务必从当前池中删除任何骰子掷骰子中的所选问题。
旁注:您没有遵循命名约定 - 例如,函数将以小写字母开头。
为了您自己的良好和可读性,请遵循流行的惯例,至少在与他人共享您的代码时。更好的是,所有的时间。
修改强>:
更详细:
NSUserDefaults
可以轻松为您节省少量数据。如果你只是想记住一系列数字,那就是去处理。假设您的数据在如下的实例变量中是helt:
var questions : [Question] = // load the questions - carefully, see below.
您可以轻松删除PSNG的问题( p seudo- r andom n umber g enerator)选择如此:
let randomNumber = Int(arc4random_uniform(UInt32(questions.count)))
questions.removeAtIndex(randomNumber)
因此,下一个骰子滚动(例如你的PSNG的调用)保证不会选择已经问过的问题,因为它不再是从它选择的可用问题池中。
这种方法确实需要您以正确的顺序保存所有随机数,以“重播”实例化新实例之前发生的事情(例如,因为应用程序已重新打开)。这是NSUserDefaults
' setObject:forKey:
和objectForKey:
在最初加载问题和“记住”每个新骰子时发挥作用的地方。
我希望,这涵盖了您之前可能不了解的内容。