web-dev-qa-db-fra.com

Comment fait-on un nombre aléatoire entre range pour arc4random_uniform ()?

mon objectif dans ce code code est donc de lancer deux dés au hasard et, comme nous le savons tous, votre dé ordinaire n’a que 6 faces. J’ai donc importé Foundation pour accéder à arc4random_uniform (UInt32). J'ai essayé d'utiliser la plage de (1..7) pour éviter d'avoir 0 au hasard, mais cela a renvoyé une erreur que je n'ai pas trop appréciée. J'ai essayé de faire ceci:

dice1 = arc4random_uniform(UInt32(1..7))

mais qui est revenu

Impossible de trouver une surcharge pour 'init' qui accepte les arguments fournis

J'espère que cela vous donnera suffisamment d'informations pour vous aider à débattre des débats étonnants :)

S'il vous plaît noter que je fais juste cela dans un terrain de jeu pour pratiquer Swift. Il n'est pas impératif que j'apprenne à faire cela. il me suffit de bricoler avant de sauter dans la construction d'applications réelles: D

//imports random number function
import Foundation
//creates data storage for dice roll
var dice1: UInt32 = 0
var dice2: UInt32 = 0
//counter variable
var i = 0
//how many times snake eyes happens
var snakeeyes = 0
 //how many times a double is rolled
var `double` = 0
//rolls dice 100 times
while i < 100{
    //from here
    //sets dice roll

Ceci renvoie une erreur de 'Range $ T3' non convertible en UInt32.

   dice1 = arc4random_uniform(1..7)
   dice2 = arc4random_uniform(1..7)
    //checks for snake eyes
    if dice1 == 1 && dice2 == 1 {
        snakeeyes = snakeeyes + 1

    }
    //checks for doubles
    if dice1 == dice2{
        `double` = `double` + 1
    }
    //increases counter
        i = i + 1
    //to here
}
println("You got Snake Eyes \(snakeeyes) times.")
println("You got Doubles, \(`double`) times.")
122
arcreigh

Je crois que tu devrais faire 

dice1 = arc4random_uniform(6) + 1;

pour obtenir la plage 1 - 6. Je ne fais pas iOS Objective C, je ne connais pas le langage Swift. La méthode aléatoire doit renvoyer une valeur comprise entre 0 et 5, et +1 en fera une valeur comprise entre 1 et 6.

Si vous avez besoin d’une plage comprise entre 10 et 30, faites-le. 

int random = arc4random_uniform(21) + 10;
251
Sky

J'ai fait une extension de type Int. testé dans le terrain de jeu, espérons que cela est utile. Il accepte également les plages négatives:

extension Int
{
    static func random(range: Range<Int> ) -> Int
    {
        var offset = 0

        if range.startIndex < 0   // allow negative ranges
        {
            offset = abs(range.startIndex)
        }

        let mini = UInt32(range.startIndex + offset)
        let maxi = UInt32(range.endIndex   + offset)

        return Int(mini + arc4random_uniform(maxi - mini)) - offset
    }
}

utiliser comme

var aRandomInt = Int.random(-500...100)  // returns a random number within the given range.

ou définissez-le comme une extension Range en tant que propriété comme ceci:

extension Range
{
    var randomInt: Int
    {
        get
        {
            var offset = 0

            if (startIndex as Int) < 0   // allow negative ranges
            {
                offset = abs(startIndex as Int)
            }

            let mini = UInt32(startIndex as Int + offset)
            let maxi = UInt32(endIndex   as Int + offset)

            return Int(mini + arc4random_uniform(maxi - mini)) - offset
        }
    }
}

// usage example: get an Int within the given Range:
let nr = (-1000 ... 1100).randomInt
90
Ted van Gaalen

Quelques bonnes réponses, mais je voulais juste partager ma fonction de génération de nombres aléatoires Swift préférée pour les entiers positifs:

Swift 2

func randomNumber(range: Range<Int> = 1...6) -> Int {
    let min = range.startIndex
    let max = range.endIndex
    return Int(arc4random_uniform(UInt32(max - min))) + min
}

Swift 3

Voici une mise à jour rapide pour Swift 3 et, en prime, cela fonctionne désormais pour tout type de valeur conforme au protocole SignedInteger - bien plus pratique pour les applications de données principales qui doivent spécifier Int16, Int32, etc. Si vous en avez vraiment besoin pour travailler sur des entiers non signés, copiez simplement la fonction entière puis remplacez SignedInteger par UnsignedInteger et toIntMax() par toUIntMax().

func randomNumber<T : SignedInteger>(inRange range: ClosedRange<T> = 1...6) -> T {
    let length = (range.upperBound - range.lowerBound + 1).toIntMax()
    let value = arc4random().toIntMax() % length + range.lowerBound.toIntMax()
    return T(value)
}

Swift 4

