I'm initialising a set of dice in swift 2.0. I've declared a class Die with a name (:String), a list of states(:[String]) and a face (an index to the states array) (:[Int])
As per the recommendations in the GameplayKit Framework Reference and in this short article by Erica Sadun, I want to drop the first 1024 values of my GKARC4RandomSource to ensure "true" randomness.
In my UIViewController, I setup an init? function to initialise my dice
class IceDiceViewController: UIViewController {
var Dice: [Die]
var source : GKRandomSource
...
required init?(coder aDecoder: NSCoder){
Dice = [Die]()
source = GKARC4RandomSource()
// call the init function to instantiate all variables
super.init(coder: aDecoder)
// now initialize two dice with states ["red","yellow","blue","black","green","multiple"]
Dice.append(Die(name:"iceDie", states: ["red","yellow","blue","black","green","multiple"]))
Dice.append(Die(name:"iceDie", states: ["big","med","small","bigmed","bigsmall","medsmall"]))
// and drop the first values of the ARC4 random source to ensure "true" randomness
source.dropValuesWithCount(1024)
...
}
This won't even compile: the last line returns an error:
Value of type GKRandomSource has no member dropValuesWithCount
My code works without this line, but I'm not sure quite what I'm doing wrong here, and I can hardly find any references to Dice implementation using Gameplay Kit on the web, apart from the above cited links.
This is an issue with the declared type of source
:
var source : GKRandomSource
Since you've told Swift only that it's a GKRandomSource
, it'll only let you call methods that are defined on that class (and thus available to all subclasses). The dropValuesWithCount
method is only on one of those subclasses, so you can't call it on a variable whose static type isn't that subclass.
Even though the variable actually contains an object of the right type when you get around to calling that method, the compiler can't really know that — it only knows about declared (and inferred) types.
So, you can simply just declare that source
is actually a GKARC4RandomSource
, not just a GKRandomSource
:
var source : GKARC4RandomSource
But then again, maybe you want other parts of your code to not know which random subclass it is, so that you can easily switch out random number generators without changing all your code? Well, there are a few ways to handle that, but a simple one might be to just cast it in the one place where you call ARC4-specific API:
(source as! GKARC4RandomSource).dropValuesWithCount(1024)