比较同一类实例之间变量的最佳方法是什么



这是一款基于某些元素组合的游戏,我正试图找到一种方法,让两个元素相互比较,以减少硬编码。最后,我确实提供了一个有效的解决方案,但我正在努力学习任何更简单、更直接、更可读的方法。

//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:的解决方案

  1. 检查是否有水和火精灵(带Linq(
  2. 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++;
}

最新更新