RU

бесконечная вложенная рекурсия в QSP

v.v.b. #897 19.08.2014 08:04 12 comments 12559 views

при портировании очередного проекта с QSP на INSTEAD столкнулся с тем, что в QSP допустимы конструкции, когда функция А вызывает функцию Б, которая, в свою очередь, вызывает функцию А.
каким образом QSP относится к бесконечной вложенной рекурсии?

Edited at 19.08.2014 08:04 (11 years ago)

v.v.b.,
а какого поведения ты ожидаешь?

Nex:

v.v.b.,
а какого поведения ты ожидаешь?

отвечать вопросом на вопрос – это и есть случай вызова той самой бесконечной вложенной рекурсии.
потому отвечу так. я не ожидаю никакого. я спрашиваю у специалистов какое поведение сейчас в движке. и спрашиваю ЧТО происходит при подобном случае.

Будет вылет плеера.

Ajenta:

Будет вылет плеера.

странно. но игра с этим кодом прекрасно играет. речь идёт о “Город Туманов”

Aleks Versus Moderator 19.08.2014 11:25 (11 years ago)

Явная рекурсия типа goto $curloc на текущей локации (равно как и случай, описанный выше) в классике вызывает повисание плеера и вылет. Если добавить команду задержки типа wait 500, и что-нибудь типа pl ‘Сообщение’, то вы увидите, что плеер работает нормально. Можно сделать вложенную рекурсию, но мне не видится, как при этом игрок сможет взаимодействовать с игрой.

Город туманов под аеру, вероятно там (в аере) предусмотрен какой-то механизм на случай рекурсии. Классик же стабильно вылетает.

фрагмент непонятного мне кода:

Spoiler
Location: "_check_cuper"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Location's description:

    ! $args[0] - figure name

    if $args[0] = 'circle':
        result = cuper_circle
        if func('_check_gold', 'squre') = 1:
            result = 1
        end
    elseif $args[0] = 'triangle':
        result = (cuper_triangle - 1) * -1
        if func('_check_silber', 'rectangle') = 1 or func('_check_silber', 'triangle') = 1:
            result = 0
        end
    elseif $args[0] = 'square':
        result = (cuper_square - 1) * -1
        if func('_check_silber', 'triangle') = 1 or (func('_check_gold', 'triangle') = 1 and gold_triangle = 0):
            result = 0
        end
    elseif $args[0] = 'rectangle':
        result = (cuper_rectangle - 1) * -1
        if func('_check_silber', 'triangle') = 1 or (func('_check_gold', 'triangle') = 1 and gold_triangle = 1):
            result = 0
        end
    end

------------ End of location: "_check_cuper" ------------

Location: "_check_gold"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Location's description:

    ! $args[0] - figure name


    if $args[0] = 'circle':
        result = (gold_circle - 1) * -1
        if func('_check_gold', 'squre') = 1 or func('_check_cuper', 'squre') = 1:
            result = 0
        end
    elseif $args[0] = 'triangle':
        result = 1
        if func('_check_cuper', 'squre') = 1:
            result = 0
        end
    elseif $args[0] = 'square':
        result = (gold_square - 1) * -1
        if func('_check_silber', 'rectangle') = 1 or func('_check_silber', 'triangle') = 1 or (func('_check_gold', 'triangle') = 1 and gold_triangle = 0) or func('_check_cuper', 'squre') = 1:
            result = 0
        end
    elseif $args[0] = 'rectangle':
        result = 0
    end

------------ End of location: "_check_gold" ------------

непонятно:
func(’_check_cuper’, ‘squre’) включает вызов func(’_check_gold’, ‘triangle’)
func(’_check_gold’, ‘triangle’) включает вызов func(’_check_cuper’, ‘squre’)

поясните, плиз

Aleks Versus Moderator 19.08.2014 11:36 (11 years ago)

а почему squre, а не square, как в условиях. Так в игре сделано?

Aleks Versus:

а почему squre, а не square, как в условиях. Так в игре сделано?

я скопировал из кода игры
получается, что этот кусок кода из-за опечатки не вызывается, и потому не возникает рекурсии?

Aleks Versus Moderator 19.08.2014 11:46 (11 years ago)

v.v.b.,
тогда тут два варианта, но надо разбираться, и лучше спросить у автора. Первый вариант: ошибка в коде игры, которая вызывает прерывание рекурсии, но тогда игра не будет работать. Второй вариант: автор изначально предусмотрел, как прервать рекурсию. Это не отменяет ошибки в коде, но тогда опасаться нечего и можно смело исправлять squre на square.
Нужно исправить, запустить и проверить. Или разрисовать по блокам, кто, что вызывает, и где вызовы прекращаются.

Правильно сделанная рекурсия не будет бесконечной. Даже в случае “из A вызывается B, из B вызывается A”. Даже в случае “из A вызывается A”.

Бесконечная рекурсия приведёт либо к глючащей игре, либо к “зависанию”, либо к вылету плеера. Накосячить можно разными способами.

автор написал, что ошибся в коде. текущая версия на qsp, соответственно, тоже не совсем корректная. потому по уму надо думать как иначе реалзивать всё что автор придумал в игре.
вопрос закрыт. всем спасибо

Log in or Register to post comments.