我想写一个Python函数,它返回与游戏NetHack中相同的月相值。这在hacklib.c中找到。如何将这个NetHack函数移植到Python?
我试图简单地从NetHack代码复制相应的功能,但我不相信我会得到正确的结果。
我写的功能是phase_of_the_moon()
。
函数position()
和phase()
,我在网上找到了,我用它们来表示我的函数成功。它们非常准确,结果与nethack.alt.org服务器大致相同(请参阅http://alt.org/nethack/moon/pom.txt)。然而,我之后是原始NetHack功能的完全复制,idiosyncrasies完好无损。
我期待我的功能和'控制'功能至少给出相同的月相,但目前他们没有,我不知道为什么!
这里是NetHack代码:
/*
* 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);
}
这里是getlt()
功能(也hacklib.c):
static struct tm *
getlt()
{
time_t date;
#if defined(BSD) && !defined(POSIX_TYPES)
(void) time((long *)(&date));
#else
(void) time(&date);
#endif
#if (defined(ULTRIX) && !(defined(ULTRIX_PROTO) || defined(NHSTDC))) || (defined(BSD) && !defined(POSIX_TYPES))
return(localtime((long *)(&date)));
#else
return(localtime(&date));
#endif
}
这里是我的Python代码:
from datetime import date
def phase_of_the_moon():
lt = date.today()
diy = (lt - date(lt.year, 1, 1)).days
goldn = ((lt.year - 1900) % 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)
import math, decimal, datetime
dec = decimal.Decimal
def position(now=None):
if now is None:
now = datetime.datetime.now()
diff = now - datetime.datetime(2001, 1, 1)
days = dec(diff.days) + (dec(diff.seconds)/dec(86400))
lunations = dec("0.20439731") + (days * dec("0.03386319269"))
return lunations % dec(1)
def phase(pos):
index = (pos * dec(8)) + dec("0.5")
index = math.floor(index)
return {
0: "New Moon",
1: "Waxing Crescent",
2: "First Quarter",
3: "Waxing Gibbous",
4: "Full Moon",
5: "Waning Gibbous",
6: "Last Quarter",
7: "Waning Crescent"
}[int(index) & 7]
def phase2(pos):
return {
0: "New Moon",
1: "Waxing Crescent",
2: "First Quarter",
3: "Waxing Gibbous",
4: "Full Moon",
5: "Waning Gibbous",
6: "Last Quarter",
7: "Waning Crescent"
}[int(pos)]
def main():
## Correct output
pos = position()
phasename = phase(pos)
roundedpos = round(float(pos), 3)
print "%s (%s)" % (phasename, roundedpos)
## My output
print "%s (%s)" % (phase2(phase_of_the_moon()), phase_of_the_moon())
if __name__=="__main__":
main()
啊nethack代码...现在,这是一些复杂的代码。 – Craig 2009-06-02 23:04:47
我知道,但我当然可以处理一个teensy weensy甲虫功能! – nakedfanatic 2009-06-02 23:12:08
首先,定义'epact'的行以分号结尾。 – Zifre 2009-06-02 23:30:20