Дихотомия, чтобы найти неизвестный номер с успехом / неудачей вместо более или менее - PullRequest
0 голосов
/ 27 апреля 2020

Я пытаюсь перевести программу из Python в LSL (сценарий SecondLife), чтобы найти число, к которому у меня нет доступа из функций. Это число - мой баланс липы (деньги в игре). Единственный способ определить эту сумму по моему сценарию - это перевести мне деньги и проверить, был ли процесс успешным или нет.

Для этого я нашел скрипт python с дихотомией, который отлично работает:

from random import randint

n = 100000000 # Maximum amount possible
amountToFind = randint(1,n)
a = 1
b = n
nbAnswers = 0

while b-a >=0: 
    answer= (a+b)//2
    nbAnswers += 1
    if answer== amountToFind:
        print("The correct answer is:", answer)
        break 
    elif answer> amountToFind:
        b = answer- 1
    else:
        a = answer+ 1

print("The number of steps to get the correct amount was :", nbAnswers)
print(amountToFind)

Проблема в том, что я не могу сравнить answer с числом i ' ищу У меня только неудача и успех:

llCheckLindenBalance()
{
        rep = (a+b)/2;
        transactionId = llTransferLindenDollars(owner, rep);
}

touch_start(integer total_number)
{
    llCheckLindenBalance();
}

transaction_result(key id, integer success, string data)
{
    if(id != transactionId)
        return;



    if(success) // rep < amount or rep == amount
    {

        a = rep+1;
        llOwnerSay("Last amount " +(string)rep);
        llCheckLindenBalance();

    }
    else // FAIL - rep < amount
    {
       b = rep-1;
       llCheckLindenBalance();
    }
}

Этот скрипт работает до сих пор, но он никогда не остановится, поскольку никогда не знает, когда остановиться. Я думал о сравнении a и b, но расстояние между ними также является переменным (от 0 до 10). Так что я застрял в этом. Я думал о тестировании answer+1, и если он провалился, это означает, что это самое большое количество, но я не могу сейчас где его протестировать.

Ребята, у вас есть идеи?

1 Ответ

1 голос
/ 27 апреля 2020

Делать так не быстрее, чем считать с 0 и проверять все возможные значения; каждая итерация будет уменьшать границы только на одну. Что еще более важно, llTransferLindenDollars ограничен скоростью до 1 в секунду, поэтому вы скорее достигнете предела, чем в любом случае найдете какой-либо полезный результат. Предполагая, что у кого-то есть L $ 20, если вы использовали сценарий Python и начинали с L $ 100 000 000, выполнение этой процедуры заняло бы более трех лет.

Итак, поскольку большинство пользователей SL не имеют L $ 50 000 000, вероятно, было бы быстрее просто считать с нуля и продолжать проверять до тех пор, пока не будет получен сбой:

integer amount;
key trans_id;

default
{
    touch_start(integer total_number)
    {
        amount = 0;
        trans_id = llTransferLindenDollars(llGetOwner(), amount);
    }
    transaction_result(key id, integer success, string data)
    {
        if (id != trans_id) return;
        if (success)
        {
            llOwnerSay("Last amount: " + (string)amount);
            llSleep(1.0); // avoid rate limiting
            trans_id = llTransferLindenDollars(llGetOwner(), ++amount);
        }
        else if (data == "LINDENDOLLAR_INSUFFICIENTFUNDS")
        { // this is the error we care about
            llOwnerSay("L$ balance: " + (string)(amount - 1));
        }
        else
        { // some other error
            llOwnerSay("Error: " + data);
            llSleep(10.0); // wait and retry
            trans_id = llTransferLindenDollars(llGetOwner(), amount);
        }
    }
}

Это все еще невероятно медленно и практически бесполезно для тех, у кого более нескольких L $, частично для безопасности причины - скрипты, знающие баланс аккаунта, означают, что он может мгновенно опустошить весь аккаунт без ошибки. Просто не существует быстрого способа определить баланс L $ в учетной записи, если только учетная запись не является ботом, и любой используемый вами бот-сервис имеет функцию API, которая может это сделать.

Кроме того, к вашему сведению, плохая практика предшествовать пользователю - определенные функции с "ll"; Для удобства читаемости функции ll должны быть только встроенными.

...