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

时间:2019-11-16 17:23:34

标签: c# arrays contains

这是一个基于某些元素组合的游戏,我试图找到一种方法来使两个元素相互比较以减少硬编码。最后,我确实提供了一个可行的解决方案,但我正在尝试学习任何更简单,直接且易于理解的方法。

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

我想在bothPlayers中搜索活动元素,以便影响Player的健康。我知道这行不通,但是我想知道是否可以做类似的事情:

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

3 个答案:

答案 0 :(得分:2)

这是一个棘手的问题,但值得庆幸的是,您正在使用一种语言,该语言具有隐藏复杂性所需的所有工具。

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)),但对于此答案,我保持简单。

答案 1 :(得分:0)

Linq解决方案:

  1. 检查是否有水火向导(使用Linq)
  2. 用于搜索和添加健康状况等...

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

您可以更改要搜索的向导及其依赖的属性

答案 2 :(得分:0)

有多种方法可在集合中查找项目。例如:

// 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++;
}