在 Swift 中避免使用 arc4random 重复
Avoiding repetition with arc4random in Swift
我有以下代码在 Swift 中生成随机填充的网格:
import Foundation
var tile = [String](count: 900, repeatedValue: ".")
// Randomly populate the grid with hashes
for i in 0...400 {
tile[Int(arc4random_uniform(899))] = "#"
}
// Print the grid to console
for y in 0...(29) {
for x in 0...(29) {
print("\(tile[y * 10 + x])")
}
println("")
}
运行 此代码生成如下所示的网格:
..##..#.#...#..#..#.#.####.#..
..#..#..#.#.####.#....###.#.#.
#.####.#....###.#.#.#####.....
..###.#.#.#####.....#...#....#
#####.....#...#....###.##.###.
#...#....###.##.###..#.....#..
##.##.###..#.....#...##..#.##.
.#.....#...##..#.##...#.####..
.##..#.##...#.####..###..#.#.#
..#.####..###..#.#.#.#..#.....
###..#.#.#.#..#.........#...##
.#..#.........#...##.##.......
....#...##.##............#...#
.##............#...####....##.
.....#...####....##..#.#.....#
###....##..#.#.....#........#.
.#.#.....#........#...#.#..#..
........#...#.#..#......#....#
..#.#..#......#....#.##.#...##
....#....#.##.#...###...#..#..
.##.#...###...#..#..#.#..#...#
#...#..#..#.#..#...#####...##.
#.#..#...#####...##..#.......#
####...##..#.......#.#.#.....#
.#.......#.#.#.....##.........
.#.#.....##..........##.#..#.#
#..........##.#..#.##.#.#.....
.##.#..#.##.#.#.....##...#....
#.#.#.....##...#......#.##....
##...#......#.##.....#.######.
你可以清楚地看到一个模式在重复。有没有办法让"throw"功能让生成更有说服力?
你的打印函数是错误的:tile[y*10 + x]
应该是tile[y*30 + x]
。
至于生成网格:您到底想要什么?
如果答案是"a random choice from the uniform distribution over the space of all possible 30x30 grids, where each cell is either #
or .
",那么您应该简单地选择具有#
和.
:
等概率的每个单元格
for i in 0..<900 {
// arc4random_uniform(2) is either 0 or 1, with equal probability
tile.append(arc4random_uniform(2) == 0 ? "." : "#")
}
如果答案是"a random choice from the uniform distribution over 30x30 grids in which exactly 400 cells are #
",那么你应该预先选择400个唯一索引,然后再将它们转换为#
。
照原样,您的代码 可能 生成只有一个 #
的网格(尽管这种可能性很小)。而且它 永远不会 生成超过 400 #
的网格。
- 您只将 900 个中的 400 个转换为 #
- 您将有很多重复项(用# 覆盖#),所以我希望有很多“.”。剩下的。
我觉得你显示的模式还不错。
把你所有的货物都放在bag/array里,随机分类,然后一件一件拉出来。
我有以下代码在 Swift 中生成随机填充的网格:
import Foundation
var tile = [String](count: 900, repeatedValue: ".")
// Randomly populate the grid with hashes
for i in 0...400 {
tile[Int(arc4random_uniform(899))] = "#"
}
// Print the grid to console
for y in 0...(29) {
for x in 0...(29) {
print("\(tile[y * 10 + x])")
}
println("")
}
运行 此代码生成如下所示的网格:
..##..#.#...#..#..#.#.####.#..
..#..#..#.#.####.#....###.#.#.
#.####.#....###.#.#.#####.....
..###.#.#.#####.....#...#....#
#####.....#...#....###.##.###.
#...#....###.##.###..#.....#..
##.##.###..#.....#...##..#.##.
.#.....#...##..#.##...#.####..
.##..#.##...#.####..###..#.#.#
..#.####..###..#.#.#.#..#.....
###..#.#.#.#..#.........#...##
.#..#.........#...##.##.......
....#...##.##............#...#
.##............#...####....##.
.....#...####....##..#.#.....#
###....##..#.#.....#........#.
.#.#.....#........#...#.#..#..
........#...#.#..#......#....#
..#.#..#......#....#.##.#...##
....#....#.##.#...###...#..#..
.##.#...###...#..#..#.#..#...#
#...#..#..#.#..#...#####...##.
#.#..#...#####...##..#.......#
####...##..#.......#.#.#.....#
.#.......#.#.#.....##.........
.#.#.....##..........##.#..#.#
#..........##.#..#.##.#.#.....
.##.#..#.##.#.#.....##...#....
#.#.#.....##...#......#.##....
##...#......#.##.....#.######.
你可以清楚地看到一个模式在重复。有没有办法让"throw"功能让生成更有说服力?
你的打印函数是错误的:tile[y*10 + x]
应该是tile[y*30 + x]
。
至于生成网格:您到底想要什么?
如果答案是"a random choice from the uniform distribution over the space of all possible 30x30 grids, where each cell is either #
or .
",那么您应该简单地选择具有#
和.
:
for i in 0..<900 {
// arc4random_uniform(2) is either 0 or 1, with equal probability
tile.append(arc4random_uniform(2) == 0 ? "." : "#")
}
如果答案是"a random choice from the uniform distribution over 30x30 grids in which exactly 400 cells are #
",那么你应该预先选择400个唯一索引,然后再将它们转换为#
。
照原样,您的代码 可能 生成只有一个 #
的网格(尽管这种可能性很小)。而且它 永远不会 生成超过 400 #
的网格。
- 您只将 900 个中的 400 个转换为 #
- 您将有很多重复项(用# 覆盖#),所以我希望有很多“.”。剩下的。
我觉得你显示的模式还不错。
把你所有的货物都放在bag/array里,随机分类,然后一件一件拉出来。