Reputation: 253
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.
}
}
Upvotes: 0
Views: 121
Reputation: 285069
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 ;-)
Upvotes: 2
Reputation: 131408
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
.
Upvotes: 2
Reputation: 1519
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.
Upvotes: 2