I'm making a ro sham bo game. Functions in swift are different than what I have used before. I keep getting an error:
Variable used before being initialized in function
What am I doing wrong?
import Foundation
import UIKit
class Result: UIViewController {
var rval: Int?
var chosen: Int?
func determineWinner() -> Int {
var returnval: Int
if (chosen == rval){
returnval = 2
}
else if (chosen == 1 && rval == 3){
returnval = 1
}
else if (chosen == 1 && rval == 2){
returnval = 0
}
else if (chosen == 2 && rval == 1){
returnval = 1
}
return (returnval)
}
@IBOutlet weak var wl: UILabel!
@IBAction func PlayAgain(sender: AnyObject) {
}
override func viewDidLoad() {
print(chosen)
}
}
Returning an Int?
As others already said, the problem is that none of your conditions is met then
returnval
is not initialized.You can use a switch statement + guard + computed property. Like this
Returning Int + Fatal error
If you know chose and rval will always be populated then
EDITTED
Problem Resolution
You're getting the initializer error because you haven't initialized
returnval
withInt()
prior to setting.Code Improvements
Consider using a computed property to return the value of who won. I made the assumption in my code below, that the value 2 you were using inferred a tie situation based on your logic.
Here I created an enumeration to ensure the returned value is only handled in these particular ways you'd expect the outcome to mean. You can still access the
Int
values via the hash value on the enum case. Use.rawValue
to do so.It is important to try your best to avoid using
Int
values in this case because they can be other values.In the code I included below I wrote you a set of
guard
statements to fail and return afatalError
message when the values checked do not allow the winner state to be determined.Improved Code
As a side note be sure to +1 the answers you like!
Try
var returnval: Int = 0
(or another random number in case your if-else statements are exhaustive)The problematic statement is
return (returnval)
because Swift compiler thinks that there is a pass through the if-then-else chain that does not result in assignment ofreturnval
.For example, if
chosen
is 3 andrval
is 2, there would be no assignment.Perhaps other parts of your program makes it impossible for
chosen
to be 3 at the same time asrval
is 2, but Swift has no idea of that, so it reports an error. In order to fix the compile error, add an initial value toreturnval
.If you are absolutely sure that your if-then-else chain enumerates all valid possibilities, set
returnval
to-1
, and make an assertion about it being set to a non-negative value before returning:Every possible path in the flow of a Swift program must have a defined returned value. In your case, if the
if
/else if
/else
sections are all skipped, leavingreturnval
unassigned. Thus, no valid value is being returned. Try this:This is also a very good candidate for using pattern matching with
switch
statements. Here's what I think works beside, in conjunction withSean's suggestion.You can make this much more swifty.
For instance... Why use
Int
to represent the different moves? Here I used an enum to represent the moves and the logic behind what wins...Then all you need to do is wrap this up in some sort of
Player
andGame
type thing...Not a single Int was used in the whole thing and you can see exactly what the winning move was and who won etc...
Enums are really a lot more powerful than they are given credit for in Swift.