1

関係のある複雑な構造を処理するための最良の方法は何でしょうか?

私は自分のプロジェクトに銀河生成アルゴリズムを実装しています。基本的には、次の単純な列挙型があります。

GalaxySize { Small, Medium, Large };
GalaxyAge { Young, Mature, Ancient}; 
StarTypes { Black = 1, White = 3, Yellow = 1, Red = 3 };

これまでのところ、GalaxySizeの値によって制限された星を生成しています。次に、StarTypesからランダムにタイプを取得し、このタイプからスターを作成します。私がやりたいのは、StarTypesとGalaxyAgeの関係です。

つまり、若い銀河では(たとえば)黄色と白の星の可能性が高くなり、古代の銀河では黒と赤の星の可能性が高くなります。

私が考えているのは、StarTypeが「ロール」され、GalaxyAgeに応じて修飾子を追加する基本的なチャンスがあることです。これにより、特定の銀河時代でより一般的な星が増えます。

Example: weight (chance) of a white star in young galaxy is 3 base + 3 
from the "young" galaxy age modifier 
against the weight of a red star which has 3 base + 1 from the "young" modifier.


Resulting in:
White star type weight = (3 + 3 ) * rand.nextDouble() 
Red star type weight = (3 + 1) * rand.nextDouble()

明らかに列挙型だけでは十分ではないため、この機能を実現/表現する方法に関する提案はありますか?:)

4

3 に答える 3

0

銀河のクラス階層を作成してみませんか?

using System.Collections.Generic;

enum StarTypes { Black, White, Yellow, Red };

abstract class Galaxy {
    Dictionary<StarTypes, float> _baseProbabilities;
    protected Galaxy() {
        _baseProbabilities = new Dictionary<StarTypes, float>();
        _baseProbabilities[StarTypes.Black] = 1.0f;
        _baseProbabilities[StarTypes.White] = 3.0f;
    }
    public float GetStarProbability(StarTypes starType) {
        return _baseProbabilities[starType] + GetStarProbabilityModifier(starType);
    }
    protected abstract float GetStarProbabilityModifier(StarTypes starType);
}

class YoungGalaxy : Galaxy {
    protected override float GetStarProbabilityModifier(StarTypes starType) {
        switch (starType) {
        case StarTypes.White:
            return 3.0f;
        default:
            return 0;
        }
    }
}
于 2012-12-14T16:02:07.823 に答える
0

ランダムな星を生成したいのですが、これは銀河の年齢に基づいて重み付けされていますか? これらの重み付けがどこかに保存されていると思います。

そう:

若い銀河。仮定しましょう:

  1. 白星:確率40%
  2. 黄色い星:40%の確率
  3. 赤い星: 10% の確率で
  4. ブラックスター:確率10%

この場合、リストを作成し、4 つの白と黄色の星と 1 つの赤と黒の星を含めます。

ここで、各スター スロットに対して次の操作を行います。

    var start=GetListOfStarsBasedOnGalaxyAge(galaxyAge);
    var starList=new List<StarTypes>();
    for(int starCount=0;starCount<starsInGalaxy,starCount++)
{
    var star=var stars.OrderBy(a => Guid.NewGuid()).First();
 starList.Add(star);
}

基本的に、ランダムな Guid で並べ替えています。これは、安価ですが効果的なシャッフル方法です。これにより、星の選択がランダムになりますが、必要な適切な重み付けも使用されます。銀河全体が黒い星で満たされている可能性もありますが、その可能性は非常に低いです。

于 2012-12-14T16:04:11.900 に答える
0

私はアルゴリズムを本当に理解していませんでしたが、これから始めることができます:

sealed class Age
{
    public static readonly Young = new Size(3.0);
    public static readonly Mature = new Size(2.0);
    public static readonly Ancient = new Size(1.0);

    public double Weight
    {
        get;
        private set;
    }

    private Age(float weight)
    {
        Weight = weight;
    }
}

sealed class Size
{
    public static readonly Small = new Size(3.0);
    public static readonly Medium = new Size(2.0);
    public static readonly Large = new Size(1.0);

    public double Weight
    {
        get;
        private set;
    }

    private Size(float weight)
    {
        Weight = weight;
    }
}

のクラスを定義しましょうGalaxy

sealed class Galaxy
{
    public Age Age
    {
        get;
        set;
    }

    public Size Size
    {
        get;
        set;
    }
}

次に、星を定義するクラスを定義する必要があります。

abstract class Star
{
    protected Star(string color, Galaxy galaxy)
    {
        Color = color;
        Galaxy = galaxy;
    }

    public string Color
    {
        get;
        private set;
    }

    public Galaxy Galaxy
    {
        get;
        private set;
    }

    public abstract float Chances(Random rnd);
}

次に、各星の新しいクラスを定義しましょう (各タイプの実際の状況に応じて、アルゴリズム、式、および重みを変更することを忘れないでください)。

sealed class WhiteStar : Star
{
    public WhiteStar(Galaxy galaxy) : base("White", galaxy)
    {
    }

    public override float Chances(Random rnd)
    {
        return (3 + Galaxy.Age + Galaxy.Size) * rnd.NextDouble();
    }
}

もちろん、これは最終的なコードではありませんが、コードを整理するためのヒントとして使用できます。

最良の利点は、Galaxyが特定のタイプの星を取得するためのルールを認識していないことです。各星のタイプは独自のルールを認識しています (つまり、新しい星のタイプを追加する場合、すべてにまたがるルールを検索する必要はありません)。多くのクラス)。もちろん、これは他のクラスにも有効です (たとえば、MiddleAge銀河の年齢を追加する場合、他のクラスを更新する必要はありません)。

Weight最後に、プロパティの名前をドメインにとってより意味のある名前に変更することを忘れないでください。

于 2012-12-14T16:07:14.330 に答える