喵宅苑 MewoGarden × 技术宅社区II | Z站 Z Station 棒棒哒纯文字二次元技术社区

正文

[Python] 解迷宫的程序

作者:轻舟过
顺便博客求关注:http://bimania.org/

在stackoverflow上看到一个有趣的问题:给定一张图片,如何表示并解决图片上的迷宫。

自己也写了一下,稍微用qt做了个界面。其实并没有用到什么很难的算法,只是一个简单的BFS。

当然迷宫上会有一个入口和出口,首先需要自己对图片做下预处理,把入口和出口封住,否则最后算出的最短路径将是从迷宫外面的空白区域绕过去的。另外程序运行之后还要用鼠标确定起点和终点,剩下就是从起点开始进行BFS,直到到达终点。另外需要注意的是边界和路径的区分,这个是通过计算像素点的灰度值,将灰度值超过一定限度的作为边界,低于的作为可以通过的区域。

[mw_shl_code=python,true] import sys import os from PyQt4.QtGui import * from PyQt4.QtCore import * from collections import deque class State: def __init__(self, x, y, pre=None): self.x = x self.y = y self.pre = pre def __str__(self): return "(%d, %d)" % (self.x, self.y) class MazeLabel(QLabel): def __init__(self, pixmap, path, parent=None): QLabel.__init__(self, parent) self.setPixmap(pixmap) self.path = path self.p1 = None self.p2 = None def isWhite(self, c): if abs(qGray(c) - qGray(qRgb(255, 255, 255))) < 30: return True else: return False def solve(self, img): q = deque() q.append(State(self.p1.x(), self.p1.y())) img.setPixel(self.p1.x(), self.p1.y(), qRgb(0, 0, 0)) print len(q) #cnt = 100 while len(q) > 0: s = q.popleft() #print s if s.x == self.p2.x() and s.y == self.p2.y(): return s for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]: nx, ny = s.x + dx, s.y + dy if nx >= 0 and nx < img.width() and ny >= 0 and ny < img.height() and self.isWhite(img.pixel(nx, ny)): q.append(State(nx, ny, s)) img.setPixel(nx, ny, qRgb(0, 0, 0)) #cnt = cnt - 1 print "no solution!" def mousePressEvent(self, ev): if self.p1 == None: self.p1 = ev.pos() else: self.p2 = ev.pos() print self.p1 print self.p2 image = self.pixmap().toImage() sol = self.solve(image) image = self.pixmap().toImage() it = sol while it != None: image.setPixel(it.x, it.y, qRgb(255, 0, 0)) it = it.pre self.setPixmap(QPixmap.fromImage(image)) self.update() fileName, fileExt = os.path.splitext(self.path) newFileName = fileName + "_solved" + fileExt self.pixmap().save(newFileName) if __name__ == "__main__": app = QApplication(sys.argv) scrollArea = QScrollArea() pixmap = QPixmap(sys.argv[1]) imageLabel = MazeLabel(pixmap, sys.argv[1]) scrollArea.setWidget(imageLabel) scrollArea.show() app.exec_() [/mw_shl_code]

下面是一个迷宫的例子,非常复杂,入口在左上角,出口在右下角

不过用程序,很容易能得出啊答案,下面是程序给出的解

回复

以为是张模糊的图

作者:jains521
第一眼, 以为是张模糊的图,,, 仔细一看才发现是...额..疯狂了..
查看回复

好壮观的迷宫

作者:轻舟过
zhangjiqimao 发表于 2013-1-3 23:10 好壮观的迷宫
为了测试程序特意选用了复杂的迷宫
查看回复

好壮观的迷宫

作者:zhangjiqimao
好壮观的迷宫
查看回复

pblh123回复给帖子:6659109

作者:pblh123
给力。强人
查看回复

不过话说既然可以封掉入口和出口

作者:轻舟过
foodszhu 发表于 2012-11-11 01:29 不会pyqt。。。不过话说既然可以封掉入口和出口,为什么不可以将其定位出来呢。。难道是没有最外面的一层边 ...
pyqt其实我也不会,是临时去查了下的 其实封掉入口和出口是自己之前用windows自带的画图板编辑的
查看回复

不过话说既然可以封掉入口和出口

作者:foodszhu
不会pyqt。。。不过话说既然可以封掉入口和出口,为什么不可以将其定位出来呢。。难道是没有最外面的一层边缘么
查看回复

就是根据灰度值来判断

作者:南面之君
轻舟过 发表于 2012-11-10 23:39 就是根据灰度值来判断 最开始的时候是用纯白来作为可通行区域的,不过后来发现很多图看上去白色的地方其 ...
是啊~ 我刚才还把例图用matlab转换成了灰度图看了一下
查看回复

南面之君

作者:轻舟过
南面之君 发表于 2012-11-10 23:23 紧跟版主脚步,刚才我还对着程序和图图研究怎么识别边界和可通,然后,觉得又有点懒得看,再然后一抬头.. ...
就是根据灰度值来判断 最开始的时候是用纯白来作为可通行区域的,不过后来发现很多图看上去白色的地方其实不是白色
查看回复
上一页
下一页
0%
站点地图友情链接:
喵宅苑
喵空间社区程序
喵宅苑 静态版
宅喵RPG地图编辑器
络合兔
Lanzainc
技术宅
小五四博客
莉可POI
Mithril.js
枫の主题社
Project1
午后少年
机智库
七濑胡桃
xiuno
幻想の日常
魂研社
Nothentai
0xffff
欲望之花
泽泽社长
淀粉月刊
HAYOU