Grâce à la suppression de toIntMax () dans Swift 4, nous devons maintenant utiliser un moyen de conversion différent en un type entier commun. Dans cet exemple, j'utilise Int64, qui est assez grand pour mes besoins, mais si vous utilisez des entiers non signés ou si vous avez un type personnalisé Int128 ou Int256, vous devez les utiliser.

public func randomNumber<T : SignedInteger>(inRange range: ClosedRange<T> = 1...6) -> T {
    let length = Int64(range.upperBound - range.lowerBound + 1)
    let value = Int64(arc4random()) % length + Int64(range.lowerBound)
    return T(value)
}

Encore une, pour le total aléatoire-phile, voici une extension qui retourne un élément aléatoire à partir de n’importe quel objet de type Collection. Notez que ceci utilise la fonction ci-dessus pour générer son index, vous aurez donc besoin des deux.

extension Collection {
    func randomItem() -> Self.Iterator.Element {
        let count = distance(from: startIndex, to: endIndex)
        let roll = randomNumber(inRange: 0...count-1)
        return self[index(startIndex, offsetBy: roll)]
    }
}

Usage

randomNumber()

renvoie un nombre aléatoire compris entre 1 et 6.

randomNumber(50...100)

renvoie un nombre compris entre 50 et 100 inclus. Naturellement, vous pouvez remplacer les valeurs de 50 et 100 par ce que vous voulez.

59
Ash

D'après Swift 4.2, il est maintenant facile d'obtenir un nombre aléatoire comme celui-ci

let randomDouble = Double.random(in: -7.9...12.8)

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

pour plus de détails voir ceci

18
Nosov Pavel

Si vous voulez, je crée cela pour des nombres aléatoires. ceci est l'extension du nombre Int et Double, Float

/**
    Arc Random for Double and Float
*/
public func arc4random <T: IntegerLiteralConvertible> (type: T.Type) -> T {
    var r: T = 0
    arc4random_buf(&r, UInt(sizeof(T)))
    return r
}
public extension Int {
    /**
    Create a random num Int
    :param: lower number Int
    :param: upper number Int
    :return: random number Int
    By DaRkDOG
    */
    public static func random (#lower: Int , upper: Int) -> Int {
        return lower + Int(arc4random_uniform(upper - lower + 1))
    }

}
public extension Double {
    /**
    Create a random num Double
    :param: lower number Double
    :param: upper number Double
    :return: random number Double
    By DaRkDOG
    */
    public static func random(#lower: Double, upper: Double) -> Double {
        let r = Double(arc4random(UInt64)) / Double(UInt64.max)
        return (r * (upper - lower)) + lower
    }
}
public extension Float {
    /**
    Create a random num Float
    :param: lower number Float
    :param: upper number Float
    :return: random number Float
    By DaRkDOG
    */
    public static func random(#lower: Float, upper: Float) -> Float {
        let r = Float(arc4random(UInt32)) / Float(UInt32.max)
        return (r * (upper - lower)) + lower
    }
}

UTILISATION :

let randomNumDouble = Double.random(lower: 0.00, upper: 23.50)
let randomNumInt = Int.random(lower: 56, upper: 992)
let randomNumInt =Float.random(lower: 6.98, upper: 923.09)
17
YannickSteph

Swift 3/4:

func randomNumber(range: ClosedRange<Int> = 1...6) -> Int {
    let min = range.lowerBound
    let max = range.upperBound
    return Int(arc4random_uniform(UInt32(1 + max - min))) + min
}
13

En effet, arc4random_uniform () est défini comme suit:

func arc4random_uniform(_: UInt32) -> UInt32

Il prend un UInt32 en entrée et crache un UInt32. Vous essayez de lui transmettre une gamme de valeurs. arc4random_uniform vous donne un nombre aléatoire compris entre 0 et le nombre que vous transmettez (exclusivement), donc si par exemple, vous vouliez trouver un nombre aléatoire compris entre -50 et 50, comme dans [-50, 50], vous pouvez utiliser arc4random_uniform(101) - 50.

8
Mick MacCallum

Rapide:

var index = 1 + random() % 6
5
Alexander Volkov

J'ai modifié la réponse de @DaRk -_- D0G pour fonctionner avec Swift 2.0

/**
Arc Random for Double and Float
*/
public func arc4random <T: IntegerLiteralConvertible> (type: T.Type) -> T {
    var r: T = 0
    arc4random_buf(&r, sizeof(T))
    return r
}
public extension Int {
    /**
    Create a random num Int
    :param: lower number Int
    :param: upper number Int
    :return: random number Int
    By DaRkDOG
    */
    public static func random (lower: Int , upper: Int) -> Int {
        return lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
    }

}
public extension Double {
    /**
    Create a random num Double
    :param: lower number Double
    :param: upper number Double
    :return: random number Double
    By DaRkDOG
    */
    public static func random(lower: Double, upper: Double) -> Double {
        let r = Double(arc4random(UInt64)) / Double(UInt64.max)
        return (r * (upper - lower)) + lower
    }
}
public extension Float {
    /**
    Create a random num Float
    :param: lower number Float
    :param: upper number Float
    :return: random number Float
    By DaRkDOG
    */
    public static func random(lower: Float, upper: Float) -> Float {
        let r = Float(arc4random(UInt32)) / Float(UInt32.max)
        return (r * (upper - lower)) + lower
    }
}
5
Joped

