跳棋游戏利用树构建合法路径出现循环的解决办法

博主在使用Python做跳棋游戏时,利用树存储棋子合法路径,构造落点树时出现三个落点围成圈导致无限循环的问题。后续调试还发现类似棋局状况。博主尝试多种解决办法,如遍历落点树、使用全局变量、用函数变量作缓存等均未成功,最终实现记录跳转次数判断循环并返回空列表处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

我在做跳棋游戏时利用树来存储每一个棋子的合法路径,构造落点树时,要求遍历路径上每一个可能的落点。于是出现了一个尴尬的状况——三个落点围成了圈,如下图。
在这里插入图片描述
黑色实心点为棋子位置,三个虚线表示位置为形成循环的空位。其他棋子构造合法落点树时,一旦遍历到三个位置中的一个,就会陷入循环。因为棋子在三个中的任一个位置时,其余两个点都是合法落点,可以无限跳转下去,这条路径会有无限长。
出现这种情况可能是由于我写的人工智能算法不够机智,后续调试过程中发现了另外一些类似棋局状况,即三个空位形成循环。

解决办法

  1. 遍历已经形成的落点树,重复点舍去,重复次数过多时停止遍历(未实现)

    遍历已经形成的落点树显然是一种明显思路,但是对于我的程序来说实现较为复杂。
    我写的构造落点树程序在可以隔一子跳跃时发生递归,递归后只保存了部分上一层数据,也就是本次跳跃的起点或者说来路,最多只能追溯两层数据。然而形成循环基本是两次遍历以后的结果,即涉及到三层数据,以我现有的程序不满足直接判断重复落点的条件。且我也不能排除以后出现四子循环出现的可能性。

    于是考虑将落点树改为类中的一个私有变量,其在方法中的作用范围类似于全局变量(为方便表述下文称其类别为全局变量)。
    但是尝试后发现,在递归中几乎无法使用这种有层次的全局变量(有层次的变量即多维变量)。上网搜索后发现一般递归中使用全局变量都没有层次,例如利用递归求累加和等。
    后又尝试将函数中的变量作为缓存,一部分遍历完成后将结果直接替换到落点树中。没写成。总是会有重复替换,合适的替换位置不存在。

    所以从全局变量的角度来说,遍历形成的深度是没有意义的。一维变量更适合作为全局变量使用。

  2. 记录跳转次数,跳转过多时怀疑出现循环(已实现)
    没办法阻止循环出现,就在循环出现后处理。

    我写的人工智能太废柴,所以一般跳转次数不会太多,但是就算跳转很多次,有棋盘高度的限制,跳转次数一般也不会超过20。
    跳转次数基本等同于递归次数,所以递归次数有一个上限,我将其设置为10,正常来讲我的递归次数不会超过10,一旦超过就意味着有异常,我就有理由怀疑出现了循环。

    确定循环出现方法:
    我把棋子路径的六个方向分别标记为1-6,每一次跳转时记录跳转方向,列表存储,称其为方向列表。如果出现循环,则方向列表中的数据一定有循环。
    在出现循环的基础上,方向列表中的最后一个数据一定属于循环数据中的一个。检测其出现次数,就算路径方向集中,同一方向也不应该出现太多次。所以同一数据出现若超过3次,则判定为出现循环。

    处理循环的方法:
    返回空列表。(待改进,貌似有些过于简单粗暴。(但有效))

    #怀疑出现循环
    if firstMove>10:
    		#最后一个元素一定在循环中,所以确认其数量,过大时确认为循环出现
    		if wayOfPlace.count(wayOfPlace[len(wayOfPlace)-1])>3:
    			#处理循环
    			return []
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值