用 Python 写 lurd2xsb 程序

作者:杨超

本文地址:http://sokoban.ws/blog/?p=288

上一篇博文用Haskell写了lurd2xsb程序。请参阅上篇博文了解推箱子的lurd2xsb程序是什么。这回用Python语言来再写一次。Python诞生于1991年,支持包括函数式编程在内的多种编程范式,但偏重于命令式和面向对象的编程。

以下是程序的全部代码。存为lurd2xsb.py文件后,用python lurd2xsb.py命令运行。或者用cat [lurd file] | python lurd2xsb.py命令直接从文件中读入lurd答案。

class Sokoban:
	def __init__(self):
		self.level = "####@####"
		self.w=3
		self.h=3
		self.man=4
	def __str__(self):
		temp = "";
		for i in range(0,self.h):
			temp += self.level[i*self.w : (i+1)*self.w] + "\n"
		temp += "size: " + str(self.w) + "x" + str(self.h)
		temp += "\nman: " + str(self.man)
		return temp
	def add_row(self,l):
		if l==1:
			for i in range(0,self.w):
				self.level = self.level + "#"
		elif l==0:
			for i in range(0,self.w):
				self.level = "#" + self.level
			self.man += self.w
		self.h+=1
	def add_column(self,l):
		if l==1:
			self.man += (self.man / self.w)
			for i in range(0,self.h):
				self.level = self.level[0:self.w * (self.h  -i)] + "#" + self.level[self.w * (self.h  -i):]
		elif l==0:
			self.man += ( self.man / self.w + 1 )
			for i in range(0,self.h):
				self.level = self.level[0:self.w * (self.h  - 1 - i)] + "#" + self.level[self.w * (self.h  - 1 - i):]
		self.w+=1
	def undo(self,step):
		#prepare
		if step == 'l' or step == 'L':
			d = -1
		elif step == 'r' or step == 'R':
			d = 1
		elif step == 'u' or step == 'U':
			d = -1 * self.w
		elif step == 'd' or step == 'D':
			d = self.w
		else:
			return
		#action
		if self.level[ self.man - d] == '$' or self.level[ self.man - d] == '*':
			exit("invalid input lurd string![0]")
		elif step == 'l' or step == 'u' or step == 'r' or step == 'd': #undo a move
			if self.level[ self.man] == '@':
				floor = ' '
			else:
				floor = '.'
			if self.level[ self.man - d ] == '.':
				pusher = '+'
			else:
				pusher = '@'
			self.level = self.level[0:self.man] + floor + self.level[ self.man +1:]
			self.level = self.level[0:self.man - d ] + pusher + self.level[self.man - d + 1:]
			self.man -= d
		elif step == 'L' or step == 'U' or step == 'R' or step == 'D': #undo a push
			if self.level[ self.man] == '@':
				box = '$'
			else:
				box = '*'
			if self.level[ self.man - d ] == '.':
				pusher = '+'
			else:
				pusher = '@'
			if self.level[ self.man + d ] == '*' or self.level[ self.man + d ] == '#':
				floor = '.'
			elif self.level[ self.man + d ] == '$':
				floor = ' '
			else:
				exit("invalid input lurd string![1]")
			self.level = self.level[0:self.man] + box + self.level[ self.man +1:]
			self.level = self.level[0:self.man - d ] + pusher + self.level[self.man - d + 1:]
			self.level = self.level[0:self.man + d ] + floor + self.level[self.man + d + 1:]
			self.man -= d
		#post action
		if self.man % self.w == self.w -1:
			self.add_column(1)
		elif self.man % self.w ==0:
			self.add_column(0)
		elif self.man < self.w:
 			self.add_row(0)
 		elif self.man >= (self.h - 1 )* self.w:
			self.add_row(1)
		#post action 2
		if '.' in self.level[0:self.w]:
			self.add_row(0)
		elif '.' in self.level[(self.h-1)*self.w : self.h*self.w]:
			self.add_row(1)
		else:
			for i in range(0,self.h):
				if self.level[i*self.w]=='.':
					self.add_column(0)
					break
				elif self.level[i*self.w + self.w -1]=='.':
					self.add_column(1)
					break

print "Python lurd2xsb"
print "Paste in a lurd solution in one line and press enter."
lurd = raw_input()[::-1]
skb = Sokoban()
for step in lurd:
	skb.undo(step)
print skb
此条目发表在 推箱子, 编程 分类目录。将固定链接加入收藏夹。