与二进制数组抗争:python
我目前正在为一款游戏开发一个发布的机器人,希望能学到更多关于编程的知识。不幸的是,当我进入二进制数组的主题时,我添加的一个新命令一开始看起来很简单,但却变得极其困难。基本上,我接受了一个已经发出的命令,在该命令中,您将一个项目放置在两个位置,以便定义要恢复的区域。我对该命令的编辑是,它允许完全恢复整个地图,而无需放置任何项目来定义地图 在执行恢复命令之前,将执行备份命令,其中二进制数组由整个映射组成,然后存储在文件中。为了恢复整个地图,新命令仍然需要处理两点的坐标。一个位于地图的下角(0,0,0),然后另一个位于地图的上对侧的角,这将始终根据您想要的服务器而有所不同。我解决这个问题的理由是简单地检索每个坐标的二进制数组的长度。不幸的是,我在尝试这样做时运气不佳,我真的不知道如何找到二进制数组的维数。显示了阵列的打包和解包,以及我无法解决的代码部分 一件奇怪的事情是,如果我像if语句那样手动输入带有一个服务器ip地址的数字,则bot可以完美地工作。只是,任何为任何一个地图而不是一个地图编写代码的努力都是徒劳的与二进制数组抗争:python,python,arrays,binary,Python,Arrays,Binary,我目前正在为一款游戏开发一个发布的机器人,希望能学到更多关于编程的知识。不幸的是,当我进入二进制数组的主题时,我添加的一个新命令一开始看起来很简单,但却变得极其困难。基本上,我接受了一个已经发出的命令,在该命令中,您将一个项目放置在两个位置,以便定义要恢复的区域。我对该命令的编辑是,它允许完全恢复整个地图,而无需放置任何项目来定义地图 在执行恢复命令之前,将执行备份命令,其中二进制数组由整个映射组成,然后存储在文件中。为了恢复整个地图,新命令仍然需要处理两点的坐标。一个位于地图的下角(0,0,0
enter code here
def onBackup(self,user,filename):
fn = bakFolder+filename+".backup"
try:
f = open(fn,"r")
self.bot.sendMessage("A backup by that name already exists.")
f.close()
return
except IOError:
try:
f = open(fn,"wb")
f.write(struct.pack("!3i",self.bot.level_x,self.bot.level_y,self.bot.level_z))
self.bot.block_array.tofile(f)
self.bot.sendMessage("Backup saved to file %s.backup"%filename)
print "Backup save to %s.backup"%filename
return
except IOError:
self.bot.sendMessage("Error opening %s.backup"%filename, false)
print "Backup: Error opening file"
return
def restoremap(self):
fn = bakFolder+self.restore_filename+".backup"
try:
f = open(fn,"rb")
header_x, header_y, header_z = struct.unpack('!3i',f.read(12))
backup_array = array.array('B')
backup_array.fromfile(f,header_x*header_y*header_z)
x1,y1,z1 = (0,0,0)
if server == "204.232.197.228":
x2,y2,z2 = (64,1020,64) #special server that already has coordinates
else:
x2,y2,z2 = ??? rest of servers, coordinates derived from the binary array
if x1 > x2 : x1, x2 = x2, x1
if y1 > y2 : y1, y2 = y2, y1
if z1 > z2 : z1, z2 = z2, z1
tiles_to_deglass = []
tiles_to_build = []
while x1 <= x2:
y = y1
while y <= y2:
z = z1
while z <= z2:
offset = self.bot.calculateOffset(x1,y,z)
current_tile = int(self.bot.block_array[offset])
backup_tile = int(backup_array[offset])
if not ( current_tile == backup_tile):
if (current_tile == 0) and (backup_tile in self.valid_blocks):
tiles_to_build.append((backup_tile,x1,y,z))
elif (current_tile >= 8) and (current_tile <= 11) and (backup_tile == 0):
## This deals with water & lava in what used to be empty spaces
## first we'll glass it all, and then deglass later!
self.blocks.append((20,x1,y,z))
tiles_to_deglass.append((0,x1,y,z))
elif backup_tile == 7:##use stone
tiles_to_build.append((0,x1,y,z))
tiles_to_build.append((1,x1,y,z))
elif backup_tile in self.valid_blocks:
## This is the fall through... We'll try to erase
## the current tile and then restore it to the other state
tiles_to_build.append((0,x1,y,z))
tiles_to_build.append((backup_tile,x1,y,z))
elif (backup_tile == 0) and not (current_tile == 0):
tiles_to_build.append((0,x1,y,z))
z+=1
y += 1
x1 +=1
self.DrawBlocks()
self.blocks += tiles_to_build
self.DrawBlocks()
self.blocks += tiles_to_deglass
self.DrawBlocks()
self.bot.sendMessage("Restoring...",ignorable=True)
##self.bot.action_queue.append(SayAction(self.bot,"Done restoring."))
self.onReset(silent=True)
except IOError:
self.bot.sendMessage("Error while restoring (couldn't read file).")
在此处输入代码
def onBackup(自我、用户、文件名):
fn=bakFolder+filename+“.backup”
尝试:
f=打开(fn,“r”)
self.bot.sendMessage(“已存在同名备份”)
f、 关闭()
返回
除IOError外:
尝试:
f=开放(fn,“wb”)
f、 写入(结构包(“!3i”,self.bot.level_x,self.bot.level_y,self.bot.level_z))
self.bot.block_array.tofile(f)
self.bot.sendMessage(“备份已保存到文件%s.Backup”%filename)
打印“备份保存到%s.Backup”%filename
返回
除IOError外:
self.bot.sendMessage(“打开%s.backup”%filename时出错,false)
打印“备份:打开文件时出错”
返回
def恢复映射(自):
fn=bakFolder+self.restore\u filename+“.backup”
尝试:
f=打开(fn,“rb”)
标题x,标题y,标题z=struct.unpack(“!3i',f.read(12))
backup\u array=array.array('B')
backup_array.fromfile(f,header_x*header_y*header_z)
x1,y1,z1=(0,0,0)
如果服务器==“204.232.197.228”:
x2,y2,z2=(641020,64)#已经有坐标的特殊服务器
其他:
x2,y2,z2=???其余的服务器,从二进制数组派生的坐标
如果x1>x2:x1,x2=x2,x1
如果y1>y2:y1,y2=y2,y1
如果z1>z2:z1,z2=z2,z1
瓷砖到玻璃瓷砖=[]
平铺至平铺=[]
x1考虑长度1024
;这可以转化为(x,y,z):
即使数组的长度为1001
,您也不会得到非常友好的答案:
7 11 13
11 7 13
7 13 11
11 13 7
13 11 7
13 7 11
因此,保存的文件必须包含每个特定地图的(x、y、z)坐标
看起来像是onBackup()
例程将机器人的坐标保存在前三个整数位置(每个位置四个字节)。您可以通过将机器人移动到地图的最远处,然后保存坐标来扩展此程序。或者,您可以查看服务器是否能够以某种方式报告地图的范围,并捕获信息
但是我不认为你可以从给定的输入数组中猜出维数。似乎你使用x2、y2、z2的唯一地方就是在这些循环中设置x1、y和z的限制:
while x1 <= x2:
y = y1
while y <= y2:
z = z1
while z <= z2:
offset = self.bot.calculateOffset(x1,y,z)
current_tile = int(self.bot.block_array[offset])
...
z+=1
y += 1
x1 +=1
在这种情况下,添加try
和except
将Exception
更改为索引器
x2、y2、z2不应该与header_x、header_y、header_z相同吗?实际上,答案可能是header_x、y、z的长度
while x1 <= x2:
y = y1
while y <= y2:
z = z1
while z <= z2:
offset = self.bot.calculateOffset(x1,y,z)
current_tile = int(self.bot.block_array[offset])
...
z+=1
y += 1
x1 +=1
x2=y2=z2=None
while x2 is None or x1<=x2:
y = y1
while y2 is None or y<=y2:
z = z1
while z2 is None or z<=z2:
try:
offset = self.bot.calculateOffset(x1,y,z)
current_tile = int(self.bot.block_array[offset])
except Exception: #<-- Change to most specific exception possible
if z2 is None:
z2=z-1
elif y2 is None:
y2=y-1
elif x2 is None:
x2=x1-1
break
...
z+=1
y += 1
x1 +=1
IndexError: x,y,z out of bounds