致命错误:索引超出范围(UIPickerView)

时间:2017-05-23 00:30:31

标签: swift uipickerview

我有一个用于玩游戏Go Fish的UIPickerView,因此其中的数据不断变化。在对阵列进行一些选择后,我最终在控制台中得到错误“致命错误:索引超出范围”,并在另一行上出现错误“thread 1 exc_bad_instruction(code = exc_i386_invop subcode = 0x0)”。任何关于导致这种情况以及如何解决问题的想法。

代码:

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource    {

    ///Main Section///

    //Game
    @IBOutlet weak var GameCardsLeft: UILabel!

    //CPU
    @IBOutlet weak var CPUCardsLeft: UILabel!
    @IBOutlet weak var CPUPairs: UILabel!

    //Player
    @IBOutlet weak var UserPairs: UILabel!
    @IBOutlet weak var pickerView: UIPickerView!

    //Variables
    var deck = [Card]()

    //Creates a deck of cards
    func createDeck()   {
        var i = 0 //Suite
        while(i < 2)    {
            var s = "" //suite
            var x = 1 //Value
            if(i == 0)  {
                s = "Clubs"
            }/*   else if(i == 1) {
                s = "Spades"
            }   else if(i == 2) {
                s = "Diamonds"
            }*/   else    {
                s = "Hearts"
            }
            while(x < 14)   {
                let tempCard = Card()
                tempCard.value = x
                tempCard.suite = s
                tempCard.assignRank(value: tempCard.value)
                tempCard.setDescription(rank: tempCard.rank, suite: tempCard.suite)
                x += 1
                deck.append(tempCard)
            }
            i += 1
        }
    }

    //Shuffles the deck
    func shuffle()  {
        var tempDeck = [Card]()
        while deck.count > 0    {
            let random = Int(arc4random_uniform(UInt32(deck.count)))
            let card = deck.remove(at: random)
            tempDeck.append(card)
        }
        deck = tempDeck
    }


    ///Go Fish Section///
    var drawDeck = [Card]()
    var playerDeck = [Card]()
    var playerPairsArray = [Card]()
    var cpuDeck = [Card]()
    var cpuPairsArray = [Card]()
    var selectedCard = Card()
    var gameOver = false
    var randomIndex = 0

    func deal() {
        for card in deck    {
            if(playerDeck.count < 5)    {
                playerDeck.append(card)
            }   else if(cpuDeck.count < 5)  {
                cpuDeck.append(card)
            }   else    {
                drawDeck.append(card)
            }
        }
    }

    //Player draw card
    func playerDraw()   {
        if(playerDeck.count == 0)  {
            while(playerDeck.count != 7)   {
                if(drawDeck.count > 0)  {
                    playerDeck.append(drawDeck[0])
                    drawDeck.remove(at: 0)
                }   else    {
                    break
                }
            }
        }   else    {
            if(drawDeck.count > 0)  {
                playerDeck.append(drawDeck[0])
                drawDeck.remove(at: 0)
            }
        }
    }

    //CPU draw card
    func cpuDraw()   {
        if(cpuDeck.count == 0)  {
            while(cpuDeck.count != 7)   {
                if(drawDeck.count > 0)  {
                    cpuDeck.append(drawDeck[0])
                    drawDeck.remove(at: 0)
                }   else    {
                    break
                }
            }
        }   else    {
            if(drawDeck.count > 0)  {
                cpuDeck.append(drawDeck[0])
                drawDeck.remove(at: 0)
            }
        }
    }

    //Player's turn check cpu hand
    func checkCPUHand(selectedCard: Card)   {
        var x = 0
        while(x < cpuDeck.count)    {
            if(selectedCard.value == cpuDeck[x].value)  {
                playerDeck.append(cpuDeck[x])
                cpuDeck.remove(at: x)
                checkForPlayerPairs()
                return
            }   else    {
                x += 1
            }
        }
        playerDraw()
    }

    //CPU's turn check player hand
    func checkPlayerHand(selectedCard: Card)   {
        var x = 0
        while(x < playerDeck.count)    {
            if(selectedCard.value == playerDeck[x].value)  {
                cpuDeck.append(playerDeck[x])
                playerDeck.remove(at: x)
                checkForCPUPairs()
                return
            }   else    {
                x += 1
            }
        }
        cpuDraw()
    }

    //Check for player Pairs
    func checkForPlayerPairs()  {
        var i = 0
        var k = 0
        var pairFound = false
        while(i < playerDeck.count) {
            pairFound = false
            k = i + 1
            while(k < playerDeck.count) {
                if(playerDeck[i].value == playerDeck[k].value) {
                    pairFound = true
                    break
                }   else    {
                    k += 1
                }
            }
            if(pairFound)   {
                playerPairsArray.append(playerDeck[i])
                playerDeck.remove(at: k)
                playerDeck.remove(at: i)
            }   else    {
                i += 1
            }
        }
    }

    //Check for cpu pairs
    func checkForCPUPairs()  {
        var i = 0
        var k = 0
        var pairFound = false
        while(i < cpuDeck.count) {
            pairFound = false
            k = i + 1
            while(k < cpuDeck.count) {
                if(cpuDeck[i].value == cpuDeck[k].value) {
                    pairFound = true
                    break
                }   else    {
                    k += 1
                }
            }
            if(pairFound)   {
                cpuPairsArray.append(cpuDeck[i])
                cpuDeck.remove(at: k)
                cpuDeck.remove(at: i)
            }   else    {
                i += 1
            }
        }
    }

    /*  Start of PickerView Stuff   */

    //Returns the number of columns
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    //Returns the number of rows
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return playerDeck.count
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return playerDeck[row].description //Error is in this line(thread 1 exc_bad_instruction (code=exc_i386_invop subcode=0x0))
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)  {
        selectedCard = playerDeck[row]
        //have var = pickerData[row]
    }


    /*  End of PickerView Stuff */


    func organizeCardDeck() {
        playerDeck = playerDeck.sorted { $0.value < $1.value }
        cpuDeck = cpuDeck.sorted { $0.value < $1.value }
    }

    func start()    {
        createDeck()
        shuffle()
        shuffle()
        deal()
        organizeCardDeck()
        checkForPlayerPairs()
        checkForCPUPairs()
        GameCardsLeft.text = "\(drawDeck.count)"
        CPUCardsLeft.text = "\(cpuDeck.count)"
        CPUPairs.text = "\(cpuPairsArray.count)"
        UserPairs.text = "\(playerPairsArray.count)"
    }

    func checkGameOver()    {
        if(cpuDeck.count == 0 && playerDeck.count == 0 && drawDeck.count == 0)  {
            let cpuPairCount = cpuPairsArray.count
            let playerPairCount = playerPairsArray.count
            playerDeck.removeAll()
            cpuDeck.removeAll()
            deck.removeAll()
            cpuPairsArray.removeAll()
            playerPairsArray.removeAll()
            /*if(playerPairCount > cpuPairCount)  {
                let alertController = UIAlertController(title: "Game Over", message: "You win", preferredStyle: .alert)
                let defaultAction = UIAlertAction(title: "Restart", style: .default, handler: nil)
                alertController.addAction(defaultAction)
            }   else if(playerPairCount < cpuPairCount) {
                let alertController = UIAlertController(title: "Game Over", message: "You lose", preferredStyle: .alert)
                let defaultAction = UIAlertAction(title: "Restart", style: .default, handler: nil)
                alertController.addAction(defaultAction)
            }   else if(playerPairCount == cpuPairCount)    {
                let alertController = UIAlertController(title: "Game Over", message: "Tie game", preferredStyle: .alert)
                let defaultAction = UIAlertAction(title: "Restart", style: .default, handler: nil)
                alertController.addAction(defaultAction)
            }*/
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.pickerView.delegate = self
        self.pickerView.dataSource = self
        /*var alert = UIAlertController(title: "Go FIsh Go", message: "", preferredStyle: .alert)
        var startAlert = UIAlertAction(title: "Start", style: .default, handler: nil)
        alert.addAction(startAlert)
        present(alert, animated: true, completion: nil)*/

        start()


    }

    @IBAction func SelectCard(_ sender: UIButton) {
        checkCPUHand(selectedCard: selectedCard)
        checkForPlayerPairs()
        pickerView.reloadAllComponents()
        pickerView.selectRow(0, inComponent: 0, animated: true)
        if(playerDeck.count == 0 && drawDeck.count > 0)   {
            playerDraw()
        }

        GameCardsLeft.text = "\(drawDeck.count)"
        CPUCardsLeft.text = "\(cpuDeck.count)"
        CPUPairs.text = "\(cpuPairsArray.count)"
        UserPairs.text = "\(playerPairsArray.count)"

        randomIndex = Int(arc4random_uniform(UInt32(cpuDeck.count)))
        checkPlayerHand(selectedCard: cpuDeck[randomIndex])
        checkForCPUPairs()
        if(cpuDeck.count == 0 && drawDeck.count > 0)   {
            cpuDraw()
        }

        GameCardsLeft.text = "\(drawDeck.count)"
        CPUCardsLeft.text = "\(cpuDeck.count)"
        CPUPairs.text = "\(cpuPairsArray.count)"
        UserPairs.text = "\(playerPairsArray.count)"
        checkGameOver()
    }
}

1 个答案:

答案 0 :(得分:0)

return playerDeck[row].description更改为:return (row < playerDeck.count ? playerDeck[row].description : nil),并将selectedCard = playerDeck[row]更改为:

if row < playerDeck.count {
    self.selectedCard = playerDeck[row]
}

此外,请在从self.pickerView.reloadAllComponents()dealplayerDrawcheckCPUHandcheckPlayerHand,{{1}返回之前立即致电checkForPlayerPairs }和organizeCardDeck函数以及修改checkGameOver的任何其他函数。