прекратить итерации после возврата истины? - PullRequest
0 голосов
/ 25 января 2012

(не могу придумать лучшего заголовка, не стесняйтесь редактировать его для заголовка, который лучше описывает вопрос)

У меня есть следующий метод:

bool CalculateNewState(int adjacent, bool currentState)
    {
        if (currentState == true)
        {
            foreach (int n in liveRule)
            {
                if (adjacent == n)
                {
                    return true;
                }               
            }
            return false;
        }
        else
        {
            foreach (int n in becomeAliveRule)
            {
                if (adjacent == n)
                {
                    return true;
                }               
            }
            return false;
        }
    }

Этодля игры о жизни клона.Я хочу реализовать то, что пользователь может создавать свои собственные правила.

bool currentState сообщает методу, жива ли ячейка или нет.int adjacent сообщает методу, сколько живых соседей имеет ячейка.

Что я хочу достичь, так это когда пользователь говорит: 2,3 and 5 neighbors keep the cell alive.Что он будет перебирать массив (liveRule), который содержит 2,3 and 5.когда происходит какое-либо совпадение, оно должно возвращать true, иначе false.

. Здесь происходит то, что после возврата true он продолжает повторяться и в конечном итоге возвращает совпадение с последним элементом в liveRule.

Что мне нужно сделать, чтобы прекратить итерации после того, как произошло совпадение?

Конечно, возможно, я неправильно подхожу к этой проблеме.Я начал с предложений здесь .

(пытался описать это в меру своих способностей, но все еще кажется довольно неясным)

Это C # в Unity3D.

Ответы [ 5 ]

6 голосов
/ 25 января 2012

Код, который вы внедрили, говорит: «Если смежность не равна 2, 3 или 5, верните».Очевидно, что смежные не могут быть равны всем из них!

Начать сначала.Переименуйте ваши методы, чтобы они были более понятными.Булевы значения должны отвечать на вопрос «истина / ложь», поэтому выбирайте имена, которые задают вопрос:

bool IsCellAlive(int adjacentCount, bool isAlive)
{
    if (isAlive)
        return liveRule.Contains(adjacentCount);
    else
        return deadRule.Contains(adjacentCount);
}

«Содержит» медленнее, чем цикл foreach, поэтому это может вызвать проблемы с производительностью.Не волнуйтесь об этом сейчас;Вы даже не получили код правильный .Напишите код так, чтобы он был , очевидно, правильный , а затем используйте профилировщик, чтобы найти медленное место, если оно недостаточно быстрое.

Помните: сделайте это правильно, затем проясните это, затем сделайте это быстро.

1 голос
/ 25 января 2012

Ну, вы всегда можете использовать инструкцию " break " для завершения цикла.Сделайте что-то вроде:

bool CalculateNewState(int adjacent, bool currentState)
{
    if(currentState)
    {
        return IsStateMatch(adjacent, liveRule);
    }
    else
    {
        return IsStateMatch(adjacent, becomeAliveRule);
    }
}

bool IsStateMatch(int adjacent, int[] rules)
{
    bool finalState = false;

    if(rules != null)
    {
        for(int i = 0; i < rules.length; i++)
        {
            if(adjacent == rules[i])
            {
                finalState = true;
                break;
            }
        }
    }

    return finalState;
}

Я немного разбил методы, просто для удобства чтения, но я думаю, что это основная идея.Теперь я согласен с другими авторами о том, что может происходить.Если ваш цикл продолжается после оператора break / return, то, скорее всего, в другом месте есть ошибочный код, неправильно вызывающий метод.

1 голос
/ 25 января 2012

Ваши операторы return немедленно выйдут из метода CalculateNewState. Если вы обнаружите, что итерация продолжается, либо вы не нажимаете операторы return (adjacent == n никогда не выполняется), либо, возможно, CalculateNewState вызывается повторно из других мест вашего кода.

Вы, вероятно, можете переписать его гораздо проще, например:

if (currentState)
    return liveRule.Contains(adjacent);
return becomeAliveRule.Contains(adjacent);
0 голосов
/ 25 января 2012

Можете ли вы использовать цикл for вместо foreach с дополнительной переменной?

bool CalculateNewState(int adjacent, bool currentState)
{
    if (currentState == true)
    {
        bool match = false;
        for(int n = 0; n < liveRule.length && !match; n++)
        {
            if (adjacent != n)
            {
                match = true;
            }               
        }
        return match;
    }
    else
    {
        bool match = false;
        for(int n = 0; n < becomeAliveRule.length && !match; n++)
        {
            if (adjacent != n)
            {
                match = true;
            }               
        }
        return match;
    }
}
0 голосов
/ 25 января 2012

Похоже, что ваш тест на равенство является виновником ... разве вы не должны проверять adjacent == n вместо adjacent != n? Таким образом, он вернет true для совпадений и вернет false только при отсутствии совпадений.

Итератор НЕ продолжит работу после возврата из цикла.

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