Need Explanation About Random Function Swift

Need explanation about random function swift

A IEEE 754 32-bit floating point number has 24 significant bits for the mantissa, that is not enough to store a 10-digit integer exactly:

print(0xFFFFFFFF)             // 4294967295
print(Float(0xFFFFFFFF)) // 4.2949673e+09
print(Int(Float(0xFFFFFFFF))) // 4294967296

That won't affect your code because

Float(arc4random()) / Float(0xFFFFFFFF)

is still a floating point number between 0.0 and 1.0. Changing the calculation to

return CGFloat(arc4random()) / 0xFFFFFFFF

will fix the warning on 64-bit platforms: The integer constant is now converted to a (64-bit) Double.

But as of Swift 4.2 you can avoid the problem completely by using the new Random API:

func random(min: CGFloat, max: CGFloat) -> CGFloat {
return CGFloat.random(in: min...max)
}

How does one generate a random number in Swift?

Swift 4.2+

Swift 4.2 shipped with Xcode 10 introduces new easy-to-use random functions for many data types.
You can call the random() method on numeric types.

let randomInt = Int.random(in: 0..<6)
let randomDouble = Double.random(in: 2.71828...3.14159)
let randomBool = Bool.random()

Swift call random function

The reason the three functions are called (and in the same order) is since you are causing them to be called when you put them in the array.

This:

let randomFunc = [self.firstFunction(), self.secondFunction(), self.thirdFunction()]

Stores the return value of each function in the array since you are invoking them (by adding the '()').

So at this point randomFunc contains the return values rather than the function closures

Instead just store the functions themselves with:

[self.firstFunction, self.secondFunction, self.thirdFunction]

Now if you want to call the selected method do not return its closure but invoke it:

 //return randomFunc[randomResult] // This will return the function closure 

randomFunc[randomResult]() // This will execute the selected function

Smart way to pick a random function

If you want the probability of the different functions to be different then your switch statement would be a good choice:

switch Int.random(in: 1...100) {
case 1...10: functionOne() //10% of calls
case 11...100: functionTwo() //90% of calls
default: noFunction()
}

If you want them all to be equally as likely then Matt's approach seems cleaner:

let functions = [functionOne, functionTwo]
(functions.randomElement()!)()

Swift: how to call the function which calls a random function?

The problem is that createSquare() returns a closure that you never invoke (that's the "unused function" mentioned in the warning message).

You need to call the function, for example, like this:

let randomFunction = createSquare()
randomFunction()

You can also call it right away with a somewhat less readable syntax:

createSquare()()

Swift Random Function

Assuming I'm understanding your question correctly, you want this:

 func createObstacle() -> () -> () {

var obstacles = [obstacle1, obstacle2, obstacle3]

var randomObstacle = Int(arc4random_uniform(UInt32(obstacles.count)))

return obstacles[randomObstacle]
}

Check out the documentation section about functions: https://developer.apple.com/library/ios/documentation/swift/conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-XID_243

How to Generate a New Random Number Once Every time Content View Loads?

Approach #1:

MyView is created once, when ContentView renders.

Inside MyView, randomInt is set when the view is first created and then never modified. When you press the button, myMessage is set, but randomInt is never changed. If you wanted randomInt to change, you'd want to say something like:

randomInt = Int.random(in: 1...100)

inside your button action:

Approach #2:

You're creating a new randomInt variable in the local scope by declaring let randomInt = inside the view body.

Instead, if I'm reading your initial question correctly, I think you'd want something using onAppear:

struct MyView: View {

@State var randomInt = 0
@State var myMessage: String = ""

var body: some View {
VStack {
Text(String(randomInt))

Button("Press Me") {
myMessage = String(randomInt)
}

Text(myMessage)
}.onAppear {
randomInt = Int.random(in: 1...100)
}
}
}

You'll see that with this, every time you go back in the navigation hierarchy and then revisit MyView, there's a new value (since it appears again). The button triggering a re-render doesn't re-trigger onAppear

Approach #3:

MyView gets created on the first render of the parent view (ContentView). Unless something triggers a refresh of ContentView, you wouldn't generate a new random number here.


In conclusion, I'm a little unclear on what the initial requirement is (what does it mean for a View to 'load'? Does this just mean when it gets shown on the screen?), but hopefully this describes each scenario and maybe introduces the idea of onAppear, which seems like it might be what you're looking for.


Addendum: if you want the random number to be generated only when ContentView loads (as the title says), I'd create it in ContentView instead of your MyView and pass it as a parameter.


struct ContentView: View {
@State var randomInt = Int.random(in: 1...100)

var body: some View {

NavigationView {

NavigationLink(destination: MyView(randomInt: $randomInt)) {
Text("Link to MyView")
}
}
}
}

struct MyView: View {

@Binding var randomInt : Int
@State var myMessage: String = ""

var body: some View {

Text(String(randomInt))

Button("Press me to refresh only myMessage") {
myMessage = String(randomInt)
}

Button("Press me to change the randomInt as well") {
randomInt = Int.random(in: 1...100)
myMessage = String(randomInt)
}

Text(myMessage)
}

}

Generating random numbers with Swift

let randomIntFrom0To10 = Int.random(in: 1..<10)
let randomFloat = Float.random(in: 0..<1)

// if you want to get a random element in an array
let greetings = ["hey", "hi", "hello", "hola"]
greetings.randomElement()

Swift - Select Random Function

func fireEvent() {
var randomFunction = [addEnemyFromCornersTogether(), addEnemyFromCornersWait()]
let choice = Int(arc4random_uniform(UInt32(randomFunction.count)))
var choiceFunction: () = randomFunction[choice]
let delay = 5.0 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), {
choiceFunction
fireEvent()
})
}


Related Topics



Leave a reply



Submit