很抱歉,我无法在问题标题中更好地解释。我会在这里更好地定义我的问题。
这就是我正在做的事情 - 在我的游戏中,可以选择彼此使用物品。对于每对项目,游戏执行动作。
目前,游戏使用了两个变量:“ItemUsed”和“ItemUsedOn”。首先,游戏选择第一项 - 其id转到“ItemUsed”,然后他选择第二项,它的id转到“ItemUsedOn”。然后,存在一个定义特定操作的空白。
代码的简短示例:
if (ItemUsed == "itm_cable")
{
if (ItemUsedOn == "itm_towel")
SubMain.ItemsMergedText = "To achieve what?";
else if (ItemUsedOn == "itm_wet_towel")
SubMain.ItemsMergedText = "No, water will damage it";
else if (ItemUsedOn == "itm_glass")
SubMain.ItemsMergedText = "I don't need to cut the cable";
}
if (ItemUsed == "itm_book_electronics")
{
if (ItemUsedOn == "itm_towel")
SubMain.ItemsMergedText = "Why?";
if (ItemUsedOn == "itm_wet_towel")
SubMain.ItemsMergedText = "No, water will damage the book";
else if (ItemUsedOn == "itm_soap")
SubMain.ItemsMergedText = "Wrong plan";
else if (ItemUsedOn == "itm_hair")
SubMain.ItemsMergedText = "It won't help";
}
还有很多这样的配对。 但是,这种方法存在问题。当两个项目组合时,它们的顺序无关紧要,例如“itm_toolbox”可以是“ItemUsed”而“itm_cable”可以是“ItemUsedOn”,但也可以是相反的方式,结果将是相同的。如何实现这一目标?
如果符合以下条件,我确实尝试在每个“较大”中使用它:
else
CombineItems(ItemUsedOn, "itm_book_edda");
但这并不总是有效,我找不到原因。
所以,我正在寻找的是获得2个变量的函数:
void CombineItems(string Item1, string Item2)
然后在这些情况下给出相同的结果:
if (Item1="Tomato")&&(Item2="Cucumber")
Item3="Salad"
if (Item1="Cucumber")&&(Item2="Tomato")
Item3="Salad"
我的问题:如果不使用这么多“if's”,有没有更简单的方法呢?
提前谢谢你, 叶甫盖尼
答案 0 :(得分:5)
我建议你创建一个例如UnorderedPair
类型,它会覆盖.Equals
和/或==
的行为,这样:
new UnorderedPair("Tomato", "Cumcumber") == new UnorderedPair("Cucumber", "Tomato");
然后,您可以将所有if
语句缩减为简单字典:
combinedItems = new Dictionary<UnderedPair, string>
{
[new UnorderedPair("Tomato", "Cumcumber")] = "Salad",
[new UnorderedPair("Bread", "Filling")] = "Sandwich",
...
};
然后您的确定文本的代码可以是:
SubMain.ItemsMergedText = combinedItems[new UnorderedPair(ItemUsed, ItemUsedOn)];
答案 1 :(得分:2)
您可以使用params
(将它们视为数组)和LINQ。将沙拉项目也存放在一个阵列中:
private string[] SaladItems = new string[] { "Tomato", "Cucumber" };
string CombineItems(params string[] Items)
{
bool isSalad = SaladItems.Length == Items.Length && !SaladItems.Except(Items).Any();
if (isSalad) return "Salad";
// other types ...
return null; // no match, exception?
}
侧注:如果你想接受“番茄”(所以忽略这种情况)请使用:
!SaladItems.Except(Items, StringComparer.InvariantCultureIgnoreCase).Any()
答案 2 :(得分:1)
如果将逻辑结构化为单独的部分,则可以使这个无穷无尽的比较列表变得更小。
首先,我会创建一个列表左右来保存项目及其结果:
var items = new[] { new { Item1 = "tomato", Item2 = "Cucumber", Result = "Salad" }
, new { Item1 = "tomato2", Item2 = "Cucumber2", Result = "Salad2" }
};
然后找到匹配的项目:
var match = items.FirstOrDefault
(itm => (itm.Item1 == Item1 && itm.Item2 == Item2)
|| (itm.Item1 == Item2 && itm.Item2 == Item1)
);
答案 3 :(得分:1)
有两种方法可以降低整个代码中的重复数量:
对项目进行排序,使其按字母顺序排列:
if(Item1 > Item2) {
var tmp = Item2;
Item2 = Item1;
Item1 = tmp;
}
现在,您剩下的所有代码都可以假设Item1
值的字母顺序始终早于Item2
,因此您只需编写:
if (Item1="Cucumber")&&(Item2="Tomato")
Item3="Salad"
或者,您可以在耗尽所有选项后(再次只写一次),使用交换的参数递归调用您的方法:
void TakeAction(Item1, Item2) {
.
.
.
/* No matches */
else {
TakeAction(Item2,Item1);
}
}
答案 4 :(得分:0)
var items= new HashSet<string>();
items.Add("tomato");
items.Add("Cucumber");
if(items.Contains("tomato") && items.Contains("Cucumber")) //Order does **NOT** matter
Item3="Salad";