La réponse est juste 1 code de ligne:

let randomNumber = arc4random_uniform(8999) + 1000 //for 4 digit random number
let randomNumber = arc4random_uniform(899999999) + 100000000 //for 9 digit random number
let randomNumber = arc4random_uniform(89) + 10    //for 2 digit random number
let randomNumber = arc4random_uniform(899) + 100  //for 3 digit random number

La solution alternative est:

    func generateRandomNumber(numDigits: Int) -> Int{
    var place = 1
    var finalNumber = 0;
    var finanum = 0;
    for var i in 0 ..< numDigits {
        place *= 10
        let randomNumber = arc4random_uniform(10)         
        finalNumber += Int(randomNumber) * place
        finanum = finalNumber / 10
           i += 1
    }
    return finanum
}

Bien que l'inconvénient est que ce nombre ne peut pas commencer à 0.

3
Nupur Sharma

En rapide ...

Ceci est inclusif, appeler random(1,2) renverra un 1 ou un 2. Cela fonctionnera également avec des nombres négatifs.

    func random(min: Int, _ max: Int) -> Int {
        guard min < max else {return min}
        return Int(arc4random_uniform(UInt32(1 + max - min))) + min
    }
3
Carter Medlin

Edit: Swift 4.2+ fournit ceci maintenant:

(100...200).randomElement()

C’est idiomatique pour moi d’étendre Range:

public extension Range where Bound == Int {
    var random: Int {
        return lowerBound + Int(arc4random_uniform(UInt32(upperBound - lowerBound)))
    }
}

public extension ClosedRange where Bound == Int {
    var random: Int {
        return lowerBound + Int(arc4random_uniform(UInt32(upperBound - lowerBound + 1)))
    }
}

Utilisé:

let foo = (100..<600).random
1
mxcl

Depuis Swift 4.2:

Int {    
    public static func random(in range: ClosedRange<Int>) -> Int
    public static func random(in range: Range<Int>) -> Int
}

Utilisé comme:

Int.random(in: 2...10)
1
Camsoft

J'ai réussi à créer un nombre aléatoire à l'aide du code suivant:

var coin = arc4random_uniform(2) + 1

J'espère que cela peut vous aider.

1
Bigfoot11

Vous trouverez probablement utile cette version un peu mise à jour de l'extension Range de la réponse de Ted van Gaalen avec Swift 4/Xcode 9+ :

extension CountableClosedRange where Bound == Int {
    var randomFromRange: Bound {
        get {
            var offset = 0
            if lowerBound < 0 {
                offset = abs(lowerBound)
            }
            let mini = UInt32(lowerBound + offset)
            let maxi = UInt32(upperBound + offset)
            return Int(mini + arc4random_uniform(maxi - mini)) - offset
        }
    }
}

let n = (-1000 ... 1000).randomFromRange
print(n)

Ou cette solution un peu "hacky" pour supporter les intervalles ouverts et fermés: 

extension CountableRange where Bound == Int {
    var randomFromRange: Bound {
        return uniformRandom(from: lowerBound, to: upperBound)
    }
}

extension CountableClosedRange where Bound == Int {
    var randomFromRange: Bound {
        return uniformRandom(from: lowerBound, to: upperBound - 1)
    }
}

func uniformRandom(from: Int, to: Int) -> Int {
    var offset = 0
    if from < 0 {
        offset = abs(from)
    }
    let mini = UInt32(from + offset)
    let maxi = UInt32(to + offset)
    return Int(mini + arc4random_uniform(maxi - mini)) - offset
}

Vous ne savez pas s'il existe un moyen d'ajouter une propriété aux deux types d'intervalles simultanément.

0
devforfu

Swift 3 Xcode Beta 5 Solution. Basé sur la réponse de Ted van Gaalen.

extension Int
  {
     static func random(range: Range<Int> ) -> Int
    {
        var offset = 0

        if range.lowerBound < 0   // allow negative ranges
        {
            offset = Swift.abs(range.lowerBound)
        }

        let mini = UInt32(range.lowerBound + offset)
        let maxi = UInt32(range.upperBound   + offset)

        return Int(mini + arc4random_uniform(maxi - mini)) - offset
    }
}
0
Statik

var rangeFromLimits = arc4random_uniform ((UPPerBound - LOWerBound) + 1)) + LOWerBound;

0
dev_shanghai

espérons que cela fonctionne. faire un nombre aléatoire entre range pour arc4random_uniform ()?

var randomNumber = Int(arc4random_uniform(6))
print(randomNumber)