0

迷路をランダムに生成するゲームを作成しました。迷路は2D配列に格納されます。配列内の各整数は、セルが持つ壁の数を表します。

これは、次のJavaの例に基づいています: http: //rosettacode.org/wiki/Maze

人々がユニークな迷路を共有できるようにするために、私は配列を1人のユーザーが生成できる文字列または整数に変換し、コピーして別のゲームに貼り付け、同じ迷路をロードする方法を見つけようとしています。

ユーザーは最大25x25の迷路のサイズを選択できるため、各値(2 | 16 | 4 | 20 ...)を印刷するだけで非常に長くなります。

それを「コード」に変換することが不可能な場合、ファイルを使用せずにそれを行うことができる他の方法はありますか?

4

4 に答える 4

4

乱数ジェネレーターのシードを保存します。シードは、乱数ジェネレーターの出力を完全に決定します。

デフォルトのコンストラクターを使用java.util.Randomする代わりに、を使用して乱数を生成していると仮定します。new Random()

long seed = System.currentTimeMillis();
// store the seed somewhere
// so you can generate the same sequence of random numbers again
Random rng = new Random(seed);

共有のためにユーザーに提供できる短い「コード」を作成するには、数値を16進数または36進数に変換します。

String code = Long.toString(seed, 36); // codes like heeho82h
于 2013-03-17T17:34:21.523 に答える
4

その配列の値をランダムに作成している場合、それらを再生成するために必要なのは、それらの値を生成したPRNGの状態のみです。これは同時に、すべての疑似乱数ジェネレーターの最大の弱点と強みです。

ほとんどのPRNGは状態の取得と設定を許可していないか、かなり大きな状態を持っているため(Mersenne Twisterには内部で数キロバイトの状態があります)、代わりにシードを使用することをお勧めします。もちろん、レベル生成のために新しいPRNGを作成する(または既存のPRNGをリセットする)必要があります。

数字を人間が読める形式にするには、基数でレンダリングする必要があります。基数10は、それが数値であることを明確にし、生成と解析が最も簡単です。Base 16(16進数)とBase 64は、より短く、よりあいまいな「コード」を生成します。実際の値に関係なく、固定長になるようにパディングすることはおそらく良い考えです。

于 2013-03-17T17:37:00.490 に答える
1

Serializationコンセプトを使用しての状態を保存し、2-D array逆シリアル化を使用してそれを取得することができます。2-D arrayこれは、状態を保存して読み戻すための簡単なデモです。私はそれがあなたの助けになることを願っています:

import java.io.*;
class ArraySerialization 
{
    ByteArrayOutputStream baos;
    ByteArrayInputStream bins;
    public void saveState(Object obj)throws Exception
    {
        baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(obj);
        oos.close();
    }
    public int[][] readState()throws Exception
    {
        bins = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream oins = new ObjectInputStream(bins);
        Object obj = oins.readObject();
        oins.close();
        return (int[][])obj;
    }
    public static void main(String[] args) throws Exception
    {
        int arr[][]= {
                        {1,2,3},
                        {4,5,7}
                    };
        ArraySerialization ars = new ArraySerialization();
        System.out.println("Saving state...");
        ars.saveState(arr);
        System.out.println("State saved..");
        System.out.println("Retrieving state..");
        int j[][] = ars.readState();
        System.out.println("State retrieved..And the retrieved array is:");
        for (int i =0 ; i < j.length ; i++ )
        {
            for (int k = 0 ; k < j[i].length ; k++)
            {
                System.out.print(j[i][k]+"\t");
            }
            System.out.print("\n");
        }

    }
}
于 2013-03-17T18:03:31.673 に答える
0

ランダムジェネレーターを使用しますが、実際には決定論的なプロセスです。ランダムシードを知ることでそれを繰り返すことができます。Joniが述べたように、ランダムシードを共有するだけです。とにかく、データを共有したい場合:NxNメッシュにはNxNの内壁があり、壁の有無を保存するのに1ビットかかることを考えると、迷路を保存するにはNxNビットが必要になります。このようにして、90x90の迷路を1kbで保存できます。

于 2013-03-17T18:24:32.503 に答える