This is the code i have made so far. I have two words, red and black. when the red button is pressed i want an if statement that tells the user if they are wrong or right. The code picks randomly either red or black but i can't seem to figure how to match the if statement with word that is randomly picked.
#IBAction func red(sender: AnyObject) {
let array = ["Red", "Black"]
let randomIndex = Int(arc4random_uniform(UInt32(array.count)))
print(array[randomIndex])
if array == Int("Red") {
colorLabel.text = "You're right"
} else {
colorLabel.text = "Wrong! It was a Black"
}
}
There's a few things wrong with your code...
You don't want to pass a string into an Int initializer, or you'll get nil:
Int("Red") // don't do this
Next, you're matching on your entire array anyway which won't work either:
if array == Int("Red") // will never == true
You want to match based on whats in your print statement:
var word = array[randomIndex] // set up a new variable
Solution
You're going to want to try something more like this:
#IBAction func red(sender: AnyObject) {
let array = ["Red", "Black"]
let randomIndex = Int(arc4random_uniform(UInt32(array.count)))
var word = array[randomIndex]
if word == "Red" {
colorLabel.text = "You're right"
} else {
colorLabel.text = "Wrong! It was a Black"
}
}
Related
I'm building swift quiz app I want to show random questions with no repeat.
var sorular: Array = ["soru1","soru2","soru3","soru4","soru5"]
var gorulensoru = [Int]()
var sayac: Int = 0
var sorularcevaplar = ["D","Y","D","Y","D"]
var cevaplar: Array<Any> = []
var dogru: Int = 0
var yanlis: Int = 0
func chooseRandom() -> String {
if gorulensoru.count == sorular.count { return "" }
let randomItem = Int(arc4random() % UInt32(sorular.count)) //get
if (gorulensoru.contains(randomItem)) {
return chooseRandom()
}
let requiredItem = sorular[randomItem]
gorulensoru.append(randomItem)
return requiredItem
}
override func viewDidLoad() {
super.viewDidLoad()
soruText.text = chooseRandom()
}
What is the problem in my code? I'm tried insert selected random item to inside gorulensoru array but it shows again selected item
if (gorulensoru.contains(randomItem)) {
return chooseRandom()
}
This statement doesn't run.
Your code only runs once.
Also, you shouldn't include potential infinite recursive calls because it can easily get to a level where it causes a hang or crash.
Use shuffle() and then iterate over the array.
Change this and it may work:
let requiredItem = sorular[randomItem]
gorulensoru.append(requiredItem)
I am using iterators to cycle through an array of flash cards, but the iterator is going every other, for example, I tested it by entering in numbers 1-7 as new cards (in order) but when I flip through the deck it only displays 2, then 4, then 6, then back to 2. When I print out the deckIterator in the functions it gives a corresponding integer back, so for card 2 the iterator prints 2. I'm not sure If i'm using the iterator correct, could anyone point me in the right direction?
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
}
func fetchData() {
deckArray.removeAll()
deckIterator = nil
do {
fetched = try context.fetch(Card.fetchRequest())
for each in fetched {
let term = each.term
let definition = each.definition
termLabel.text = each.term!
definitionLabel.text = each.definition!
let Card = card(term: term!, definition: definition!)
deckArray.append(Card)
}
} catch {
print(error)
}
deckIterator = deckArray.makeIterator()
}
#IBAction func leftSwipe(_ sender: UISwipeGestureRecognizer) {
getNextCardPlease()
self.definitionLabel.isHidden = true
alreadyFlipped = false
}
func getNextCardPlease(){
if(deckIterator?.next() == nil){
fetchData()
} else {
let next = deckIterator?.next()
termLabel.text = next?.term
definitionLabel.text = next?.definition
}
}
Every time you call next(), we iterate. So every call to getNextCardPlease iterates twice. Count them:
if(deckIterator?.next() == nil){ // 1
fetchData()
} else {
let next = deckIterator?.next() // 2
The problems was once if(deckIterator?.next() == nil) gets called, the iterator iterates. Iterators do not work like linked lists.
My code below is trying to index every new entry to the array when the button is pressed. So automatically sort the element when the button is pressed.
var arrayOfInt = [Int]()
#IBAction func submitText(_ sender: Any) {
if let text = enterText.text {
if let number = Int(text) {
var index = 0
for num in arrayOfInt {
if num > number {
arrayOfInt.insert(number, at: index)
break
}
index += 1
}
print(arrayOfInt)
} else {
print("Please enter number")
}
}}
When printed this is what is coming out []. None of the numbers are printed.
Initially arrayOfInt is empty array. So it will never go inside this as the array is empty
for num in arrayOfInt {
//Whatever is here
}
Your logic is also wrong for whatever you are trying to achieve.
Array has already sort(by:(Element, Element) -> Bool) method
You better write the code as follows:-
var arrayOfInt = [Int]()
#IBAction func submitText(_ sender: Any) {
if let text = enterText.text , let number = Int(text) {
arrayOfInt.append(number)
arrayOfInt.sort { return $0 > $1 } //Modify accordingly the order you want
print(arrayOfInt)
} else {
print("Please enter number")
}
}
Your arrayOfInt variable has no elements, it's empty... so the for loop won't iterate over a zero index array, it would have no sense... that's why the code inside the curly brackets is never executed.
If you would have debugged your code with either a breakpoint or using a print statement this issue would have been shown by itself.
I would avoid using if let every time the guard statement could solve the same. Basically because it looks more readable and it's kind of the Swift approach... at the same time you are avoiding the pyramid of doom.
My suggestion would be:
var arrayOfInt = [Int]()
#IBAction func submitText(_ sender: Any) {
guard let text = enterText.text else {
print("Please enter a number")
return
} // guard
guard let number = Int(text) else {
print("Can't creates an integer value from the given string.")
return
} // guard
arrayOfInt.append(number)
arrayOfInt.sort() // From lowest to highest by default.
//arrayOfInt.sort { $0 < $1 } // From lowest to highest using a higher order function.
//arrayOfInt.sort { $0 > $1 } // From highest to lowest using a higher order function.
} // submitText
Hello I am trying to take an array I have and update a label to display each element in the array one second apart. An example would be me having the array [3,6,2] and my label would show 3 then wait a second and show 6 then wait a second and show 2. I've seen many NSTimer examples with update functions doing things like this but only with an incrementation on a number, never trying to parse an array. Can anyone help?
Update
I am calling my timer in a UIButton and am running into a problem. The timer works fine but my code in the button function under my timer runs before the timer and update function. My code below generates a random array of numbers then should display them one second apart. It is doing this correct but my print statement under my timer is running before it updates and displays the numbers in the textbook. I do not know why? Is the timer running on a different thread?
func updateCountdown() {
if(numbersIndex <= numberLimit){
self.counter.text = String(numbers[numbersIndex])
}else if(numbersIndex == numberLimit+1){
self.counter.text = ""
}else{
timer!.invalidate()
timer=nil
}
numbersIndex+=1
}
#IBAction func startButton(_ sender: AnyObject){
startB.setTitle("", for: .normal)
var highestLength = 3
//for trialNumber in 0...11{
var numberSequence = Array(repeating:11, count: highestLength)
for count in 0...highestLength-1{
var randomNumber = Int(arc4random_uniform(10))
if(count>0){
while(numberSequence.contains(randomNumber) || randomNumber-1 == numberSequence[count-1]){
randomNumber = Int(arc4random_uniform(10))
}
}
numberSequence[count] = randomNumber
}
print(numberSequence)
self.numbers = numberSequence
self.numbersIndex = 0
self.numberLimit = numberSequence.count-1
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateCountdown), userInfo: nil, repeats: true)
print("this should be last")
//do other stuff too
//}
}
you can do something like this.
var counter = 0
var list: [String] = ["Eggs", "Milk"]
override func viewDidLoad() {
super.viewDidLoad()
var timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
}
func update() {
label.text = "\(list[counter])"
counter += 1
if (counter >= list.count) {
counter = 0
}
}
this is assumming the name of you Label is label
I'm trying to make a memory game where I apply images to 12 different buttons and check if the images are the same when 2 buttons are showing.
-------------------FINISHED FORM?-------------------------
Here is a try at Duncan C's suggestion;
func setImages() {
var values = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6]
values.shuffleInPlace()
button1.tag = values[0]
button2.tag = values[1]
button3.tag = values[2]
button4.tag = values[3]
button5.tag = values[4]
button6.tag = values[5]
button7.tag = values[6]
button8.tag = values[7]
button9.tag = values[8]
button10.tag = values[9]
button11.tag = values[10]
button12.tag = values[11]
}
#IBAction func buttonPressed(sender: UIButton) {
var images : [UIImage] = [
UIImage(named:"ye1")!,
UIImage(named:"ye2")!,
UIImage(named:"ye3")!,
UIImage(named:"ye4")!,
UIImage(named:"ye5")!,
UIImage(named:"ye6")!,
UIImage(named:"ye7")!,
UIImage(named:"ye8")!,
UIImage(named:"ye9")!,
UIImage(named:"ye10")!,
UIImage(named:"ye11")!,
UIImage(named:"ye12")!
]
images.shuffleInPlace()
let integrera = (sender.tag - 1)
let imageString:String = String(format: "ye%i", integrera)
if !firstButtonAlreadyPresssed {
firstButtonValue = sender.tag //remember the button for later
firstButtonAlreadyPresssed = true
sender.setImage(UIImage(named: imageString), forState: .Normal)
}
else
//We already have a first button pressed.
if sender.tag == firstButtonValue {
sender.setImage(UIImage(named: imageString), forState: .Normal)
}
else {
let secondimage = (sender.tag)
let secondString : String = String(format: "ye%i", secondimage)
sender.setImage(UIImage(named: secondString), forState: .Normal)
}
firstButtonAlreadyPresssed = false //reset the "isFirstButton" flag for the next time.
}
}
Hmm, there are a bit of lengthy and repetitive code here I believe. You can just add all buttons to the same #IBAction func. So you can have one #IBAction func buttonPressed(sender: UIButton) rather than 12 like you have now (I think, since your function is called #IBAction func button1PRESSED(sender: AnyObject)). So when you first click a button you store the button, and also store if its the first or second button clicked. When you click the second button you check if it has the same UIImage as the first one clicked, otherwise you what ever it is you are supposed to do.
#IBAction func buttonPressed(sender: UIButton) {
if self.firstButtonStored == true {
if self.firstButton.image == sender.image {
// They are the same
} else {
// they are not the same
}
} else {
self.firstButtonStored = true
self.firstButton = sender
}
}
I would also recommend storing all the buttons in one OutletCollection (works like an array) rather than 12 buttons in self. And I would also use something else than UIImage to check if they are the same, not sure if this actually works since you need the image name and not the image itself to make a comparison. Let me know if you need help.
Don't, dont, DON'T create 12 separate variables, card1-card12 and 12 IBActions button1PRESSED-button12PRESSED. This kind of thing where you have lots of exactly the same thing where the only thing that changes is a value is a "code smell". It tells you you are doing it wrong.
Instead, you should find a way to do it where you can use the same IBAction for all the buttons, and index into the array rather than having 12 separate variables.
I would suggest using tags on your buttons. Have button 1 use tag 1, button 2 use tag 2, etc.
Then in your IBAction, fetch the tag from the button and use that to figure out which button was pressed and what to do.
You will also need a flag that tells you if this was the first button pressed or the second, so you can tell if you need to test for matches (if it's the 2nd one) or just remember which one was pressed (if this is the first button pressed.)
var firstButtonValue: Int
var firstButtonAlreadyPresssed: Bool
#IBAction func buttonPressed(sender: UIButton)
{
if !firstButtonAlreadyPresssed
{
firstButtonValue = sender.tag //remember the button for later
firstButtonAlreadyPresssed = true
}
else
{
//We already have a first button pressed.
if sender.tag == firstButtonValue
{
//right answer. Handle it.
}
else
{
//wrong answer. Handle it.
}
firstButtonAlreadyPresssed = false //reset the "isFirstButton" flag for the next time.
}
}
You could have an array of the images to use for each value, and then fetch that image based on the value of firstButtonValue or sender.tag.
An approach, not a full solution
Create a struct Card with value and index properties and make it Equatable by value.
You can add more properties like done, status, image or whatever.
struct Card : Equatable, CustomStringConvertible {
let value : Int
let index : Int
var description : String { return "Card \(index)"}
}
func ==(lhs: Card, rhs: Card) -> Bool
{
return lhs.value == rhs.value
}
Shuffle the values and create an array of 12 cards
var values = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6]
values.shuffleInPlace()
var cards = [Card]()
for (index, value) in values.enumerate() {
cards.append(Card(value: value, index: index))
}
Implement a method to find the corresponding card
func twinCard(card : Card) -> Card {
return cards.filter({$0 == card && $0.index != card.index}).first!
}
In Interface Builder assign tags from 0 to 11 to the twelve buttons and connect all buttons to the same #IBAction
#IBAction func buttonPressed(sender: UIButton) {
let tag = sender.tag
let chosenCard = cards[tag]
let otherCard = twinCard(chosenCard)
// The following depends on the design of the UI
// for example get the corresponding button by viewWithTag(otherCard.index)
// or use an array which holds the button references.
...
}
Don't shuffle the view, shuffle the model ;-)