I'm trying to make a procedurally generated map/2d_array using Cellular Automata.
I found a good video explaining Cellular automata and followed it. Video link: https://www.youtube.com/watch?v=slTEz6555Ts
But for some reason I only get a fully filled 2d array with the same value and not a procedurally generated map like 2d array. I tried to Debug it and see what's the problem and for some reason this if statement is always false:
//check if neighbor is a - and if so add neighbor_wall_count
if (temp_grid[k, j] == '-')
{
neighbor_wall_count++;
}
And I can't find the reason why. Maybe you could help?
Heres all the code:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
//this line string is used for printing
string line = "";
//2d array size specifications
int width = 10;
int height = 10;
//density = how much procent will be - in the array when i we make random noise
int density = 60;
//create the 2d array
char[,] grid = new char[width, height];
//This creates random noise in array or its a function make_noise_grid(density) from video https://www.youtube.com/watch?v=slTEz6555Ts
for (int y = 0; y < height; y++)
{
line = "";
for(int x = 0; x < width; x++)
{
int rand = new Random().Next(1, 100);
if(rand > density)
{
grid[x, y] = '+';
}
else
{
grid[x, y] = '-';
}
line += grid[x, y];
}
Console.WriteLine(line);
}
// This is just a divider to divide random noise map from map with applied with cellulat automata
Console.WriteLine("-------------------------------------------------------------------");
//This section is the function apply_cellular_automation(grid, count) from video https://www.youtube.com/watch?v=slTEz6555Ts
//This first for will determine how much times Cellular Automata will be added
for (int i = 0; i < 1; i++)
{
//Create a temporary map
char[,] temp_grid = grid;
//Go through array
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
//create variable to store neighbor minuses (-)
int neighbor_wall_count = 0;
//go through neigbors
for (int j = y-1; j <= y+1; j++)
{
for(int k = x-1; k <= x+1; k++)
{
//check if in bounds of array if not just assume its -
if (j >= 0 && j < grid.GetLength(1) && k >= 0 && k < grid.GetLength(0))
{
//check if this is not the coordinate whose neighbors we are checking
if (j != y && k != x)
{
//check if neighbor is a - and if so add neighbor_wall_count
if (temp_grid[k, j] == '-')
{
neighbor_wall_count++;
}
}
}
else
{
neighbor_wall_count++;
}
}
}
//if there are more than 4 neighbors that are - make the coordinate a - and if not make it +
if (neighbor_wall_count > 4)
{
grid[x, y] = '-';
}
else
{
grid[x, y] = '+';
}
}
}
}
// this is to print the array when we apply Cellular automata.
for (int y = 0; y < height; y++)
{
line = "";
for (int x = 0; x < width; x++)
{
line += grid[x, y];
}
Console.WriteLine(line);
}
}
}
}
And the result from this:
-------+--
++---+-+--
+--++--+-+
--+--+----
-+--+-----
----+-+---
---+--+++-
-+---++--+
+--+-----+
++---+--+-
-------------------------------------------------------------------
-++-+-+-+-
++++++++++
++++++++++
++++++++++
++++++++++
++++++++++
++++++++++
++++++++++
++++++++++
-++++++++-
Almost 3 years later but i will post this in case this serves to anyone to see a working cellular automata cave system, your fault in your code is the condition in the [k,j] loops of checking if your are in the x and y block, your condition is reversed, this is the correct condition in if: (j != y || k != x)
This is the working code:
//this line string is used for printing
string line = "";
//2d array size specifications
int width = 40;
int height = 40;
//density = how much procent will be - in the array when i we make random noise
int density = 40;
//create the 2d array
char[,] grid = new char[width, height];
//This creates random noise in array or its a function make_noise_grid(density) from video https://www.youtube.com/watch?v=slTEz6555Ts
var random = new Random();
for (int y = 0; y < height; y++)
{
line = "";
for (int x = 0; x < width; x++)
{
int rand = random.Next(1, 100);
if (rand > density)
{
grid[x, y] = '#'; //wall
}
else
{
grid[x, y] = '.'; //free space
}
line += grid[x, y];
}
Console.WriteLine(line);
}
// This is just a divider to divide random noise map from map with applied with cellulat automata
Console.WriteLine("\\\\-------------------------------------------------------------------//");
//This section is the function apply_cellular_automation(grid, count) from video https://www.youtube.com/watch?v=slTEz6555Ts
//This first for will determine how much times Cellular Automata will be added
for (int i = 0; i < 1; i++)
{
//char[,] temp_grid = DeepCopy(width, height, grid);
char[,] temp_grid = (char[,])grid.Clone();
//Go through array
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
//create variable to store neighbor minuses (-)
int neighbor_wall_count = 0;
//go through neigbors
for (int k = x - 1; k <= x + 1; k++)
{
for (int j = y - 1; j <= y + 1; j++)
{
//check if in bounds of array if not just assume its -
if (j >= 0 && j < grid.GetLength(1) && k >= 0 && k < grid.GetLength(0))
{
//check if this is not the coordinate whose neighbors we are checking
if (j != y || k != x)
{
//check if neighbor is a # and if so add neighbor_wall_count
if (temp_grid[k, j] == '#')
{
neighbor_wall_count++;
}
}
}
else
{
neighbor_wall_count++;
}
}
}
if (neighbor_wall_count > 4)
{
grid[x, y] = '#';
}
else
{
grid[x, y] = '.';
}
}
}
}
// this is to print the array when we apply Cellular automata.
for (int y = 0; y < height; y++)
{
line = "";
for (int x = 0; x < width; x++)
{
line += grid[x, y];
}
Console.WriteLine(line);
}
Console.ReadKey();
This is the result:
.##..##...######.###########..###..#####
....##..#..#.#.#####.#.###.#.#..#..#.###
###.###..######.#.##.#...#.#####.###..##
#.#.#######...##...##.##..#.#..#..##.###
#######..##.########.#....#.##.###....#.
####...#.####..#.#.#.#.###..#..###..##.#
###..###..##.....##.###..##.###.#.#.##.#
##..##..#.###.#...##..#.##..##.#..#...##
.###.#.###.####.#..##....#.....##...##.#
#.##.########......######.##.##.##.##.#.
.##.##..##.##...##.##.#.#.######..#.##.#
#.###..##.###..###########...##..#.#.#..
...##.#....##..#.##...#...###..#####.###
...##.##......#.....####..####...####...
.##...#.##.#.##..#...###.##...#.#.##...#
.##.####....#.#####.##.##.#..#######..#.
##########...####.##.####.####..#..#.#.#
###.##..#.#.#..####.#...####.#.##..#..#.
#.#.#####.########.###..#...###.#..#..#.
#..#.####....###.##########..###....#.#.
##..#.###.##..#####.##.##.##...#..#.####
####.#.#.#.#...###.#.####.##.#...##.####
##.#.##.#.#.###..####.####.####.###.#.#.
##.#.###.#.#.##.#.#.#.####...#.#...#.###
.####.###..#..###...#.###.####...#####..
#.####.###..#..#.######..#.##.#.......#.
..#.#..#.#.##.#..#.#..##..#.....#.######
...####.###.#.##...#####.#.###.####.....
#####..##.##..###.###.#.###.##..#...#...
###.#..##.##.#.##.##.##...#......#####.#
.######...##.###.####.#..#.#.####.#.##.#
#.#...###.####..###.###.####.###.#.###.#
##.###..#..#####...####.###.###..##.#.##
#..##....##.##.#....#.####..##.#..##..##
.#..#....##.##.#...####..###.####..##.#.
#..##..#..####.#..#######.###.#..#.###.#
####.#.#...#.#..#######.####.####.#.#.##
.........####..#....#.##.#..##.##.#..#.#
###.#.#...#####.###.##..##...####.###.##
#..##.#...#..####.###..#########.##.###.
\\-------------------------------------------------------------------//
#..#####.###############################
##...##...###########.#.###.#.##..#.####
#..########...##.####.#.#.#.#.....#.####
#######..############......####.###...##
############..###.#.#.#....#....#....###
#######...##....###.#.#....#.#####....##
###......####.....##...###...#.#.#....##
###...##.#####.....###........#......###
###.#.########.....###.##.....#.......##
#####.########.....###...#..#.##....##.#
#####.#######.....########..###....##...
...###.....##...####.#.#..#######.#.#.##
...###.#........#..#####...###...####...
.....#...............##...##....####...#
#..#.###.......#....#####..#.#.#.###....
####.####....#####...#####.#...#.##....#
########......#######..######.#####....#
##########.#.#########.#.#.####........#
##.#####.#...#########.####..###.......#
##..######.###############....#......#.#
###..####.....#############...#....#.###
###.#.###.#...###############....#.#.###
###.#.##.......#####.######.#......#.###
###.#####...####.#.#.##########..#####.#
#########......#.#.#.#####..#.........##
.####.###.......#....###..##......####.#
...####.###..#....#####....##....#.....#
#.###..#####.#.#..#######.#......#.#...#
######.#####..##...#####...#.....###....
######...####.########...#.........##...
####...#.####.#.######....#...#..#######
######.....#####..####.#.##.#####.######
#........######.....###########...##.###
#...#......####....############....#.#.#
#..#......#####....############...####.#
###........##.#...######.########..#####
#.........###......#############.#.#.###
###.......####..######..###..#####.#..##
#.........######...#...####.######.#.###
######.#.###############################