作者:杨超
本文地址: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