How to create seemingly random arrangement of tiles in a grid?

I am making a game with a huge environment where terrain tiles appear as the player gets close enough to them. It can be thought of as a grid of tiles with coordinates starting at (0, 0), and extending outwards in all directions. I will have a variety of these terrain tiles, and I need them to be placed on the map in a way that appears to not have a pattern, but it can not be random either. Manually setting the tiles is not an option because the map will be gigantic. I need a function that will take the map coordinates and output which tile to spawn.

Thanks in advance!

You need to push the tile coordinates through a hash function. You need to be careful how you combine the coordinates - one reasonable way is to hash one of the coordinates first, then add the hash of the sum of the coordinates, then hash again - i.e. Hash(Hash(x) + Hash(Hash(x)+y)).

For your purposes it doesn’t matter much what you use for the hash function, so long as it’s not too predictable and it avoids periodicity. Most hashes that get studied these days are for cryptographic purposes, which is overkill here. The other main set of hashes are those used for creating things like C#'s HashSet - and all C# objects provide these (the GetHashCode() method). However, these are not meant to be random-looking - their only goal is to avoid collisions. So it can be hard to find something in-between, which is cheap to compute but doesn’t show obvious patterns.

I’ve taken the top function from this page and converted it to C# below:

http://burtleburtle.net/bob/hash/integer.html

public static int Hash(int input)
{
	uint a = (uint)input;
	a = (a ^ 61) ^ (a >> 16);
	a = a + (a << 3);
	a = a ^ (a >> 4);
	a = a * 0x27d4eb2d;
	a = a ^ (a >> 15);
	return (int)a;
}

I haven’t checked suitability much, but the page I took it from seems to have a bunch of analysis further down, if you’re interested enough. You could also read Wikipedia: http://en.wikipedia.org/wiki/List_of_hash_functions

Again, for getting a hash from two coordinates, make sure you don’t do something symmetrical or periodic - nesting the hashes is a simple solution that gives good results.

public static int Hash(int x, int y)
{
    int hy = Hash(y);
    return Hash(Hash(x+hy) + hy);
}