作为人工智能课程的一部分,我正在研究游戏解决机器人(滚石)我找到了here。此代码是在1999年编写的(可能在HP UNIX工作站上)。我似乎无法在我的平台上运行它(Ubuntu Linux 18.10 x64)。我遇到了分段错误(SIGSEGV,SIGBUS等)
该代码使用自定义编写的数据结构,如位串,由指针算法和引用调用使用。例如,在一个实例中,我们通过index = t->Array[index][square];
获得某种类型块的索引
我们检查玩家正在移动的状态,空块或墙壁。
do {
p = pos + xofs*t->Sup[i].x_ofs + yofs*t->Sup[i].y_ofs;
/* test if goal is in the pattern, if yes, no deadlock or
* test the mirror pattern to see if that finds a deadlock */
/* check for pattern overflow first */
if (p<0 || p>XSIZE*YSIZE)
square = WallSquare;
else {
if (maze->Phys[p].goal >= 0) {
goto TEST_MIRROR;
}
if (IsBitSetBS(maze->out,p)) square = WallSquare;
else if (maze->PHYSstone[p]>=0) square = StoneSquare;
else square = BlancSquare;
}
index = t->Array[index][square];
i++;
} while (index>0);
但是,Array是空的,因此我们得到了分段错误。 Here are the code in question
我已将代码移植到GitHub。你可以检查一下here
注意:我也尝试在Ubuntu 16.04.06 X86和Visual Studio 2019中运行此代码,但没有运气。
在我的测试中,第一次通过这段代码(当index=0
)我们发现t->Array[0]
包含一些巨大的数字。所以index
发送到一个巨大的东西,下一次通过循环,它超过t->Array
的大小,你崩溃。
t->Array
的内容最初是从函数DL.1
中的文件LoadTree
加载的:
t->Next[0] = fread(t->Array,sizeof(DLENTRY),
t->CurrentLength,fp);
不幸的是,作者选择将这些数据存储在他们机器的本机二进制格式中,这可能与您当前的机器不一致。
现在DLENTRY
是int[3]
的typedef。快速浏览一下DL.1
表明它似乎是大端32位整数。如果你在x86上运行它,那么你的int
是32位小端。因此,您需要在读取数据后对其进行字节交换(例如,通过使用ntohl()
循环它)。
如果这是其余代码的可移植性的任何指示,那么我认为将其移植到您当前的机器可能是一个重要的项目。