|
楼主 |
发表于 2016-8-21 10:15:41
|
显示全部楼层
本帖最后由 ntwuhui 于 2016-8-31 00:38 编辑
puzzle v1.0设计说明:
1、界面设计:由于EV3分辨率有限,这里设计为4*4的格子。右侧time、step、Rtime、Rstep依次为时间、步数、最少时间以及最少步数。
2、交互设计:
(1) 原游戏本应移动数字(先选择某中某个数字,再移动它),为了简化操作,以及提高移动时间(本游戏有计时功能),同时为了锻炼游戏者的思维能力,改为移动空格。
(2) 游戏开始时,当按下上下左右任意键时(且对空格操作有效),即开始计时(time)并计算步数(step)。界面只显示小数点后1位,实际记录时精确到小数点后三位(毫秒),初始时,记录值均为上限值999。
(3) 游戏中,可随时按确认键暂停游戏,一旦再次移动空格,继续计时。
3、核心设计:
为确保每次可以完成任务,必须让初始随机数满足以下两个要求:
(1) 能够不重复的生成1-15以及空格位(基本要求)
(2) 初始随机数从左到右,从上到下,构成的数列中的逆序对的个数与空格所在行奇偶性应该一致(这样才能保证有解)
如:上图可视为数列11、3、4、6、8、12、7、5、9、2、13、10、15、1、14,其中相对于11来说,(11,3)(11,4)(11,6)(11,8)(11,7)(11,5)(11,9)(11,2)(11,10)(11,1)共计10个逆序对,这样上图左侧共计有10+2+2+3+4+6+3+2+2+1+2+1+2=40个逆序对,空格此时在第4行,奇偶性一致,因此有解。否则的话,最后只能得到如下情况:
因此核心算法避免这个问题即可。
问题(1)的解决比较简单,将空格视为0,这样生成0-15内的随机数即可,为了避免重复生成,每生成一个新的数,将其视为阵列(数组)hash的下标,对应的值记为true即可(已生成)。初始时hash均为false(表示所有的数均没有生成),特别的记录下14和15的位置pos14、pos15(为解决问题2做准备)
问题(2),先根据上述穷举计算出逆序对的个数,判断当前情况是否有解,如没有,将pos14、pos15对应的14、15交换即可,这样可以高效地避免重新生成新的随机数。(PS:记录1、2的位置也可以)
4、主程序界面如下:
其中几个自定义模块如下:
Init:用于欢迎页面以及初始页面的显示(从记录文件中读取记录)
InitPuzzle:核心算法,用于生成随机数和保证有解
Timer:用于计时,可随时被暂停(确认键)
Move:用于移动空格,并更新数字阵列以及更新显示
Check:检查是否成功或者失败(超过999秒)
UpdateRecord:用于更新记录,(这里采用将文件方式记录最好时间及步数)
|
|