Skip to content

Commit

Permalink
将所有数据记录在一张地图中。
Browse files Browse the repository at this point in the history
  • Loading branch information
zhai_pro committed Sep 22, 2018
1 parent d4e770f commit 363efbb
Showing 1 changed file with 31 additions and 40 deletions.
71 changes: 31 additions & 40 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ def __init__(self, level, col=10):
:param col: 地图的宽度,由于设定为10,默认为10
'''
self.level = level
# start和end 表示开始的状态,结束的状态
# start只有0, 1, 2, 4。
# end只有0, 3,0表示其他。
self.start = ''
self.end = ''
self.col = col
# paths记录最短路径(可能有多条)
self.paths = []
Expand All @@ -42,25 +37,17 @@ def __init__(self, level, col=10):

def pre(self):
'''
1.获得start状态和end状态
2.获得人的位置ppos
获得人的起始位置px,py
'''
# 现在只需要把start状态中的2位置移动到end状态中的3位置即满足条件
start_dict = {'3': '0', '5': '2', '6': '4'}
end_dict = {'3': '3', '5': '3', '6': '3'}
for x in self.level:
self.start += start_dict.get(x, x)
self.end += end_dict.get(x, '0')
assert '2' in self.start, '关卡中没有箱子?'
# ppos表示4(人)的位置
self.ppos = self.start.find('4')
assert self.ppos != -1, '关卡中没有人?'
for pos, enum in enumerate(self.level):
if enum in ('4', '6'):
self.ppos = pos

def is_ok(self, start):
def is_ok(self, line):
'''
如果start中的2(盒子)都移动到end的3(终点)即为游戏结束
如果 line 状态中的已经没有2(箱子),则说明箱子已经被推到终点。
'''
return ('2', '0') not in zip(start, self.end)
return '2' not in line

def BFS(self): # NOQA
'''
Expand All @@ -69,18 +56,18 @@ def BFS(self): # NOQA
# 4个方向,小写代表只是人移动,大写表示人推着箱子一起移动
dirs = [[-self.col, 'u', 'U'], [self.col, 'd', 'D'], [1, 'r', 'R'], [-1, 'l', 'L']]
# 把开始的状态进入队列(list模拟),状态包括字符串表示的当前状态、当前的路径、当前人的位置
states = [[self.start, '', self.ppos]]
states = [[self.level, '', self.ppos]]
# 访问集合,访问过的状态(字符串)不再访问
visi = set()
visi.add(self.start)
visi.add(self.level)

s_len = 1000
while states:
start, path, ppos = states.pop(0)
line, path, ppos = states.pop(0)
if len(path) > s_len:
break
# 保存最短路径到paths中
if self.is_ok(start):
if self.is_ok(line):
if self.len == -1 or len(path) == self.len:
self.paths.append(path)
self.len = len(path)
Expand All @@ -91,23 +78,27 @@ def BFS(self): # NOQA
cpos = ppos + dir[0]
# 4挨着挨着的状态的位置
npos = cpos + dir[0]
if start[cpos] == '2' and start[npos] == '0':
# 人和箱子一起推动,start中连着的状态为4 2 0。推完之后start变为0 4 2
if line[cpos] in ('2', '5') and line[npos] in ('0', '3'):
# python中字符串不可更改,于是把字符串变成list更改状态后再转换为字符串
digits = list(start)
digits[ppos], digits[cpos], digits[npos] = '0', '4', '2'
new_start = ''.join(digits)
if new_start not in visi:
visi.add(new_start)
states.append([new_start, path + dir[2], cpos])
elif start[cpos] == '0':
# 人动箱子不动,start中连着的状态为4 0。
digits = list(start)
digits[ppos], digits[cpos] = '0', '4'
new_start = ''.join(digits)
if new_start not in visi:
visi.add(new_start)
states.append([new_start, path + dir[1], cpos])
digits = list(line)
a = {'0': '2', '2': '4', '3': '5', '4': '0', '5': '6', '6': '3'}
digits[ppos] = a[digits[ppos]]
digits[cpos] = a[digits[cpos]]
digits[npos] = a[digits[npos]]
new_line = ''.join(digits)
if new_line not in visi:
visi.add(new_line)
states.append([new_line, path + dir[2], cpos])
elif line[cpos] in ('0', '3'):
# 人动箱子不动,line中连着的状态为4 0。
a = {'0': '4', '3': '6', '4': '0', '6': '3'}
digits = list(line)
digits[ppos] = a[digits[ppos]]
digits[cpos] = a[digits[cpos]]
new_line = ''.join(digits)
if new_line not in visi:
visi.add(new_line)
states.append([new_line, path + dir[1], cpos])

def gen_shortest_paths(self):
self.pre()
Expand Down

0 comments on commit 363efbb

Please sign in to comment.