作为人工智能课程的一部分,我正在研究游戏 我发现了解决机器人(滚石) 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);
但是,数组是 空,所以我们得到了一个分割错误Here are the code in question
我已将代码移植到GitHub。您可以检查它here
注意:我也曾尝试在Ubuntu 16.04.06 X86和Visual Studio 2019中运行此代码,但是没有运气。
答案 0 :(得分:2)
在我的测试中,第一次通过此代码(当index=0
时),我们发现t->Array[0]
包含一些巨大的数字。因此,index
被发送到一个巨大的对象,并且在下一次循环中,它超过了t->Array
的大小,您便崩溃了。
t->Array
的内容最初是从函数LoadTree
中的文件DL.1
加载的:
t->Next[0] = fread(t->Array,sizeof(DLENTRY),
t->CurrentLength,fp);
很不幸,作者选择了以机器的本机二进制格式存储此数据,这可能与您当前的机器不一致。
现在DLENTRY
是int[3]
的typedef。快速浏览DL.1
,表明它似乎是32位大端整数。如果您是在x86上运行此程序,则您的int
是32位little-endian。因此,读入数据后,您需要对这些数据进行字节交换(例如,通过用ntohl()
对其进行循环。)
如果这表明其余代码具有可移植性,那么我认为将其移植到当前计算机上可能是一个艰巨的项目。