Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Nick Kohrn
38,025 PointsHow Do I Prevent Same Random Color and Random Fact From Showing Consecutively in Swift?
I have completed the Build a Simple iPhone App with Swift course, and now I would like to add a feature to it. I want to have functionality that prevents the same background color and same interesting fact from showing consecutively. I have been working on this, but I just cannot seem to figure out the correct way. Any help would be much appreciated!
//
// ColorWheel.swift
// FunFacts
//
// Created by Nick Kohrn on 9/18/14.
// Copyright (c) 2014 Nick Kohrn. All rights reserved.
//
import Foundation
import UIKit
struct ColorWheel {
let colorsArray = [
UIColor(red: 90/255.0, green: 187/255.0, blue: 181/255.0, alpha: 1.0), //teal color
UIColor(red: 222/255.0, green: 171/255.0, blue: 66/255.0, alpha: 1.0), //yellow color
UIColor(red: 223/255.0, green: 86/255.0, blue: 94/255.0, alpha: 1.0), //red color
UIColor(red: 239/255.0, green: 130/255.0, blue: 100/255.0, alpha: 1.0), //orange color
UIColor(red: 77/255.0, green: 75/255.0, blue: 82/255.0, alpha: 1.0), //dark color
UIColor(red: 105/255.0, green: 94/255.0, blue: 133/255.0, alpha: 1.0), //purple color
UIColor(red: 85/255.0, green: 176/255.0, blue: 112/255.0, alpha: 1.0), //green color
]
func randomColor() -> UIColor {
var unsignedArrayCount = UInt32(colorsArray.count)
var unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
var randomNumber = Int(unsignedRandomNumber)
return colorsArray[randomNumber]
}
}
//
// FactBook.swift
// FunFacts
//
// Created by Nick Kohrn on 9/18/14.
// Copyright (c) 2014 Nick Kohrn. All rights reserved.
//
import Foundation
struct FactBook {
let factsArray = [
"Ants stretch when they wake up in the morning.",
"Ostriches can run faster than horses.",
"Olympic gold medals are actually made mostly of silver.",
"You are born with 300 bones; by the time you are an adult you will have 206.",
"It takes about 8 minutes for light from the Sun to reach Earth.",
"Some bamboo plants can grow almost a meter in just one day.",
"The state of Florida is bigger than England.",
"Some penguins can leap 2-3 meters out of the water.",
"On average, it takes 66 days to form a new habit.",
"Mammoths still walked the earth when the Great Pyramid was being built." ]
func randomFact() -> String {
var unsignedArrayCount = UInt32(factsArray.count)
var unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
var randomNumber = Int(unsignedRandomNumber)
return factsArray[randomNumber]
}
}
//
// ViewController.swift
// FunFacts
//
// Created by Nick Kohrn on 9/18/14.
// Copyright (c) 2014 Nick Kohrn. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var funFactLabel: UILabel!
@IBOutlet weak var funFactButton: UIButton!
let factBook = FactBook()
let colorWheel = ColorWheel()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
funFactLabel.text = factBook.randomFact()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func showFunFact() {
var randomColor = colorWheel.randomColor()
var randomFact = factBook.randomFact()
view.backgroundColor = randomColor
funFactButton.tintColor = randomColor
funFactLabel.text = randomFact
}
}
5 Answers
Stone Preston
42,016 Pointsuse a variable to store the value of the previousRandomIndex. then in your randomFact/color function use a do while loop to generate the number. in the while condition compare the randomNumber that was generated to the previous randomNumber. if you get the same twice in a row it will keep generating a number until its different.
import Foundation
struct FactBook {
//this will hold the random index
var previousRandomIndex = 0
let factsArray = [
"Ants stretch when they wake up in the morning.",
"Ostriches can run faster than horses.",
"Olympic gold medals are actually made mostly of silver.",
"You are born with 300 bones; by the time you are an adult you will have 206.",
"It takes about 8 minutes for light from the Sun to reach Earth.",
"Some bamboo plants can grow almost a meter in just one day.",
"The state of Florida is bigger than England.",
"Some penguins can leap 2-3 meters out of the water.",
"On average, it takes 66 days to form a new habit.",
"Mammoths still walked the earth when the Great Pyramid was being built." ]
func randomFact() -> String {
var unsignedArrayCount = UInt32(factsArray.count)
var unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
//this will run at least once. it will keep generating a random number until you get one thats not the same as the previous
do {
var randomNumber = Int(unsignedRandomNumber)
} while randomNumber == previousRandomIndex
previousRandomIndex = randomNumer
return factsArray[randomNumber]
}
}
Nick Kohrn
38,025 PointsStone,
Thank you so much! I was using a variable to store the index, however, I was using if-statements rather than a loop. No wonder I was generating the same colors/facts consecutively.
Thanks again, sir!
Stone Preston
42,016 Pointsno problem
Nick Kohrn
38,025 PointsWhen I go to assign ``` previousRandomIndex = randomNumber
I keep getting an error that says "Cannot assign to 'previousRandomIndex' in 'self'". I am not quite sure how to fix this.
Thomas Sirchia
5,683 PointsI tried implementing the above code and am also seeing that error. Stone Preston, how can this be resolved?
Stone Preston
42,016 Pointsare you sure you declared previousRandomIndex as a variable and not a constant?
Thomas Sirchia
5,683 PointsSo when I set up my code similarly to your first solutions I got the three errors that I added as comments below.
import Foundation
struct FactBook {
var previousRandomIndex = 0
let factsArray = [
"Ants stretch when they wake up in the morning.",
"Ostriches can run faster than horses.",
"Olympic gold medals are actually made mostly of silver.",
"You are born with 300 bones; by the time you are an adult you will have 206.",
"It takes about 8 minutes for light from the Sun to reach Earth.",
"Some bamboo plants can grow almost a meter in just one day.",
"The state of Florida is bigger than England.",
"Some penguins can leap 2-3 meters out of the water.",
"On average, it takes 66 days to form a new habit.",
"Mammoths still walked the earth when the Great Pyramid was being built."
]
func randomFact() -> String {
var unsignedArrayCount = UInt32(factsArray.count)
var unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
do {
var randomNumber = Int(unsignedRandomNumber)
} while randomNumber == previousRandomIndex //use of unresolved indentifier 'randomNumber'
previousRandomIndex = randomNumber //use of unresolved indentifier 'randomNumber'
return factsArray[randomNumber] //use of unresolved indentifier 'randomNumber'
}
}
Then I tried declaring random number outside of the do while loop to change the scope of the variable, and got the same error as Nick.
func randomFact() -> String {
var randomNumber = 0
var unsignedArrayCount = UInt32(factsArray.count)
var unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
do {
randomNumber = Int(unsignedRandomNumber)
} while randomNumber == previousRandomIndex
previousRandomIndex = randomNumber //Cannot assign to "previousRandomIndex' in 'self'
return factsArray[randomNumber]
}
Thanks for your help Stone!
Greg Melson
3,037 PointsTo solve your error I'd try to move the
var previousRandomIndex = 0
to above your Struct declaration and I'd also put the randomNumber declaration there too
i.e.
var previousRandomIndex = 0 var randomNumber = 0
struct FactBook {
I hope this helps, I'm just learning too, but I thought I'd add this
I also think that the var unsignedRandomNumber = arc4random_uniform(unsignedArrayCount) should be put into your array to ensure it doesn't get stuck in a never ending loop?
i.e. do { var unsignedRandomNumber = arc4random_uniform(unsignnedNumberOfJokes) randomNumber = Int(unsignedRandomNumber) } while randomNumber == previousRandomIndex
Let me know if that works for you :)
josephsherratt
iOS Development Techdegree Graduate 17,032 PointsCan someone post the solution without any errors?