拼图游戏和它的AI算法

本文介绍了如何实现一个拼图游戏,并探讨了多种AI算法,包括广度优先搜索、双向广度优先搜索和A*搜索。游戏允许用户自定义图片、设置难度,并具有自动复原功能。文章详细讨论了各种搜索算法的实现细节,如状态树、搜索策略以及启发式函数,并对比了不同算法在不同难度下的性能表现。
摘要由CSDN通过智能技术生成

写了个拼图游戏,探讨一下相关的AI算法。拼图游戏的复原问题也叫做N数码问题。


  • 拼图游戏

  • N数码问题

  • 广度优先搜索

  • 双向广度优先搜索

  • A*搜索


游戏设定

实现一个拼图游戏,使它具备以下功能:

1、自由选取喜欢的图片来游戏

2、自由选定空格位置

3、空格邻近的方块可移动,其它方块不允许移动

4、能识别图片是否复原完成,游戏胜利时给出反馈

5、一键洗牌,打乱图片方块

6、支持重新开始游戏

7、难度分级:高、中、低

8、具备人工智能,自动完成拼图复原

9、实现几种人工智能算法:广度优先搜索、双向广度优先搜索、A*搜索

10、保存游戏进度

11、读取游戏进度


Puzzle Game.png


自动完成拼图复原


先看看完成后的效果。点自动按钮后,游戏将会把当前的拼图一步一步移动直到复原图片。



自动复原.gif


图片与方块


图片的选取可通过拍照、从相册选,或者使用内置默认图片。
由于游戏是在正方形区域内进行的,所以若想有最好的游戏效果,我们需要一张裁剪成正方形的图片。


截取正方形区域.png


选好图片后,需要把图片切割成n x n块。这里每一个方块PuzzlePiece都是一个UIButton。


由于图片是会被打散打乱的,所以每个方块应该记住它自己在原图上的初始位置,这里给方块添加一个属性ID,用于保存。


@interface PuzzlePiece : UIButton /// 本方块在原图上的位置,从0开始编号

@property (nonatomic, assign) NSInteger ID; /// 创建实例+ (instancetype)pieceWithID:(NSInteger)ID image:(UIImage *)image; @end


难度选择


切割后的图片块组成了一个n x n矩阵,亦即n阶方阵。而想要改变游戏难度,我们只需要改变方阵的阶数即可。


设计三档难度,从低到高分别对应3 x 3、4 x 4、5 x 5的方阵。



难度选择.gif


假如我们把游戏中某个时刻的方块排列顺序称为一个状态,那么当阶数为n时,游戏的总状态数就是n²的阶乘。


在不同难度下进行游戏将会有非常大的差异,无论是手动游戏还是AI进行游戏。


在低难度下,拼图共有(3*3)! = 362880个状态,并不多,即便是最慢的广搜算法也可以在短时间内搜出复原路径。



3阶方阵的搜索空间.png


在中难度下,拼图变成了4阶方阵,拼图状态数飙升到(4*4)! = 20922789888000,二十万亿。广搜算法已基本不能搜出结果,直到爆内存。


广搜算法占用的巨量内存.gif


在高难度下,拼图变成了5阶方阵,状态数是个天文数字(5*5)! = 1.551121004333098e25,10的25次方。此时无论是广搜亦或是双向广搜都已无能为力,而A*尚可一战。



高难度下的5阶方阵.png


方块移动


在选取完图片后,拼图是完整无缺的,此时让第一个被触击的方块成为空格。


从第二次触击开始,将会对所触击的方块进行移动,但只允许空格附近的方块发生移动。


每一次移动方块,实质上是让方块的位置与空格的位置进行交换。在这里思维需要转个小弯,空格并不空,它也是一个对象,只不过表示出来是一块空白而已。那么我们移动了方块,是否可以反过来想,其实是移动了空格?答案是肯定的,并且思维这样转过来后,更方便代码实现。



方块移动.gif


打乱方块顺序


这里为了让打乱顺序后的拼图有解,采用随机移动一定步数的方法来实现洗牌。

  • 6
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值