这是一款基于某些元素组合的游戏,我正试图找到一种方法,让两个元素相互比较,以减少硬编码。最后,我确实提供了一个有效的解决方案,但我正在努力学习任何更简单、更直接、更可读的方法。
//Wizard is a class
Wizard player1;
Wizard player2;
player1.health = 3;
player2.health = 3;
//Elements is an enum that allows fire/water/air to be selected
player1.elementSelected = Elements.fire;
player2.elementSelected = Elements.water;
Wizard[] bothPlayers = { player1, player2 };
我想在两个玩家中搜索活动元素,这样我就可以影响玩家的健康。我知道这不起作用,但我想知道我是否可以做一些类似的事情:
if (bothPlayers.Contains(Wizard.elementSelected.Elements.fire) && bothPlayers.Contains(Wizard.elementSelected.Elements.water))
或者,我想把它设置为一个新的数组,但这不会让我回调来影响玩家的健康,除非我把它们设置为一种新的变量,比如:
Elements[] bothSelectedElements = { player1.elementSelected, player2.elementSelected };
if (bothSelectedElements.Contains(Elements.fire) && bothSelectedElements.Contains(Elements.water))
{
Wizard playerWithFire; // = player who selected fire. Can't set without hardcoding
Wizard playerWithWater; // = player who selected water. Can't set without hardcoding
playerWithFire.health--;
playerWithWater.waterStrength++;
}
//当前工作解决方案
//set each Wizard container to null at the start of each check
Wizard fire = null;
Wizard water = null;
Wizard air = null;
//add check to make sure same elements aren't selected. Then assign the players to the containers
foreach (Wizard player in bothPlayers)
{
if (player.elementSelected == Elements.fire)
{
fire = player;
}
if (player.elementSelected == Elements.water)
{
water = player;
}
if (player.elementSelected == Elements.air)
{
air = player;
}
}
//then do the actual check
if (fire != null && water != null)
{
fire.health--;
water.waterStrength++;
}
//repeat with other if statement comparisons
这是一个棘手的问题,但值得庆幸的是,您使用的语言拥有隐藏复杂性所需的所有工具。
var elementWizards = wizards.GroupBy(w => w.elementSelected).ToDictionary(g => g.Key);
var elements = elementWizards.Keys.ToHashSet(); // gives us access to SetEquals
if (elements.SetEquals(new[] { Elements.Fire, Elements.Water }))
{
foreach (var wizard in elementWizards[Elements.Fire]) wizard.health--;
foreach (var wizard in elementWizards[Elements.Water]) wizard.waterStrength++;
}
else if (elements.SetEquals(new[] { Elements.Earth, Elements.Fire }))
{
// more effects...
}
请注意,SetEquals
不关心物品的顺序,因此您不必担心处理水/火而不是处理火/水。
脚注:在现实世界中,我会定义一些静态的HashSet<Element>
对象并调用if(foo.SetEquals(elementWizards.Keys))
,但我对这个答案保持简单。
使用Linq:的解决方案
- 检查是否有水和火精灵(带Linq(
-
Foreach搜索并添加健康状况等…
if (bothPlayers.Count(wizard => wizard.elementSelected == Elements.fire) > 0 && bothPlayers.Count(wizard => wizard.elementSelected == Elements.water) > 0) { bothPlayers.ForEach(wizard => { var _ = wizard.elementSelected == Elements.water ? wizard.waterStrength++ : wizard.elementSelected == Elements.fire ? wizard.health-- : 1; }); }
您可以更改正在搜索的向导以及依赖于它的属性
在集合中查找项有多种方法。例如:
// using Array.Find method
Wizard fire = Array.Find(bothPlayers, player => player.elementSelected == Elements.fire);
// or using System.Linq FirstOrDefault extension
Wizard water = bothPlayers.FirstOrDefault(player => player.elementSelected == Elements.water);
if (fire != null && water != null)
{
fire.health--;
water.waterStrength++;
}
对于两个以上的玩家,可以使用Lookup
将玩家分组:
var lookup = bothPlayers.ToLookup(player => player.elementSelected);
if (lookup.Contains(Elements.fire) && lookup.Contains(Elements.water))
{
foreach (Wizard fire in lookup[Elements.fire] ) fire.health--;
foreach (Wizard water in lookup[Elements.water]) water.waterStrength++;
}