1

I have the following code to generate a randomly populated grid in 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("")
}

Running this code produces a grid which looks like the following:

..##..#.#...#..#..#.#.####.#..
..#..#..#.#.####.#....###.#.#.
#.####.#....###.#.#.#####.....
..###.#.#.#####.....#...#....#
#####.....#...#....###.##.###.
#...#....###.##.###..#.....#..
##.##.###..#.....#...##..#.##.
.#.....#...##..#.##...#.####..
.##..#.##...#.####..###..#.#.#
..#.####..###..#.#.#.#..#.....
###..#.#.#.#..#.........#...##
.#..#.........#...##.##.......
....#...##.##............#...#
.##............#...####....##.
.....#...####....##..#.#.....#
###....##..#.#.....#........#.
.#.#.....#........#...#.#..#..
........#...#.#..#......#....#
..#.#..#......#....#.##.#...##
....#....#.##.#...###...#..#..
.##.#...###...#..#..#.#..#...#
#...#..#..#.#..#...#####...##.
#.#..#...#####...##..#.......#
####...##..#.......#.#.#.....#
.#.......#.#.#.....##.........
.#.#.....##..........##.#..#.#
#..........##.#..#.##.#.#.....
.##.#..#.##.#.#.....##...#....
#.#.#.....##...#......#.##....
##...#......#.##.....#.######.

You can clearly see that a pattern is repeating itself. Is there a way to "throw" function so that the generation is more convincing?

Matteo Piombo
  • 6,688
  • 2
  • 25
  • 25
Alex Laing
  • 47
  • 5

2 Answers2

4

Your print function is wrong: tile[y*10 + x] should be tile[y*30 + x].


As for generating grids: what, precisely, do you want?

If the answer is "a random choice from the uniform distribution over the space of all possible 30x30 grids, where each cell is either # or .", then you should simply choose each cell with equal probability of # and .:

for i in 0..<900 {
    // arc4random_uniform(2) is either 0 or 1, with equal probability
    tile.append(arc4random_uniform(2) == 0 ? "." : "#")
}

If the answer is "a random choice from the uniform distribution over 30x30 grids in which exactly 400 cells are #", then you should choose 400 unique indexes up front, before converting them to #.

As is, your code may produce grids with only one # (though it is very unlikely). And it will never produce grids with more than 400 #s.

jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • I had written the program as I intended; it was the incorrect `tile[y * 10 + x]` you identified which was causing the repetition in the pattern. – Alex Laing Jul 15 '15 at 08:42
0
  1. You're only converting 400 of the 900 to a #
  2. You will have many duplicates (overwriting # with #), so I expect many '.' left over.

The pattern you show is pretty ok I guess.

Put all your goods in the bag/array, randomly sort them and pull them out one by one.

Bart
  • 25
  • 3
  • The limit of 400 was intended, but I could have the program iterate only over "." symbols, rather than all of the tiles. – Alex Laing Jul 15 '15 at 08:44