0

I don't know if key is the right word for this but I implemented a version of the Diamond-Square algorithm and I was wondering if there is any way to "save" the current output and recreate it using a simple (6 to 10 characters) key. The only way I tought so far is to save it as a single number/string containing the output value of each cell but for a 17X17 grid I would have at least a 289 characters long sequence (assuming the output is a single digit per cell).

Since the algorithm is random I can't think of a better way to do it. If it is impossible can you tell me about better algorithm to use. Thank you :)

PS: I'm using unity 3D and C#

AntoineO
  • 3
  • 5
  • 2
    You just need to know and set the seed for your prng and you will create the same output. – thehennyy Sep 26 '18 at 12:11
  • Do you have a good link or some good documentation I can read on this it seems quite confusing for me :) – AntoineO Sep 26 '18 at 12:15
  • 1
    Somewhere in your code, there's a RNG. It will have another constructor that takes a ***seed*** value. When supplied with a seed value, the RNG's output becomes deterministic, and, supplied with the same seed, will return the same sequence of values on successive runs. All you need to do now is show us how you get your random numbers. – spender Sep 26 '18 at 12:17
  • Also, how many different states can each tile be? – spender Sep 26 '18 at 12:20
  • For my random numbers I'm using unity random.range(-17,17) for the state I don't really know what your talking about ... but I have only one "type of tile" so all my tiles are clones of the same object. – AntoineO Sep 26 '18 at 12:28
  • https://docs.unity3d.com/ScriptReference/Random.html read `state` and `InitState`. – thehennyy Sep 26 '18 at 12:36
  • Wow thanks a lot! I'll try this when I get home! Did not expect to get that much help in such a short time thanks guys :) P.S: Don't know how to upvote your comments but I would totally do it :) – AntoineO Sep 26 '18 at 12:48
  • Storing a random seed value seems like a sensible approach to this, but if it were not you might take the following approach: each board state could be viewed as either a 1 or 0 depending on whether it has a tile or not. With a 35x35 board this would mean that you could store your data in 1225 bits, or approximately 20 `ulong` (64bit numbers). By converting between binary and ulong, you could store all possible board-states with 20 long numbers. – spender Oct 01 '18 at 19:09

2 Answers2

0

the following class is from the unity tutorial for procedural cave generation, but ive included it because it includes the core elements you need. it uses a seed to generate a map, the same seed will regenerate the same map.... you could use a seed in your generation process, even if it is random, then you could always reuse that seed to return to that map.

 using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System;

    public class MapGenerator : MonoBehaviour {
        public int width;
        public int height;

        public string seed;
        public bool useRandomSeed;

        [Range(0,100)]
        public int randomFillPercent;
        int[,] map;

        private void Start()
        {
            GenerateMap();
        }

        void GenerateMap()
        {
            map = new int[width, height];
            RandomFillMap();

            for (int i = 0; i < 5; i++)
            {
                SmoothMap();
            }
        }
        void RandomFillMap()
        {
            if (useRandomSeed)
            {
                seed = Time.time.ToString();
            }
            System.Random prng = new System.Random(seed.GetHashCode());
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (x == 0 || x == width - 1 || y == 0 || y == height - 1)
                    {
                        map[x, y] = 1;
                    }
                    else
                    {
                        map[x, y] = (prng.Next(0, 100) < randomFillPercent) ? 1 : 0;
                    }
                }

            }
        }
        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                GenerateMap();
            }
        }
        void SmoothMap()
        {
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    int neighborWallTiles = GetSurroundingWallCount(x, y);
                    if (neighborWallTiles > 4)
                    {
                        map[x, y] = 1;
                    }
                    else if (neighborWallTiles<4)
                    {
                        map[x, y] = 0;
                    }

                }
            }
                }

        int GetSurroundingWallCount(int gridx, int gridy)
        {
            int wallcount = 0;
            for(int neighborx=gridx-1; neighborx<=gridx + 1; neighborx++)
            {
                for (int neighbory = gridy - 1; neighbory <= gridy + 1; neighbory++)
                {
                    if (neighborx >= 0 && neighborx < width && neighbory >= 0 && neighbory < height)
                    {

                        if (neighborx != gridx || neighbory != gridy)
                        {
                            wallcount += map[neighborx, neighbory];
                        }
                    }
                    else
                    {
                        wallcount++;
                    }

                }
            }
            return wallcount;
        }

            void OnDrawGizmos()
            {
                if (map != null)
                {
                    for (int x = 0; x < width; x++)
                    {
                        for (int y = 0; y < height; y++)
                        {
                        Gizmos.color = (map[x, y] == 1) ? Color.black : Color.white;
                        Vector3 pos = new Vector3(-width / 2 + x + .5f, 0, -height / 2 + y + .5f);
                        Gizmos.DrawCube(pos, Vector3.one);
                        }
                    }
                }

        }

    }
Technivorous
  • 1,682
  • 2
  • 16
  • 22
0

I did like the comments said I used Random.InitState provided with unity and everything is working fine. Thanks Again!

UnityEngine.Random.InitState(seed);

I can control the seed as I wish and it gives me the same map for the same seed.

AntoineO
  • 3
  • 5