将列表创建的词典从Python翻译成C#

时间:2013-01-03 23:41:31

标签: c# python list dictionary

我正在将游戏项目的代码从Python移植到C#。现在我在翻译特定代码时遇到了麻烦,游戏会检查两艘太空船是否友好或相互敌对。派系通过整数来识别。使用敌对或友好派系号码列表。

检查敌意或友善的功能是(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#必须有一个同样简单的解决方案吗?

2 个答案:

答案 0 :(得分: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)
}

答案 1 :(得分: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);

或者,如果你永远不想要一个给定团队的实际盟友列表,而你只是想快速发现两个团队是否有联盟,你可以创建一组联盟团队对,就像这样:

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所提到的,进行重写可以为您提供一个独特的机会来思考为新语言编写程序的更好方法:直接翻译很少是最好的方法。如果他们今天有机会再次这样做,即使原作者也不会以相同的方式编写游戏。