数独介绍
数独是一个通过逻辑推理填写9*9宫格的益智类游戏,填写规则根据数独的种类不同而变化,最基础的数独的要求是,在每个格子中填写1~9中的数字,使得每行每列每宫(3*3)中不出现重复的数字。
数独的难度并不是与需要填的格子的数量成正比,而是与填写时需要用到的逻辑推理的方法及其数量不同而不同,最简单的数独只需要排除法就可解出。
关于数独解的数量,本人认为,好的数独题目应该是单解题,即一个数独只有单独一个解的题,但有时我们也会遇到多解题,即一个数独有多个解,我认为数独之魅力在于通过严密的逻辑推理,一点一点将数独填出。此时,一定有人会问,真的可以只通过逻辑推理就将一个数独填写出来么?作为一名资深菜鸡,我认为答案是肯定的,一是因为我相信一定可以通过逻辑填出,所以我相信自己现在的速度慢,一定是因为我在填写时发现逻辑的速度慢,所以我才会不断练习不断努力,二是因为和高手pk了这么多次,打死我也不相信他们试数能试的这么快。然而,著名数独学者lotsofone曾说过,多解题可以训练一个人风险分析的能力,由于笔者和该学者利益相关,此处不做过多评价。
数独软件介绍
需求分析
由于对数独的喜爱,结合自身玩数独的经历,我认为一款优质的数独软件需要做到以下几点
- 可以提供优质的区分度明显的单解题目
- 用户可自主设置填写数独时的
显示时间与否
,高亮相同数字与否
,错误提示与否
- 简单优雅的UI,其中特别强调的是note模式下数字显示的优化
- 针对手机屏幕小的特点,填写数独的方式应为拖拽方式填写(感谢著名数独学者lotsofone提供的建议)
当然,除了基本的数独要求外,我更希望数独是一个交友手段,通过数独,将用户聚合,给数独爱好者一个良好的互动平台,所以我同时希望数独有更强的用户交互性,开发pk平台等。
作为一名已经开发了好久的数独软件开发者,我为什么要写需求分析呢?答案很简答,因为这便是我们的软件的目标 :-)
软件设计模式
MVC(Model View Controller)模式是我学习的第一个软件软件设计模式,同时我认为按照mvc来写软件,各部分的功能能清晰一些,所以此软件采用MVC设计模式。下面简答介绍下MVC
- Model
模型,是开发软件功能的原型,在本项目中模型即为数独本身。
- View
界面,用于展现给用户的界面以及简单的界面交互,在本项目中主要为做数独的page。
- Controller
控制器,用于打通模型与界面,用户在界面上产生事件后,通过控制器调用模型的不同函数,此外,控制器也可访问数据来交付给界面,方便界面渲染出相应的页面,在本项目中为控制数独页面的js文件。
微信小程序开发介绍
首先要给小程序戴高帽,微信小程序“无需安装,用完即走”的产品理念非常帮,由于微信小程序体积较小,接口多,所以,从客户角度来看,轻量级的手机app非常便捷,用户懒得为了一个功能下一个大体积的app,小程序随用随下,用完即走。同时,如果腾讯可以结合用户数据分析,更加智能的为用户推荐小程序,整个生态便会变得更加高效且智能。
接下来介绍一下微信小程序开发的基本知识。
微信开发要了解四个文件类型,wxml,wxss,js,json
- wxml是类html,它们的不同在于,wxml将div, p, span等统一整理为view,同时在wxml增加了逻辑判断,进一步划分Controller和View的界限,该在View中解决的问题不在Controller中判断。至于为什么微信搞这一套,可见知乎,内有Hux大佬的回答:微信小程序为什么不用HTML5、CSS,自己搞了个WXML、WXSS,很多框架用不了,好处一点不知道?
- wxss是类css,即控制html元素的格式的文件。
- js脚本文件便是写控制器和模型的地方,js属逻辑层,做交互逻辑的,同时微信小程序也推荐将本地数据存为js,在util.js中存储本地数据,再讲数据接口暴露出来即可。好吧,你们应该也看出来了,我真的不知道该怎么介绍这鬼玩意,懂得都懂,不懂得我也解释不清楚。
- json配置文件,负责页面背景色,标题栏内容,颜色等配置,同时在app.json还需要声明小程序需要的page页面,此处有一个小细节,page属性中的第一个page默认为开发时编译后显示的页面。
所以要开发微信小程序,写好每一个页面的这四个文件即可。
微信小程序-数独 Sudoku IN WeChat
首先谈一下模型吧,数独模型,在数独类中,我设定了四个变量
变量名称 | 类型 | 用途 |
---|---|---|
boardData | cellModel(*81) | 记录每一个格子的状态 |
row | Set(*81) | 记录每一行每一个数字的填写位置 |
col | Set(*81) | 记录每一列每一个数字的填写位置 |
zone | Set(*81) | 记录每一宫每一个数字的填写位置 |
其中对于每个格子,我要存储的内容有(cellModel)
变量名称 | 类型 | 用途 |
---|---|---|
cat | bool | 记录该格子是题目类型,还是用户可填写类型 |
note | bool | 记录改格子显示模式为note模式还是普通模式 |
content | string | 记录格子里要填的数字(note模式下数字个数可大于1) |
color | int | 记录界面显示时要填的颜色,设置0为用户可填写的正常颜色,1为题目设置的数的颜色,2为用户填写出现冲突时的颜色,3为用户开启同数字提示功能后的高亮颜色 |
提供函数接口有
函数名 | 返回值 | 描述 |
---|---|---|
getData(x,y) | cellModel | 用于更新界面时,得到boardData的数据 |
setData(x,y,num) | null | 用于用户输入填写数字时更新boardData |
setGame(x,y,num) | null | 用于输入题目数据 |
freshProperty | null | 用户每次填入数字之后需要更新boardData的数据 |
judgeCorrect | bool | 判断答案是否正确 |
reset | null | 重置数独 |
show | null | 调试用 |
其实大部分函数都很简答,此处算是有一个小亮点吧,就是freshProperty()中,利用row/col/zone三个set去快速更新color,判断每个set的数量是否大于1,如果大于1,说明set中存的格子都是有问题的,直接更新color即可,这个方法减少了遍历寻找出错格子的时间。其中set的存储用了一个简单的哈希,行数*10+列数,这样保证存储和寻找的时候也很快速。同时,在实现是注意note模式的格子对set的影响,最好判断,因为note模式里的格子的内容不应该存储于记录表中,而note与非note的转换时,需要注意下小细节。
之后讲下View,由于没有网页开发基础,加之配色细胞严重匮乏,所以,view就比较丑陋。
先是一行功能行,俩button+一个text,下面是两个表,一个是board,一个是table,都是拿canvas画上去的,乍一看,画面十分简(chou)约(lou)。
其实在view中还做了一层加载层,在数据没有加载成功时,让加载层覆盖在整个页面上,呈现加载动画。
最后说一下Controller,在数独页面的js文件里有以下一些变量和函数
内容 | 类型 | 描述 |
---|---|---|
sudoku | sudoku类 | 数独的实例 |
remainNum | int | 记录宫中剩余个数 |
correctOrNot | 布尔值 | 判断是否成功 |
level | int | 游戏难度 |
timeFlag | 时间是否开始 | 记录时间开始标记 |
noteOrNot | 布尔值 | 是否开启note模式 |
timeOrNot | 布尔值 | 是否开启时间 |
hintOrNor | 布尔值 | 是否开启高亮同数字模式 |
generateOk | 布尔值 | 判断数据加载情况 |
pathStack | stack | 记录做题路径 |
函数名 | 返回值 | 描述 |
---|---|---|
loadData | int** | 获取题目数据 |
freshUI | null | 更新视图 |
judge | null | 判断正确与否 |
监听board函数 | null | 监听点击哪个cell,更新stack,修改data |
监听table函数 | null | 监听点击哪个数字 |
timeStart | null | 开始时间 |
timeStop | null | 停止时间 |
newGame | null | 开始新的游戏 |
redo | null | 撤销 |
share | null | 成功后显示分享窗口 |
canvasIdErrorCallback | null | 获取并输出canvas绘制时的错误事件 |
整个页面的业务就是,先显示加载动画,获取数独题目数据,更改generateOK值,去除加载动画,freshUI,显示数独界面,timeStart,开始计时,用户拖拽数字到数独表中,同时记录用户填写的数字与填入的位置,将要修改的格子当前的状态存入栈内,之后sudoku.setData,将填写的情况记录进数独实例中,freshProperty,freshUI,更新remainNum,一直重复操作,直到remainNum==0,judge,如果返回true,timeStop,share函数显示分享窗口,如果返回false,就继续等到下一次remainNum==0时进行同样的判断。
总结
总的来说,在开发过程中大体的思路就是上述,其实还有很多别的页面要做,例如设置页面,个人信息页面,关于页面等,项目还需要队友一起完成,此外,实现细节也会有很多问题,view中canvas绘制时,数字居中显示我就用了三四个小时的时间做人工处理,还有微信提供的新单位rpx和传统单位px的各种转换等等,这个项目其实需要注意的细节还是有一定数量的,同时pk的后端还没有学习,还需要一定的学习量,任务量颇大。
但是,
我喜欢啊!
项目开源在github上,喜欢的点一波小星星