Comment fait-on un nombre aléatoire entre la plage pour arc4random uniform()?

Donc, mon but dans ce codebit est de lancer au hasard deux dés et comme nous le savons tous, votre dé régulier n'a que 6 côtés, donc J'ai importé Foundation pour accéder à arc4random_uniform(UInt32). J'ai essayé d'utiliser la plage de (1..7) pour éviter d'obtenir au hasard 0 cependant 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))

Cependant qui a renvoyé

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

J'espère que c'est suffisamment d'informations pour vous incroyable debs là pour m'aider :)

Veuillez noter que je fais cela dans un terrain de jeu pour pratiquer swift. Il n'est pas impératif que j'apprenne à le faire; c'est juste moi 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

Cela renvoie une erreur de 'Range $ T3' n'est pas 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.")
115
demandé sur Huangism 2014-06-10 07:32:50

17 réponses

Je crois que vous devriez faire

dice1 = arc4random_uniform(6) + 1;

Pour obtenir la plage 1-6. Je ne fais pas iOS objective C et je n'ai aucune connaissance sur swift-language cependant. La méthode aléatoire devrait 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 simplement

int random = arc4random_uniform(21) + 10;
244
répondu Sky 2017-02-20 13:10:56

J'ai fait une extension de type Int. testé dans playground, j'espère 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 de plage 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
89
répondu Ted van Gaalen 2015-04-04 09:11:43

Pas mal de 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, elle fonctionne maintenant pour tout type de valeur conforme au Protocole SignedInteger-beaucoup plus pratique pour les applications de données de base qui doivent spécifier Int16, Int32, etc. Comme une note rapide, si vous avez vraiment besoin de travailler sur unsigned les entiers aussi, 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 différent de conversion 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)
}

Un de plus, pour le total aléatoire-phile, voici une extension qui renvoie un élément aléatoire à partir de n'importe quel objet de type Collection. Notez que cela 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)]
    }
}

Utilisation

randomNumber()

retourne un nombre aléatoire 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.

51
répondu Ash 2017-10-16 08:28:15

Si vous voulez, je crée cela pour nombres aléatoires.{[4] } 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
répondu YannickSteph 2015-01-29 08:02:21

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
répondu Alessandro Ornano 2018-03-15 09:57:49

C'est parce que 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 plage de valeurs. arc4random_uniform vous donne un nombre aléatoire entre 0 et le nombre que vous passez (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
répondu Mick MacCallum 2014-06-10 03:44:16

Swift:

var index = 1 + random() % 6
5
répondu Alexander Volkov 2015-01-12 05:49:42

J'ai modifié la réponse de @DaRk-_-D0G pour travailler 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
répondu Joped 2016-07-04 08:14:09

Dans swift...

Ceci est inclusif, l'appel 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
répondu Carter Medlin 2016-07-12 16:03:14

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 soit que le nombre ne peut pas commencer à partir de 0.

3
répondu Nupur Sharma 2017-07-17 08:27:28

Selon Swift 4.2 maintenant, il est facile d'obtenir un nombre aléatoire comme ceci

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

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

Pour plus de détails, consultez ceci

3
répondu Nosov Pavel 2018-06-05 09:39:02

J'ai réussi à créer un nombre aléatoire en utilisant le code suivant:

var coin = arc4random_uniform(2) + 1

J'Espère que cela peut vous aider.

1
répondu Bigfoot11 2015-03-12 09:55:29

Ne savez Pas pourquoi personne d'autre ici s'étend 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)))
    }
}

En cours d'utilisation:

let foo = (100..<600).random
1
répondu mxcl 2018-03-14 02:56:48

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
répondu Statik 2016-08-22 09:28:31

Var rangeFromLimits = arc4random_uniform( (UPPerBound - limite inférieure) + 1)) + limite inférieure;

0
répondu dev_shanghai 2017-07-12 13:37:43

J'espère que ça marche. faire un nombre aléatoire entre la plage pour arc4random_uniform ()?

var randomNumber = Int(arc4random_uniform(6))
print(randomNumber)
0
répondu Vidhyapathi Kandhasamy 2018-05-03 07:19:09

Probablement on trouve utile cette version un peu mise à jour de l'extension Range de la réponse de Ted van Gaalen en utilisant 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
répondu devforfu 2018-05-16 11:32:17