Skip to main content
5 of 5
replaced http://stackoverflow.com/ with https://stackoverflow.com/

Multiple Choice Guessing Game

I've built an app for members of an organization I'm in--the app shows the picture of a member with four multiple choice buttons, and the user then tries to guess the member's name. Pretty simple, but this is one of my first major apps.

import UIKit
import Foundation

class ViewController: UIViewController {

    @IBOutlet weak var memberPic: UIImageView!
    @IBOutlet weak var scoreLabel: UILabel!
    @IBOutlet weak var firstChoice: UIButton!
    @IBOutlet weak var secondChoice: UIButton!
    @IBOutlet weak var thirdChoice: UIButton!
    @IBOutlet weak var fourthChoice: UIButton!
    @IBOutlet var choiceButtons: Array<UIButton>?
    
    @IBOutlet weak var playAgainButton: UIButton!
    
    @IBAction func guessChosen(sender: AnyObject) {
        checkAnswer(sender)
    }
    let redButton = UIImage(named: "red_button") as UIImage?
    let greenButton = UIImage(named: "green_button") as UIImage?
    let yellowButton = UIImage(named: "yellow_button") as UIImage?
    var rightAnswer:FMResultSet?
    var databasePath:String?
    var correctName:String?
    var correctButton:UIButton?
    var memberDatabase:FMDatabase?

    var score = 0
    var correctRun = 0
    var turnCount = 0
    var queryParameters = ["None"] //"None" to exclude empty pics, names to be added
    var queryHoles = "" //append "?" for each already-seen name
    
    @IBAction func playAgainPressed(sender: AnyObject) {
        resetGame()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: "background.jpeg")!)
        let path = NSBundle.mainBundle().pathForResource("members", ofType:"sqlite3")
        playAgainButton.hidden = true
        memberDatabase = FMDatabase(path: path)
        if memberDatabase!.open(){
            println("database is ready")
        } else {
            println("error finding database")
        }
        scoreLabel.text = "\(score)"
        resetGame()
        //close database?
        
    }
    

    func resetGame(){
        score = 0
        turnCount = 0
        correctRun = 0
        playAgainButton.hidden = true
        queryParameters = ["None"]
        queryHoles = ""
        displayRandomMember()
    }
    
    func displayRandomMember(){
        for button in choiceButtons! {
            button.setBackgroundImage(yellowButton, forState: .Normal)
            button.userInteractionEnabled = true
        }
        
        let querySQL = "SELECT name, picture_name from member_data where picture_name is not ? and name not in (\(queryHoles)) ORDER BY RANDOM() LIMIT 1";
        rightAnswer = memberDatabase!.executeQuery(querySQL, withArgumentsInArray: queryParameters)
        rightAnswer!.next()
        correctName = rightAnswer!.stringForColumn("name")!

        let correctPicture = rightAnswer!.stringForColumn("picture_name")
        let wrongAnswerSQLQuery = "SELECT name from member_data where picture_name is not ? and name is not ? ORDER BY RANDOM() LIMIT 3" //gets three wrong answers
        let wrongAnswersResultSet:FMResultSet = memberDatabase!.executeQuery(wrongAnswerSQLQuery, withArgumentsInArray: ["None", correctName!])
        var wrongAnswersArray:[String] = []
        while wrongAnswersResultSet.next() == true {
            wrongAnswersArray.append(wrongAnswersResultSet.stringForColumn("name"))
        }
        var wrongButtons = [firstChoice, secondChoice, thirdChoice, fourthChoice]
        correctButton = wrongButtons.removeAtIndex(Int(arc4random_uniform(4)))
        rotateButton(correctButton!, newname: correctName!)
        for i in 0..<wrongButtons.count{
            rotateButton(wrongButtons[i], newname:wrongAnswersArray[i])
        }

        memberPic.image = UIImage(named: correctPicture)
        queryParameters.append(correctName!) //keep track of names already seen this game
        if (count(queryHoles) > 0) {
            queryHoles += (",?") //if already has one '?'
        } else {
            queryHoles += ("?")
        }
        return
    }
    
    func checkAnswer(sender:AnyObject){
        let selectedAnswer = sender.currentTitle!
        for button in choiceButtons! {
            button.userInteractionEnabled = false
        }
        correctButton!.setBackgroundImage(greenButton, forState: .Normal)
        if selectedAnswer! == correctName! {
            correctRun += 1
            score += (100 * correctRun)
            scoreLabel.text = "\(score)"
        } else {
            sender.setBackgroundImage(redButton, forState: .Normal)
            correctRun = 0
        }
        let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC * 1))
        dispatch_after(delayTime, dispatch_get_main_queue()){
        
            self.turnCount += 1
            if self.turnCount < 10 {
                self.displayRandomMember()
            } else {
                self.checkHighScore()
                self.playAgainButton.hidden = false
            }
        }
        
    }

    func checkHighScore(){
        let defaults = NSUserDefaults.standardUserDefaults()
        var oldHighScore = defaults.integerForKey("highScore")
        if (score > oldHighScore) {
            defaults.setInteger(score, forKey: "highScore")
        }
    }
    
    func rotateButton(button:UIButton, newname:String) {
        
        UIView.transitionWithView(
            button,
            duration: 0.5,
            options: UIViewAnimationOptions.TransitionFlipFromLeft | .AllowAnimatedContent,
            animations: {button.setTitle(newname, forState:.Normal)},
            completion: nil )
        }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

Questions:

  • I feel like I am supposed to close the database at some point, but I'm not sure where.
  • I hate how I query to make sure I'm not repeating names within a round (10 questions). I append "?" to queryholes and the name to queryParameters; it works, and it's the answer I got from this question but it feels so hackish.

enter image description here