设为首页 收藏本站
查看: 679|回复: 0

[经验分享] 新鲜出炉的连连看连接算法Python版

[复制链接]
发表于 2017-5-6 14:16:57 | 显示全部楼层 |阅读模式
  这段时间老是“不务正业”的搞一些东西玩。之前的贪吃蛇,俄罗斯方块激发了我研究游戏算法的兴趣。经过1个星期的构思,连连看的连接算法终于出炉了。再过一段时间就基于这个算法使用JavaScript推出网页版的连连看。下面是说明及代码。
  功能:为连连看游戏提供连接算法
说明:模块中包含一个Point类,该类是游戏的基本单元“点”,该类包含属性:x,y,value。
其中x,y代表了该点的坐标,value代表该点的特征:0代表没有被填充,1-8代表被填充为游戏图案,9代表被填充为墙壁
模块中还包含一个名为points的Point列表,其中保存着整个游戏界面中的每个点
使用模块的时候应首先调用createPoints方法,初始化游戏界面中每个点,然后可通过points访问到每个点,继而初始化界面
模块中核心的方法是link,通过提供源点和终点,可尝试连接两点,如果可以连接则返回保存路径的path列表,否则返回False
  鸣谢:感谢我的同学asy668(http://hi.baidu.com/myasy)完善这个算法中createPoints,帮助我测试这个算法,并为这个算法写了一个用户交互界面。
  

  • #-*-coding:utf-8-*-
  • """连连看连接算法

  • 为连连看游戏提供连接算法
  • 模块中包含一个Point类,该类是游戏的基本单元“点”,该类包含属性:x,y,value。
  • 其中x,y代表了该点的坐标,value代表该点的特征:0代表没有被填充,1-8代表被填充为游戏图案,9代表被填充为墙壁
  • 模块中还包含一个名为points的Point列表,其中保存着整个游戏界面中的每个点
  • 使用模块的时候应首先调用createPoints方法,初始化游戏界面中每个点,然后可通过points访问到每个点,继而初始化界面
  • 模块中核心的方法是link,通过提供源点和终点,可尝试连接两点,如果可以连接则返回保存路径的path列表,否则返回False
  • """
  • importrandom
  • importtime

  • __author__="http://blog.csdn.net/anhulife"
  • __license__="python"

  • classPoint:
  • """Point类

  • Point类是游戏中基本单元:“点”
  • """
  • def__init__(self,x,y,value):
  • self.x=x
  • self.y=y
  • self.value=value
  • self.directs=None
  • self.changed=0


  • def__createDirect(self,pre,target):
  • """构造点的方向集

  • 每个点在连接的过程中都持有一个方向集,这个方向集中保
  • 存着该点的前进方向选择的优先级优先级:指向目标点的方向级别最
  • 高,在同等级别并且遵循x方向优先于y方向
  • """
  • self.directs=list()
  • stx=target.x-self.x
  • sty=target.y-self.y
  • ifstx>=0:
  • self.directs.append("right")
  • self.directs.append("left")
  • else:
  • self.directs.append("left")
  • self.directs.append("right")
  • ifsty>=0:
  • self.directs.insert(1,"up")
  • self.directs.append("down")
  • else:
  • self.directs.insert(1,"down")
  • self.directs.append("up")
  • ifpre==None:
  • return
  • spx=pre.x-self.x
  • spy=pre.y-self.y
  • ifspx==0:
  • ifspy==1:
  • self.directs.remove("up")
  • else:
  • self.directs.remove("down")
  • else:
  • ifspx==1:
  • self.directs.remove("right")
  • else:
  • self.directs.remove("left")


  • defforward(self,pre,target):
  • """点的前进动作

  • 点的前进即是依次从方向集中取出优先级高的方向,并判
  • 断该方向上的下一个点是否被填充如果没有被填充则说明该方
  • 向可通,并返回该方向。否则试探下一个方向,如果方向集中没
  • 有方向可用了,则返回None
  • """
  • ifself.directs==None:
  • self.__createDirect(pre,target)
  • iflen(self.directs)==0:
  • returnNone
  • direct=None
  • while(True):
  • iflen(self.directs)==0:
  • break
  • tmpDirect=self.directs.pop(0)
  • iftmpDirect=="up":
  • x=self.x
  • y=self.y+1
  • eliftmpDirect=="down":
  • x=self.x
  • y=self.y-1
  • eliftmpDirect=="left":
  • x=self.x-1
  • y=self.y
  • eliftmpDirect=="right":
  • x=self.x+1
  • y=self.y
  • p=points[x][y]
  • ifp.value>0andp!=target:
  • continue
  • else:
  • direct=tmpDirect
  • ifpre==None:
  • self.changed=1
  • else:
  • if(pre.x-self.x)==0and(p.x-self.x)==0:
  • self.changed=0
  • else:
  • if(pre.y-self.y)==0and(p.y-self.y)==0:
  • self.changed=0
  • else:
  • self.changed=1
  • break
  • returndirect

  • def__eq__(self,p):
  • ifp==None:
  • returnFalse
  • ifself.x==p.xandself.y==p.y:
  • returnTrue
  • else:
  • returnFalse

  • points=list()
  • valuestack=list()

  • defcreatePoints(w,h):
  • """构造游戏界面的点

  • 初始化界面中的所有的点,并且规则如下:
  • 最外一层是“墙壁”点,接下来的一层是没有被填充的点,被包裹的是填充的点
  • """
  • r=random.randint
  • random.seed(time.time())
  • Pointstack(w,h)
  • forxinrange(w):
  • temp=list()
  • foryinrange(h):
  • ifx==0orx==(w-1)ory==0ory==(h-1):
  • temp.append(Point(x,y,9))
  • else:
  • ifx==1orx==(w-2)ory==1ory==(h-2):
  • temp.append(Point(x,y,0))
  • else:
  • temp.append(Point(x,y,valuestack.pop()))
  • points.append(temp)

  • defPointstack(w,h):
  • size=w*h-(w*4+h*4-16)
  • size=size/2
  • random.seed(time.time())
  • foriinrange(size):
  • value=random.randint(1,8)
  • iflen(valuestack)==0:
  • valuestack.append(value)
  • valuestack.append(value)
  • else:
  • valuestack.insert(random.randint(1,len(valuestack)),value)
  • valuestack.insert(random.randint(1,len(valuestack)),value)

  • deflink(source,target):
  • """点的连接

  • 连接方法的思想:针对源点的每个方向尝试前进,如果可以前进,
  • 则将针对该方向上的下个点的每个方向尝试前进,
  • 当一个点的可选方向都不能前进的时候,则使用规定的信息标记该点,
  • 并返回到已有前进路径中的前一个点,尝试该点其他可选方向。当回源点
  • 的每个方向都走不通,连接失败返回False。否则当路径连接到目标点而且
  • 路径的方向变化小于4的时候,连接成功返回路径
  • """
  • ifsource==target:
  • returnFalse
  • ifsource.value==9orsource.value==0:
  • returnFalse
  • path=list()
  • fail=dict()
  • change=0
  • current=source
  • tempPoint=None
  • whileTrue:
  • ifcurrent==targetandchange<4:
  • forpinpath:
  • p.directs=None
  • returnpath
  • ifchange==4:
  • current.directs=None
  • fail[str(current.x)+"_"+str(current.y)]=change
  • current=path.pop()
  • change=change-current.changed
  • continue
  • ifcurrent==source:
  • direct=current.forward(None,target)
  • else:
  • direct=current.forward(path[len(path)-1],target)
  • ifdirect!=None:
  • ifdirect=="up":
  • x=current.x
  • y=current.y+1
  • elifdirect=="down":
  • x=current.x
  • y=current.y-1
  • elifdirect=="left":
  • x=current.x-1
  • y=current.y
  • elifdirect=="right":
  • x=current.x+1
  • y=current.y
  • iffail.has_key(str(x)+"_"+str(y)):
  • ifchange>=fail.get(str(x)+"_"+str(y)):
  • continue
  • else:
  • fail.pop(str(x)+"_"+str(y))
  • change=change+current.changed
  • path.append(current)
  • current=points[x][y]
  • else:
  • ifcurrent==source:
  • source.directs=None
  • returnFalse
  • else:
  • current.directs=None
  • fail[str(current.x)+"_"+str(current.y)]=change
  • current=path.pop()
  • change=change-current.changed
  • #createPoints(8,8)
  • #p=link(points[2][2],points[5][2])
  • #printp


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-373913-1-1.html 上篇帖子: Python实例讲解 -- wxpython 基本的控件 (文本) 下篇帖子: python dataformat.py通用数据格式转化脚本
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表