I try programming a "Circle the dot" game. Therefor I have to do a Breath First Search over a 2D-Array of UIButtons to find the shortest path from the playerButton to the border.
Unfortunately I sometimes get a Thread 1: Swift runtime failure: force unwrapped a nil value error for several days and I just cannot find the issue.
This is a function of the program to return the next x and y coordinates to move. Thats where I do the BFS.
func findDirection()->String{
var blocked: [String] = []
let queue = otherQueue<Pair>()
let pair = Pair()
var possibleNeighbours = findPossibleNeighbours(btn: btnArr[playerX][playerY], blockedArr: blocked)
for neighbour in possibleNeighbours{
if(isOnBorder(point: neighbour)){
return neighbour
}
pair.setPair(firstValue: neighbour, secondValue: neighbour)
queue.enqueue(key: pair)
blocked.append(neighbour)
}
//Start the search
while(!queue.isEmpty){
let pointPair = queue.dequeue()
// !!!!!! THIS IS THE ERROR LINE:
let button = btnArr[getXFromString(string: (pointPair?.getFirst())!)][getYFromString(string: (pointPair?.getFirst())!)]
possibleNeighbours = findPossibleNeighbours(btn: button, blockedArr: blocked)
for neighbour in possibleNeighbours{
if isOnBorder(point: neighbour){
return (pointPair?.getSecond())!
}
pair.setPair(firstValue: neighbour, secondValue: (pointPair?.getSecond())!)
queue.enqueue(key: pair)
blocked.append(neighbour)
}
}
return "-1 -1"
}
The Problem:
It says that pointPair?.getFirst()!
is forced unwrapped a nil value. pointPair is the Pair I dequeued from the queue. So my guess was that my queue is empty and tried to dequeue. I checked several times and even wrote a new Queue Class. That was not the problem and the !queue.isEmpty
works fine, which is the while-condition. The next guess is that the getFirst(), which returns the first value of my Pair, returns a nil value. This also makes no sense to me as the first value is the iterating neighbour
from the possibleNeighbours-Array, which cannot be nil (its only added to the array if it is a POSSIBLE neighbour and obviously exists).
The problem always occurs when the dot has only 2 possible ways to move on. Take this as an example.
The blue dot startet at (4, 4). Then I clicked on (2, 3), the dot moved to (3, 3). Then I clicked on (2, 4), the dot moved to (3, 4). Then the button has to possible ways: move to (2, 5) or (3, 5). If you now click on one of both it crashes. In the console I can read that after I clicked on (2, 5) the queue only contained ["3 5"] which is correct as (3, 5) is the only way to move on. Somehow it does not move there and crashes with force unwrapped a nil value...
If you wanna download my whole project and test it you can do so here (hope the link works).
Do you have an idea why it fails? :(
Thanks for any help!