Up to date

This page is up to date for Godot `4.2`. If you still find outdated information, please open an issue.

随机数生成¶

After giving you a brief overview of useful functions that generate random numbers, you will learn how to get random elements from arrays, dictionaries, and how to use a noise generator in GDScript. Lastly, we'll take a look at cryptographically secure random number generation and how it differs from typical random number generation.

Godot internally uses the PCG Family of pseudorandom number generators.

全局作用域 vs RandomNumberGenerator 类¶

Godot 提供了两种生成随机数的方式：通过全局作用域方法或使用 RandomNumberGenerator 类。

RandomNumberGenerator requires more code to use, but allows creating multiple instances, each with their own seed and state.

randomize() 方法¶

Since Godot 4.0, the random seed is automatically set to a random value when the project starts. This means you don't need to call `randomize()` in `_ready()` anymore to ensure that results are random across project runs. However, you can still use `randomize()` if you want to use a specific seed number, or generate it using a different method.

In global scope, you can find a randomize() method. This method should be called only once when your project starts to initialize the random seed. Calling it multiple times is unnecessary and may impact performance negatively.

```func _ready():
randomize()
```

You can also set a fixed random seed instead using seed(). Doing so will give you deterministic results across runs:

```func _ready():
seed(12345)
# To use a string as a seed, you can hash it to a number.
seed("Hello world".hash())
```

```var random = RandomNumberGenerator.new()
random.randomize()
```

获得一个随机数¶

The function randi() returns a random number between 0 and 2^32-1. Since the maximum value is huge, you most likely want to use the modulo operator (`%`) to bound the result between 0 and the denominator:

```# Prints a random integer between 0 and 49.
print(randi() % 50)

# Prints a random integer between 10 and 60.
print(randi() % 51 + 10)
```

randf() returns a random floating-point number between 0 and 1. This is useful to implement a 加权随机概率 system, among other things.

randfn() 返回遵循 正态分布 的随机浮点数。这意味着返回值更有可能在平均值附近（默认为 0.0），随偏差变化（默认为 1.0）:

```# Prints a random floating-point number from a normal distribution with a mean 0.0 and deviation 1.0.
var random = RandomNumberGenerator.new()
random.randomize()
print(random.randfn())
```

randf_range() takes two arguments `from` and `to`, and returns a random floating-point number between `from` and `to`:

```# Prints a random floating-point number between -4 and 6.5.
print(randf_range(-4, 6.5))
```

RandomNumberGenerator.randi_range() 接受两个参数 `from``to` ，并返回一个介于 `from``to` 之间的随机整数：

```# Prints a random integer between -10 and 10.
var random = RandomNumberGenerator.new()
random.randomize()
print(random.randi_range(-10, 10))
```

获取一个随机数组元素¶

```var _fruits = ["apple", "orange", "pear", "banana"]

randomize()

for i in range(100):
# Pick 100 fruits randomly.
print(get_fruit())

func get_fruit():
var random_fruit = _fruits[randi() % _fruits.size()]
# Returns "apple", "orange", "pear", or "banana" every time the code runs.
# We may get the same fruit multiple times in a row.
return random_fruit
```

```var _fruits = ["apple", "orange", "pear", "banana"]
var _last_fruit = ""

randomize()

# Pick 100 fruits randomly.
for i in range(100):
print(get_fruit())

func get_fruit():
var random_fruit = _fruits[randi() % _fruits.size()]
while random_fruit == _last_fruit:
# The last fruit was picked, try again until we get a different fruit.
random_fruit = _fruits[randi() % _fruits.size()]

# Note: if the random element to pick is passed by reference,
# such as an array or dictionary,
# use `_last_fruit = random_fruit.duplicate()` instead.
_last_fruit = random_fruit

# Returns "apple", "orange", "pear", or "banana" every time the code runs.
# The function will never return the same fruit more than once in a row.
return random_fruit
```

获取一个随机字典值¶

```var metals = {
"copper": {"quantity": 50, "price": 50},
"silver": {"quantity": 20, "price": 150},
"gold": {"quantity": 3, "price": 500},
}

randomize()

for i in range(20):
print(get_metal())

func get_metal():
var random_metal = metals.values()[randi() % metals.size()]
# Returns a random metal value dictionary every time the code runs.
# The same metal may be selected multiple times in succession.
return random_metal
```

加权随机概率¶

The randf() method returns a floating-point number between 0.0 and 1.0. We can use this to create a "weighted" probability where different outcomes have different likelihoods:

```func _ready():
randomize()

for i in range(100):
print(get_item_rarity())

func get_item_rarity():
var random_float = randf()

if random_float < 0.8:
# 80% chance of being returned.
return "Common"
elif random_float < 0.95:
# 15% chance of being returned.
return "Uncommon"
else:
# 5% chance of being returned.
return "Rare"
```