mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-03 13:11:33 +00:00
use arc4random to seed non-csprng, fleshes out random subsystem
This commit is contained in:
@ -17,8 +17,12 @@ public class Arc4Random: RandomProvider {
|
||||
arc4random()
|
||||
}
|
||||
|
||||
public func next(in bound: Range<Int>) -> Int {
|
||||
assert(bound.upperBound <= Self.max)
|
||||
return bound.lowerBound + Int(arc4random_uniform(UInt32(bound.upperBound)))
|
||||
public func next(in bound: Int) -> Int {
|
||||
assert(bound <= Self.max)
|
||||
return Int(arc4random_uniform(UInt32(bound)))
|
||||
}
|
||||
|
||||
public func next(in range: Range<Int>) -> Int {
|
||||
return range.lowerBound + next(in: range.upperBound - range.lowerBound)
|
||||
}
|
||||
}
|
||||
|
33
Sources/Voxelotl/Random/DarwinRandom.swift
Normal file
33
Sources/Voxelotl/Random/DarwinRandom.swift
Normal file
@ -0,0 +1,33 @@
|
||||
public struct DarwinRandom: RandomProvider {
|
||||
public typealias Output = Int
|
||||
|
||||
public static var min: Int { 0x00000000 }
|
||||
public static var max: Int { 0x7FFFFFFF }
|
||||
|
||||
private var state: Int
|
||||
|
||||
init() {
|
||||
self.state = 0
|
||||
}
|
||||
|
||||
public init(seed: Int) {
|
||||
self.state = seed
|
||||
}
|
||||
|
||||
mutating public func seed(with seed: Int) {
|
||||
self.state = seed
|
||||
}
|
||||
|
||||
mutating public func next() -> Int {
|
||||
if self.state == 0 {
|
||||
self.state = 123459876
|
||||
}
|
||||
let hi = self.state / 127773
|
||||
let lo = self.state - hi * 127773
|
||||
self.state = 16807 * lo - 2836 * hi
|
||||
if self.state < 0 {
|
||||
self.state += Self.max
|
||||
}
|
||||
return self.state % (Self.max + 1)
|
||||
}
|
||||
}
|
20
Sources/Voxelotl/Random/RandomRange.swift
Normal file
20
Sources/Voxelotl/Random/RandomRange.swift
Normal file
@ -0,0 +1,20 @@
|
||||
public extension RandomProvider where Output: BinaryInteger {
|
||||
mutating func next(in range: Range<Int>) -> Int {
|
||||
range.lowerBound + self.next(in: range.upperBound - range.lowerBound)
|
||||
}
|
||||
|
||||
mutating func next(in range: ClosedRange<Int>) -> Int {
|
||||
range.lowerBound + self.next(in: range.upperBound - range.lowerBound + 1)
|
||||
}
|
||||
|
||||
mutating func next(in bound: Int) -> Int {
|
||||
assert(Self.min == 0)
|
||||
assert(Self.max >= bound)
|
||||
let threshold = Int(Self.max % Output(bound))
|
||||
var result: Int
|
||||
repeat {
|
||||
result = Int(truncatingIfNeeded: self.next())
|
||||
} while result < threshold
|
||||
return result % bound
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user