我是编程新手,通过学习一些在线课程一直在学习 Swift。在其中一门课程中,我们构建了一个基本的琐事游戏,我一直在尝试通过自己编写代码来改进它(最好的学习方式!)。
最近我遇到了所谓的 Fisher-Yates 洗牌,经过多次试验和错误(在堆栈溢出社区的帮助下),我能够使用 Swift Gameplaykit 中的 GKRandomSource 来洗牌我的琐事问题,以便他们被随机询问. 这是对我使用的原始 arc4random 代码的改进,因为随机播放从整个问题池中删除了已经提出的问题,从而确保它们不会重复(至少在 iOS9 中)。
这在会话中运行良好,但是一旦用户退出应用程序并重新启动它,随机播放将从头开始。所以我正在寻找一种方法让应用程序“记住”会话之间已经提出的问题。我的研究使我产生了播种的想法,我一直试图让它与我的 GKRandomSource 代码一起使用,但我显然遗漏了一些东西。
任何建议等都会受到欢迎 - 特别是因为我不完全确定这种“播种”方法将实现我的最终目标,即不重复在应用程序的前几节中已经提出的问题。
以下是我认为是我修改后的代码的相关部分。
所有问题和可能的答案选择都存储在 .json 文件中,如下所示:
{
"id" : "1",
"question": "Earth is a:",
"answers": [
"Planet",
"Meteor",
"Star",
"Asteroid"
],
"difficulty": "1"
}
我使用以下代码加载 .json 文件:
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)
}
下面是我最近尝试实现所有问题的洗牌并在以后的会话中复制它的代码):
var allEntries : NSArray!
var shuffledQuestions: [AnyObject]!
var nextQuestion = -1
var mySeededQuestions : [AnyObject]
loadAllQuestionsAndAnswers()
if #available(iOS 9.0, *) {
let lcg = GKLinearCongruentialRandomSource(seed: mySeededQuestions)
let shuffledQuestions = lcg.arrayByShufflingObjectsInArray(allEntries)
nextQuestion++
loadQuestion(nextQuestion)
// Fallback on earlier versions
}else{
let randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
loadQuestionPreiOS9(randomNumber)
}
我至少知道上面的代码有问题,但我很茫然。我也在想,也许我在储存种子方面错过了一步?
为了完整起见,我使用一个标签来显示问题,并使用四个图像来显示可能的答案,使用以下代码:
func loadQuestion(index : Int)
{
let entry : NSDictionary = shuffledQuestions[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()
}
func loadQuestionPreiOS9(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")
if #available(iOS 9.0, *) {
nextQuestion++
loadQuestion(nextQuestion)
}else{
let randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
loadQuestionPreiOS9(randomNumber)
}
我知道我的编码可能非常冗长且不必要,但在最新的改进之前,它一直运行良好,我实际上了解其中的大部分内容(我想!)