2

ゲーム プロジェクトのコードを Python から C# に移植しています。現在、2 つの宇宙船が互いに友好的か敵対的かをゲームがチェックする特定のコードの翻訳に問題があります。派閥は整数で識別されます。敵対的または友好的な派閥番号のリストが使用されます。

敵意または友好度をチェックするための関数は (Python):

def is_hostile_faction(ownF, oppF):
    hostile_factions = { 1:[5], 2:[4,5], 3:[5], 4:[2,5], 5:[1,2,3,4], 6:[5], 7:[8,9,10], 8:[5,7,9,10], 9:[7,8,10], 10:[7,8,9]}
    if oppF in hostile_factions[ownF]:
        return True
    else:
        return False

def is_allied_faction(ownF, oppF):
    allied_factions = { 1:[1,2], 2:[1,2,3], 3:[3], 4:[4], 5:[5], 6:[1,2,3,6], 7:[7], 8:[8], 9:[9], 10:[10] }    
    if oppF in allied_factions[ownF]:
        return True
    else:
        return False

それぞれ。ここまでは、とても簡単です。次のような見苦しいコードを書かずに、C# で同じ関数を再作成するにはどうすればよいでしょうか。

List<int> faction1hostiles = new List<int> {5};
List<int> faction2hostiles = new List<int> {4,5};
// etc
Dictionary<int,List<int>> hostileFactions = new Dictionary<int,List<int>();
hostileFactions.Add(faction1hostiles);
hostileFactions.Add(faction2hostiles);
// etc

public void isHostile(int ownF, int oppF) {
    if (hostileFactions[ownF].Contains(oppF)) {
        return true; }
    else { return false; }
}

// same for friendly factions

元コードは Python (Panda3D フレームワーク)、対象コードは C# (Unity3D フレームワーク) です。データ構造がオンザフライで作成される Python コードの単純さを考慮すると、C# にも同様に単純なソリューションが必要でしょうか?

4

2 に答える 2

2

私はあなたがそのようなことをすることができると思います:

Dictionary<int,int[]> hostileFactions = new Dictionary<int,int[]>(){
    {1,new[]{5}}, {2,new[]{4,5}}
};

public void isHostile(int ownF, int oppF) {
    return hostileFactions[ownF].Contains(oppF)
}
于 2013-01-03T23:49:02.897 に答える
1

それは、あなたが「醜いコード」と呼ぶものによって異なります。次のように書くことができます。

var allies = new Dictionary<int, List<int>>{
    {1, new List<int>{1,2}},
    {2, new List<int>{1,2,3}},
    //...
};

または、次のような特定の敵対行為や同盟を追跡することもできます。

var alliances = new[]{
    new {a=1,b=1},
    new {a=1,b=2},
    new {a=2,b=1},
    new {a=2,b=2},
    new {a=2,b=3},
    //...
};

var allies = alliances.ToLookup(e => e.a, e => e.b);

または、特定のチームの味方の実際のリストが必要なく、代わりに 2 つのチームが同盟を結んでいるかどうかをすばやく確認したい場合は、次のように同盟チーム ペアのセットを作成できます。

private struct TeamPair
{
    private int _team1;
    private int _team2;
    public TeamPair(int team1, int team2)
    {
        _team1 = team1;
        _team2 = team2;
    }
}

ISet<TeamPair> alliances = new HashSet<TeamPair>(
    new[]{
        new {a=1,b=1},
        new {a=1,b=2},
        new {a=2,b=1},
        new {a=2,b=2},
        new {a=2,b=3},
        // ...
    }.Select(e => new TeamPair(e.a, e.b)));


public bool isAllied(int ownF, int oppF) {
    return alliances.Contains(new TeamPair(ownF, oppF));
}

本当に望むなら、配列の配列を使用して他のより簡潔な構文を思いつくことができると確信しています。

ただし、アライアンス マッピングをコードの外部 (おそらく XML または CSV ファイル、またはリレーショナル データベース) に格納し、コードを使用してそのデータをデータ構造に読み込むことを検討することをお勧めします。コードにデータを結合しすぎているように感じます。

@Lattyware が述べたように、書き換えを行うと、新しい言語用にプログラムを記述するためのより良い方法を考えるまたとない機会が得られます。直接翻訳が最善の方法になることはめったにありません。元の作者でさえ、今日もう一度やる機会があれば、おそらく同じ方法でゲームを書くことはなかったでしょう。

于 2013-01-03T23:48:19.510 に答える