2013-01-03 25 views
2

我將遊戲項目的代碼從Python移植到C#。現在我無法翻譯一段特定的代碼,遊戲會檢查兩艘太空飛船是友好的還是敵對的。派系通過整數進行識別。使用敵對或友好派系號碼列表。將列表創建的字典從Python轉換爲C#

用於檢查敵意或friendlyness功能是(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

試圖* *轉換代碼通常是一個可怕的想法 - 適合一種語言並不一定適合其他的解決方案。最好簡單地用其他語言重新實現。 –

+0

完全同意@Lattyware –

回答

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)); 
} 

我相信你能想出智慧h其他更簡潔的使用數組數組的語法,如果你真的想。

但是,您可能需要考慮將聯盟映射存儲在您的代碼之外:可能是XML或CSV文件或關係數據庫,然後使用您的代碼將該數據讀入數據結構。對我來說感覺就像你將代碼中的數據過多地耦合在一起。

正如@Lattyware提到的那樣,重寫可以讓您有一個獨特的機會去思考爲新語言編寫程序的更好方法:直接翻譯很少是最好的方法。即使是最初的作者,如果他們今天有機會再次這樣做,也許不會以同樣的方式編寫遊戲。

+0

感謝您的代碼,稍後我會仔細研究。是的,我知道我的代碼中包含了太多的數據。當足夠的數據累積時,我會將數據外部化爲XML文件,如現有的東西。謝謝。 – Bradamante

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) 
} 
+0

是的,那個程度的作品。謝謝。我不認爲可以像這裏所做的那樣使用新的「在線」語句。我認爲必須將它綁定到某個類型聲明的變量,然後添加這個參考集合。 – Bradamante