天志,一个没有故事的男童鞋,在深圳南漂,过着苦逼的日子,想着美好的人生,平淡无奇却又想充满惊喜。。。

φ(≧ω≦*)♪

关于数独的那点事

2018.04.07

数独介绍

       数独是一个通过逻辑推理填写9*9宫格的益智类游戏,填写规则根据数独的种类不同而变化,最基础的数独的要求是,在每个格子中填写1~9中的数字,使得每行每列每宫(3*3)中不出现重复的数字。

       数独的难度并不是与需要填的格子的数量成正比,而是与填写时需要用到的逻辑推理的方法及其数量不同而不同,最简单的数独只需要排除法就可解出。

       关于数独解的数量,本人认为,好的数独题目应该是单解题,即一个数独只有单独一个解的题,但有时我们也会遇到多解题,即一个数独有多个解,我认为数独之魅力在于通过严密的逻辑推理,一点一点将数独填出。此时,一定有人会问,真的可以只通过逻辑推理就将一个数独填写出来么?作为一名资深菜鸡,我认为答案是肯定的,一是因为我相信一定可以通过逻辑填出,所以我相信自己现在的速度慢,一定是因为我在填写时发现逻辑的速度慢,所以我才会不断练习不断努力,二是因为和高手pk了这么多次,打死我也不相信他们试数能试的这么快。然而,著名数独学者lotsofone曾说过,多解题可以训练一个人风险分析的能力,由于笔者和该学者利益相关,此处不做过多评价。

数独软件介绍

需求分析

       由于对数独的喜爱,结合自身玩数独的经历,我认为一款优质的数独软件需要做到以下几点

  1. 可以提供优质的区分度明显的单解题目
  2. 用户可自主设置填写数独时的 显示时间与否高亮相同数字与否错误提示与否
  3. 简单优雅的UI,其中特别强调的是note模式下数字显示的优化
  4. 针对手机屏幕小的特点,填写数独的方式应为拖拽方式填写(感谢著名数独学者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上,喜欢的点一波小星星

发表评论