Как портировать эту функцию NetHack на Python?

Другие ответы - «Хорошо», но цикл while кажется более подходящим:

function setAll(array, value) {
  var i = array.length;
  while (i--) {
    array[i] = value;
  }
}

Более креативная версия:

function replaceAll(array, value) {
  var re = new RegExp(value, 'g');
  return new Array(++array.length).toString().replace(/,/g, value).match(re);
}

Может работать не везде. : -)

10
задан halfer 17 April 2017 в 21:08
поделиться

5 ответов

Написанный код в значительной степени не поддается тестированию - и вам необходимо сделать его тестируемым. Итак, вам нужен код C:

int
phase_of_the_moon()     /* 0-7, with 0: new, 4: full */
{
    register struct tm *lt = getlt();
    return testable_potm(lt);
}

static int
testable_potm(const struct tm *lt)
{
    register int epact, diy, goldn;

    diy = lt->tm_yday;
    goldn = (lt->tm_year % 19) + 1;
    epact = (11 * goldn + 18) % 30;
    if ((epact == 25 && goldn > 11) || epact == 24)
        epact++;

    return( (((((diy + epact) * 6) + 11) % 177) / 22) & 7 );
}

Теперь вы можете запускать тесты с несколькими значениями времени. Альтернативный способ сделать это - подделать getlt () .

Затем вам потребуются параллельные изменения в вашем коде Python. Затем вы создаете файл значений time_t , который может быть прочитан как Python, так и C, а затем преобразован в соответствующую структуру (через localtime () на C). Тогда вы сможете увидеть, где дела отклоняются.

Затем вы создаете файл значений time_t , который может быть прочитан как Python, так и C, а затем преобразован в соответствующую структуру (через localtime () на C). Тогда вы сможете увидеть, где дела отклоняются.

Затем вы создаете файл значений time_t , который может быть прочитан как Python, так и C, а затем преобразован в соответствующую структуру (через localtime () на C). Тогда вы сможете увидеть, где дела отклоняются.

5
ответ дан 3 December 2019 в 23:51
поделиться

Редактировать: Оказывается, обе «проблемы», которые я здесь заметил, были основаны на неправильном понимании структуры tm . Я оставлю ответ нетронутым для обсуждения в комментариях, но оставьте ваши голоса для того, кто действительно может быть прав. ; -)


Предостережение: я не очень хорошо знаком с конструкциями времени Си; Я в основном ухожу от полевой документации, поставляемой для strftime .

Я вижу две «ошибки» в вашем порте. Во-первых, я считаю, что tm_year должен быть годом без века, а не годом минус 1900, поэтому goldn должно быть ((lt.year% 100)% 19 ) + 1 . Во-вторых, ваш расчет для diy отсчитывается от нуля, тогда как tm_yday отображается (опять же, из документации), чтобы быть основанным на одном. Однако я не уверен насчет последнего, поскольку исправление только строки goldn дает правильный результат (по крайней мере, на сегодняшний день), тогда как исправление обоих дает неправильный ответ:

>>> def phase_of_the_moon():
    lt = date.today()

    diy = (lt - date(lt.year, 1, 1)).days
    goldn = ((lt.year % 100) % 19) + 1
    epact = (11 * goldn + 18) % 30
    if ((epact == 25 and goldn > 11) or epact == 24):
        epact += 1
    return ( (((((diy + epact) * 6) + 11) % 177) / 22) & 7 )

>>> phase_of_the_moon():
3

Опять же, это в основном догадки. Пожалуйста, будьте добры. : -)

3
ответ дан 3 December 2019 в 23:51
поделиться

Любопытно, что когда я компилирую и запускаю пример nethack, я получаю в качестве ответа «2» («Первая четверть», которая совпадает с вашим портом)

#include <time.h>

static struct tm *
getlt()
{
        time_t date;
        (void) time(&date);
        return(localtime(&date));
}
/*
 * moon period = 29.53058 days ~= 30, year = 365.2422 days
 * days moon phase advances on first day of year compared to preceding year
 *  = 365.2422 - 12*29.53058 ~= 11
 * years in Metonic cycle (time until same phases fall on the same days of
 *  the month) = 18.6 ~= 19
 * moon phase on first day of year (epact) ~= (11*(year%19) + 29) % 30
 *  (29 as initial condition)
 * current phase in days = first day phase + days elapsed in year
 * 6 moons ~= 177 days
 * 177 ~= 8 reported phases * 22
 * + 11/22 for rounding
 */
int
phase_of_the_moon()     /* 0-7, with 0: new, 4: full */
{
    register struct tm *lt = getlt();
    register int epact, diy, goldn;

    diy = lt->tm_yday;
    goldn = (lt->tm_year % 19) + 1;
    epact = (11 * goldn + 18) % 30;
    if ((epact == 25 && goldn > 11) || epact == 24)
        epact++;

    return( (((((diy + epact) * 6) + 11) % 177) / 22) & 7 );
}

int main(int argc, char * argv[]) {
    printf ("phase of the moon %d\n\n", phase_of_the_moon());
}

вывод:

> a.out
phase of the moon 2

Но это не кажется правильным ответом, так как сегодня weatherunderground.com и alt.org сообщает фазу Луны как «Растущая Луна» (также известная как 3).

Я попытался удалить «-1900», но это не помогло тоже не приведет к правильному ответу.

1
ответ дан 3 December 2019 в 23:51
поделиться

Следующий код заимствован из этого сайта , вставьте его здесь для удобства (и в случае, если другой сайт пойдет вниз). Вы можете использовать модуль время , чтобы получить текущее местное время . Смотрите, как я это сделал (вставьте ниже размещенный код для теструна):

import time
tm = time.localtime()
month = tm.tm_mon
day = tm.tm_mday
year = tm.tm_year
date, status, light = moon_phase(month, day, year)
print "moon phase on %s is %s, light = %d%s" % (date, status, light, '%')

Выход:

moon phase on 22Dec2009 is waxing crescent (increasing to full), light = 34%

Лунные вещи - это весело. :)

1
ответ дан 3 December 2019 в 23:51
поделиться

Мне нравится думать, что я кое-что знаю о календарях, так что давайте посмотрим, смогу ли я кое-что прояснить.

Католическая церковь определяет дату Пасхи с точки зрения лунных фаз (вот почему дата скачет из года в год). Поэтому она должна уметь вычислять приблизительную фазу луны, и её алгоритм для этого объясняется здесь.

Я не делал очень детальной проверки, но похоже, что алгоритм NetHack в значительной степени основан на алгоритме Церкви. Похоже, что алгоритм NetHack, как и алгоритм Церкви, обращает внимание только на календарную дату, игнорируя часовые пояса и время суток.

Алгоритм NetHack использует только год и день года. Из изучения кода я могу сказать, что для совместимости с Y2K, tm_year должен быть годом минус 1900.

.
0
ответ дан 3 December 2019 в 23:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: