Как вызвать функцию, когда 3 из 7 логических значений имеют значение true - PullRequest
3 голосов
/ 30 марта 2020

Я пытаюсь создать систему предоставления квестов следующим образом:

Существует 7 логических значений и метод, который следует вызывать только тогда, когда любые 3 из 7 логических значений оцениваются как true. Каков наиболее эффективный / лучший способ выполнить эту задачу? Я немного новичок в программировании, поэтому вот фрагмент кода:

private bool a;
private bool b;
private bool c;
private bool d;
private bool e;
private bool f;
private bool g;

private void Start() {
    //How do I call TheMethod() when any 3 of the 7 booleans evaluates to true?
}

private void TheMethod() {
   //DO SOMETHING
}

Нужно ли создавать несколько условий, если это проверяется?

Ответы [ 4 ]

2 голосов
/ 30 марта 2020

использование массива или списка с Linq может упростить ваш тест:

using System.Linq;
using System.Collections.Generic;    

// using array a = trig[0], b = trig[1] and so on
private bool[] trig = new bool[7] { true, false, false, true, true, false, true };

//or using list a = trig1[0], b = trig1[1] and so on
private List<bool> trig1 = new List<bool>{ true, false, false, true, true, false, true };


 void Start(){  
        //same syntax array or list
        trig[0] = false; // change value for fun
        if(trig.Count(p => p) ==3)// result = 3
        {
           TheMethod(); 
        }

        trig1[0] = false;// change value for fun
        if(trig1.Count(p => p) ==3) //result = 3
        {
           TheMethod(); 
        }


        //if you want to keep your boolean variable outside a collection
        //you add your boolean variables to list (or array) 
        var list = new List<Bool>() {a,b,c,d,e,f,g};
        if (list.Count(p => p) == 3)
        {
           TheMethod();
        }     
}
2 голосов
/ 30 марта 2020

самый эффективный способ - это изменить то, как вы это делаете; рассмотрите вместо этого:

private uint bits;

и используйте битовую математику для определения отдельных флагов, например:

private bool A => (values & 1) != 0;
private bool B => (values & 2) != 0;
private bool C => (values & 4) != 0;
// etc, powers of 2

Теперь вы можете использовать

var setBits = BitOperations.PopCount(bits);

и проверить что , то есть if (setBits == 3). Затем он использует встроенный процессор c, когда это возможно, в противном случае возвращается к прилично оптимизированной реализации программного обеспечения.

2 голосов
/ 30 марта 2020

Без необходимости в массиве вы могли бы сделать

private void Start() 
{
    if(Exactly3True())
    {
        TheMethod();
    }
}

private void TheMethod() 
{
   //DO SOMETHING
}

private bool Exactly3True()
{
    var checkSum =    (a ? 1 : 0)
                    + (b ? 1 : 0)
                    + (c ? 1 : 0)
                    + (d ? 1 : 0)
                    + (e ? 1 : 0) 
                    + (f ? 1 : 0)
                    + (g ? 1 : 0);

    return checkSum == 3;
}

(см. троичный оператор ?)

не то, чтобы это было лучшим в отношении удобства обслуживания ;)

1 голос
/ 30 марта 2020

Если вы используете Unity, вы можете попробовать

[SerializeField]
private bool[] values;

и прикрепить этот код к любому существующему GameObject, вы можете установить длину values в инспекторе. Установите значение 7 и

private void Start()
{
    int boolCount = 0;
    foreach (var b in values)
    {
        if (b == true) boolCount++;

        if (boolCount == 3)
        {
            TheMethod(); 
            break;
        }
    }
}

Это просто пример кода, но использование функции сериализации в Unity значительно повысит читабельность вашего кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...