时间:2025-04-19 11:01:18
目录
《Andriod平台应用与开发技术实验》
实验报告
第一章引言 – 1 –
第二章调研阶段 – 2 –
2.1项目背景 – 2 –
2.2前期调研 – 2 –
2.3开发必要性 – 2 –
2.4预期功能实现 – 2 –
第三章设计阶段 – 2 –
3.1页面设计 – 2 –
3.2角色设计 – 2 –
3.3元素、定位设计 – 2 –
3.4原画设计 – 2 –
第四章开发阶段 – 3 –
4.1总体功能实现概述 – 3 –
4.2页面分布图 – 3 –
4.3各个页面的功能实现 – 3 –
第五章项目利弊 – 4 –
5.1项目特色 – 4 –
5.2项目中出现的问题 – 4 –
5.3废弃方案 – 4 –
第六章结语 – 4 –
6.1对项目的 – 4 –
6.2对数独爱好者的 – 4 –
6.3对开发过程中帮助我的人 – 4 –
作为今年初识数独并爱上数独的游戏爱好者,在贫瘠的Java技术和充满对如今市面上可见的数独游戏思考的艰难抉择中,选择了自己尝试进行数独开发。
2022年5月,我在百无聊赖的复习时,通过广告推广下载了一款名为“数独九宫格”的游戏。其实在此之前数独对我来说是一种困难而带有圣洁意味的益智游戏(有类似的印象只是因为艾伦·图灵当年酷爱在泰晤士报上做数独游戏),但当试着接触后发现,它与“困难”“枯燥”“只有喜欢数学的人才会喜欢它”这样的刻板印象相差甚远,甚至,我在不断挑战更多高难度数独、对角数独、杀手数独、异性数独等等游戏中找到了极大的乐趣与成就感。
这时才缓缓发现,一杯午后的热茶,一幅街景,一份被画的毛糙的报纸和一个铅笔头这样富有情调的画面,竟然也可以发生在我的身上。(这种画面感真的很难得!)
于是我在网络上查询了别人编写数独游戏的思路,在他们使用的canvas方法的基础上学习了许多与安卓有关的课外知识,确认开发可行之后,开始了长达三周的Andoird&Java开发旅程。
App截图如下:
(狠狠地把sudoku写错了,,,忘记改了之后也懒得改了,请不要介意)
数独(Sudoku),是最早起源于瑞士,传播于美国,兴盛于日本的填数字游戏。因它被发表在一本日本的游戏公司杂志上,起名为「数字は独身に限る」(只能填写一个数字),故改名为“数独”。
在中国,数独也在益智游戏中占有很大的市场空间,每年在中小学、大学生以及成人之间,都举办着规模不等的数独锦标赛。除此之外,教育机构、各大院校也有老师学生自发组织数独社团,以及数独玩家交流比试的活动。
只是随着网络手游的兴起,益智游戏受到了猛烈的冲击,更多新的游戏机制映入人们的眼帘,如风靡多年的“开心消消乐”、大家在广告里可能见过的“水排序”,b站主播喜欢挑战的“异性拼图”,以及最近火爆的“羊了个羊”。
色彩、设计以及新奇的机制垄断了玩家选择益智游戏的方式,数独也在20年前后缓缓退出人们的视野,数独业余段位考试也因人数等问题不再举行了,零零散散的数独爱好者们散落进莫大的都市中,如点点金砂一般。
如何让数独游戏重新走进人们的视野,如何让大家爱上数独,我们还有很长的路要走。
了解目前市面上的数独app热度,游戏机制和一些玩家偏好,并了解不同类型的玩家对待当前数独app的看法。
1.APP Store上国内外现有的数独软件(3个主流app,3个冷门app);
2.身边18-22岁年龄段的大学生、以及数独爱好者。
2022.10.3-2022.10.9
对app进行下载测试,对人群进行随机采访。
App调研:
人群调研:
(A.太难了,不会玩
B.太无聊,没意思
C.没有纸片人有意思
D.广告太多
E.其他)
先从人群的调研结果讲起,数据非常有趣。
在随机采访中有100%的人玩过数独,但有将近60%的人认为数独无聊,并有40%的人认为数独困难。并且,在第三题“什么原因阻碍你玩数独游戏”的多选题中,100%的人都选择了“没有纸片人有意思”。
大部分人觉得因为数独的规则和玩法过于枯燥乏味,成就感少,并且没有绚丽的游戏画面,所以在难度逐级递增的过程中丧失了游玩的欲望,并感到无聊。
所以我认为应该在游戏玩法设计中加强横向创新,也就是在难度不变的基础上加入更多游戏模式,让大家更加了解到异性数独的趣味性。
同时,加强画面和故事设计,以及交互设计,让数独画面不再是枯燥的“报纸”,而是更加贴合当代游戏模式的故事推动主线、活动推动创新的游戏形式。
然后呢是对市面上的三款主流类数独游戏和三款媒体类数独游戏的调研。
主流类数独游戏,受众主要是数度爱好者,没有过度绚丽的画面,主要以方便填写、题库丰富为主,在此基础上,有一款游戏设立排行榜机制,三款都以玩法多样题库丰富为主。都没有广告,且都是在填完之后才设立检查功能。他们的鼓励活动相对较少,除了排行榜外,几乎只是一个设计简单的竞赛题库,没有定期大小活动等等。
媒体类数独游戏,主要应收依靠游戏推广,所以含有大量广告,受众主要是普通用户,主要以操作简单、操作台功能多样为主。他们的答题界面包含撤回、一键填数、提示等等功能,这些是主流类数独不会有的。但相应的,每个功能都以看广告为代价,题库以普通数独为主,多是由算法自动生成的,不附带竞赛题库。但媒体类数独含有定期活动,如“每日挑战”“挑战杀手数独”“季度活动”等等,在完成规定的题目后获得奖杯,算是在一定程度上提高了积极性。
总结来说,数独游戏的改进,应当将市面上两种主流游戏的特质结合在一起,如设立既包含多种多样的题库,又能够兼容算法生成的普通数独题目,以及有定期维护的活动等等。
这绝对是一个无法短期做完的大工程。
不过,这样的游戏模式是市场所需要的,也是数独爱好者所需要的。
功能(远期)
1.数独每日挑战,活动副本;
2.数独题库,分为简单,普通,困难三种;
3.计时器,在每场游戏中;
4.用户界面,有用户名、头像、账号、密码、平均排名、活动排名、成就;
5.成就板块,有登录天数成就,做题天数成就,常规排名成就,活动排名成就,做题时间成就等;
6.主题颜色的更换;
7.排行榜,分为题库内的关卡时间排行榜,活动排行榜和平均时长总榜;
8.设置,包括主题设置,音乐音效开关和更改,数独偏好设置等。
关卡选择:
简单:
普通:
困难:
胜利画面:
主页面画面:
等待界面:
引导界面:
如设计阶段所规定的一样,主要分为五个主要页面:
·MainPart:游戏主界面,包含用户信息、荣誉、活动入口、普通关卡入口;
·Store:商店界面,售卖相关题库,以及活动产品;
·Setting:设置界面,玩家可以选择自己的偏好以及对游戏的建议看法;
·LevelChoose:关卡选择界面,选择普通关卡的难度以及level;
·LevelRead:关卡读取界面,也就是游戏界面。
游戏的加载页面。
但因为加载太快了,所以将进度条改为了SeekBar,拖动到底,出现按钮。
功能实现就是通过调整可见性即可。
主界面包含有三个界面的跳转按钮和进入的关卡选择按钮。其实还应该有用户登录界面和活动关卡进入界面,但苦于事件还没有完成。
在还未敲出来的活动关卡中,将会开发异形数独和竞赛数独的关卡。
我对设置界面的设计最初有很多设想,但是苦于开发周期和技术受限,目前只实现了音乐开关(switch)功能。这个UI很简单,为switch申请一个onCheckChangeListener然后做if判断控制开关即可。为了全局播放音乐,并且不重复调用音乐播放器,我将音乐功能放置到了一个独立的类——mediaIntance中,作为一个单例模式使用。关于音乐播放的事,请见4.2.7音乐单例。
还没有来得及做出来,我的设想是用做一个流式布局做一个商品展示页面,然后点击后生成dialog弹窗,上面点击按钮可以购买,进行外部链接的跳转,点击空白处取消。
关卡选择界面,在这个界面中通过按钮点击,将数字利用putExtra传入LevelRead中。
数字是哪里来的呢?实际上并不是预先存储的,而是直接获取到按钮上的数字,然后强转类型传入进去的。
代码如下:
还有一个功能就是通过下面的单选框RadioGroup选择关卡难度,同时,下面的图片也会发生变化。
这个通过设置图片可见性也可以完美解决。
就不做过多解释了如下所示:
在这个界面中主要目的是得到LevelChoose界面获取到的关卡数,并传值到本活动的布局文件中用于读取关卡数据加载游戏地图。
因为之前LevelRead中已经通过强制转换关卡按钮text为int值将其存放在level中,所以只需要重载PlayGround中并允许它传进一个level值即可!
传入PlayGround后,我设定了两个String类型的变量,一个levelRead盛装关卡信息,一个levelAnswer盛装答案信息。
更细节的用法,还请我们在playground类中细说吧。
先看看代码:
LevelRead中如下:
然后是LevelChoose中的方法是这样的(之前写过了,为了方便理解,再看看):
再看看PlayGround方法此时:
展示页面:
在我将PlayGround之前, 烦请先移步4.2.6.2点阵,把那一章看完再回来!
在Dot中我定义了九阶矩阵中的每一个点的信息,看完更有助理解。
准备好了吗?
那我们开始讲解PlayGround类吧!
Playground是levelChoose活动的java布局文件,因为使用.xml文件的话,数据结构和数据的读写方面会存在很大限制,所以不如直接使用安卓工具用java写一个布局。
想法有了,那么开始做吧。
画布工具Canvas:
参考了许多安卓小游戏的做法,最终我学习了使用android.graphics.Canvas;中的Canvas来进行画布的绘制。
使用Canvas就涉及到了在View上绘制,要继承view或者view的子类surface。
然后就可以使用在paint、drawText、drawLine、drawRect方法在canvas上绘制了!
Paint是画笔工具,可以new一个画笔工具并设置相关属性,请看下面我绘制方格的画笔工具的例子。
这里c是我对Canvas的定义。
然后再看看如何使用drawxxx,ctrl+点击看看它的方法,以下是我觉得比较好用的三个使用方法,之后绘制地图和绘制按钮时,我大多使用的都是这三个方法:
九阶矩阵matrix[][]:
想想这个矩阵是什么类型的。每一个点,我们都要能获取到它的x、y坐标,以便对它进行操作,同时能通过它的坐标对它对应的格子进行颜色的变化。所以,就使用我们自己写的Dot类型。
private Dot matrix[][];//九阶矩阵,存放棋盘格
就是这样!
但因为二维数组里的x、y坐标和我们dot中的x、y是反的,所以我还写了一个getDot方法,来直接通过x、y把dot和matrix联系在一起,看看如下代码:
一维数组sequence[]:
private boolean sequence[]=new boolean[9];//一维数组,存放选数区数字
因为打印的是1-9递增数列,也不需要改变数字,所以其实没什么必要设置int型的数组。我只需要知道当前哪一个被点击,所以设置一个boolean型的数组就行!
学会基础的绘制方法和数字的储存结构后,我们来考虑一下这个游戏的框架。
游戏加载:
当开始思考制作数独时,我们就要思考一下每次加载地图时的,加载各种元素的顺序。
先来梳理一下我们需要加载的元素:
·建立九阶矩阵并初始化
·绘制9×9方格
·读levelRead(关卡数据)
·读levelAnswer(关卡答案)
·绘制关卡数字
·绘制选字区
·……
看起来很多对吧!!!
先别急,我们来分类一下,什么是与绘制有关的,什么是与数据有关的。
与数据有关的:
·读levelRead(关卡数据)
·读levelAnswer(关卡答案)
·建立九阶矩阵并初始化
与绘制有关的:
·绘制9×9方格
·绘制关卡数字
·绘制选字区
·绘制检查按钮
OK!!!目前就这么多了,可以着手试着做了。
首先,先写与数据有关的刷新方法initGame():
为了方便起见,再设置两个单独的对矩阵和数组分别刷新的方法。
之后会用到:
做到这儿,初始化就完成一半了!!!完美!!!!
下一步是地图绘制,
redraw方法:
绘制的方法一共三部,定义画笔、设置属性、划线。
所以redraw方法基本就是在重复这三部,话不多说,直接看代码。
在此解释一下我使用drawRect(RectF,Paint)的原因——
起先是在看教程时,其中解释说,new rectf可以让方格按照预想的一样居中放置。
在网上查询rect与rectf的区别时,也解释说因为rect中的变量right、left、top、bottom是int型,而rectf是float型,可能会更加精确,但是ctrl+点击查看这两个传入的参数,可见,都是float型,不加new rectf应该是没有变化的。
后面使用drawRect时,我使用的就都是drawRect(float 左右上下)了。
这里还有一个要设置的是不同状态时,方块、选字框还有数字的颜色,所以,我在setColor方法上结合力switch-case,先判定一下当前状态再进行上色。
每次数据变化只需要进行一次redraw即可刷新地图,细节请参照上面的代码。
接下来是如何读取数字的问题。
在这个问题上我思考了许多种方法,我的思路顺序大略是下面这样的:
方案1.用输入流输出流的方式读入文件数据。
方案2.写一个专门储存游戏数据的类,随时调用。
方案3.写在String.xml中调用
虽然听起来有点低效,而且维护成本大,不过对于小项目,还是在接受范围内的。
于是我开始着手做方案2。
写一个java类,定义数串并当读到关卡数的时候返回关卡值。但是写到一半的时候,我的同学建议我:
为什么不把关卡值存在String.xml里?
对哦!
为什么不呢?
这样比java类更简单,而且更容易修改。直接着手写:
先写了简单模式的八关作为实验品。
命名方式为i_j,i表示难度(简单1,普通2,困难3),j表示关卡数1,2,3,4,…,n。需要填写的地方改为0,只要打印的时候把0的位置跳过就达到目的了。
Perfect!
然后继续思考初始化的问题,初始化关卡信息(写入数字)吧!
我在前面描述过对关卡信息的存储,字符串levelRead储存数独题目,字符串levelAnswer存储数独答案。
通过之前把level的传入,我们通过一个getString方法结合之前R.String.name就能很简单就能获取到我们在String.xml中输入的信息。
请看如下代码:
不过我们在初始化题目时,还要多干一件事。
仔细思考,我们将九阶矩阵maxtria当作棋盘,里面每一个点都是Dot类型,具有自己的状态,那么我们在输入时同时需要让已经填上数字的格子和没有填写数字的格子区分开。
怎么办怎么办?其实一开始我们已经设定好了。也就是dot的Input_Status输入状态。
所以可以在getLevelReaad方法中多添加一句:
(不过改变状态的方法这样写其实不太稳定,如果想优化一下,可以把它封装起来,而且,状态的改变也可以在打印数字时在进行。
我的最初考虑是,提前将状态转换后,更稳定,在刷新地图时点不会轻易改变,如果在打印数字的时候改变状态的话,可能会因为我高耦合的代码而产生难以解决的问题!!!)
然后简单写个printf我们关卡数字的方法即可,我这里这个方法的名字叫public void levelOutput(String levelRead,Canvas c)
因为它的写法和redraw里的绘制方法相同,所以就不多做描述了。
这样初始化的任务我们就基本完成了,接着用回调函数加载布局:
在重写与它有关的方法,主要用于加载页面和让页面更加适用屏幕。
初始化大概设置的差不多了,我们就要思考一下交互设计了。
根据之前的调研,我最终敲定:
胜利判定机制: 最终判定
提示机制: 只做选中数字相应横行、纵行、同一宫的提示,不做更细节方面的判定,取而代之的是在游戏最开始的地方加入新手指引
选字机制: 玩家通过下面的选字框选数字
【其实在地图绘制的时候这个思路已经体现出来了,最后敲定方案实际上是在绘制完地图后,第一次开发缺少经验,这个理应在设计阶段就定下来的。】
那么与玩家的交互便是玩家点击填数。涉及到onTouch的方法及其监听器,那就在playGround中加入onTouch监听器。
这样playGround也就基本成型了。
之后写onTouch中的方法。
其实思路非常简单,在此就只讲解了。
从玩家的点击事件中,我们其实并无法真正知道玩家要点击的数组坐标,而是会获得一个以整个手机屏幕为坐标系的点击坐标(x,y)。
既然获得了这个值,下面的事就很简单了,将整个游戏界面分区块,点击到哪个区块,就执行哪个功能,然后在方法内减去整个区域的xy偏移量,对区域里每一个格子进行操作(状态改变等等等等)。
主干如下,剩下的就是算法问题了,在此不多加赘述。
不过这里有一个要点,就是点击时要慎防数组越界,也就是用户点击到了我们还没有定义的地方,从而发生异常,所以一定要做异常处理。【参照else中】
如果用户点击的地方未经定义,就初始化一次变量。(取消所有点击状态的变量)
再在代码优化上稍加处理后,我们的填写部分也基本完成了,随后也就是检查部分。
这里思路就很简单了,用户在每次改变方框中字符的时候,同时修改字符串levelRead中的值,最后再将levelRead和levelAnswer用charAt(i)比对即可。
对错误的数字进行input_Status状态的改变,如果没有错误的话即可退出游戏。
不过,特此强调一下退出的方法。
因为布局文件playground并不是活动,而且接受到的context并不是LevelRead(游戏界面的活动)的子类,调用不了finish方法。所以怎么退出?
怎么办怎么办怎么办怎么办?
对LevelRead寻根溯源,发现context是它的父父父父父父类。所以可以强制转换一下!
levelAct = (LevelRead)context;
然后在LevelRead里写一个方法把finish()封装起来调用即可。
LevelRead里的:
Playground里调用的:
over是我的错误代码,
over=0,没填完;
over=1,有错误;
over=9,胜利。
playground告一段落!
因为我们游戏中要让九阶矩阵完成每一个格子能变色,并且里面的数字可以改变。
所以,我要设定一个Dot对象,里面包含x、y、盛装数字的状态Input_Status、当前的点击状态Click_Status。
这是对Dot类中元素的定义:
然后为了方便,给每一个量写get、set方法,可以通过AS自动生成也可以自己写,很简单直接看代码:
SetXY()这个方法是为了方便多写的一个(虽然最后没有什么用处又被playground里的getDot方法代替掉了,但那已经是后话了)
总体来说光是写这个类就下了很大的决心。因为在朋友推荐之前,我还从未使用过甚至已经淡忘了名字的知识点。
单例模式,字如其名,就是类中只存在也只能存在一个实体的类。而且在程序中使用时,作用对象始终是同一个。
它因为设计思路和应用场景的不同,主要被分为两种,懒汉式和饿汉式。主要就看是“需要时调用”还是“随时创建”。
它的格式如下:
只要保证每次调用时只会出现一个且仅一个实例即可。因为我没有多线程的功能,所以不需要担心我的单例模式出现建立多线程的问题,所以在这里就采取 双重锁 的结构了。
然后因为个人Java基础太差问题,卡了我许久的是类之间传递数据的方法。浅浅整理一下,Java的类之间传递数据一共有三种方法。
虽然道理是这样子,我对第二种方式还是抱着很大的疑惑的。如果这个对象里没有明确的属性怎么办,我想调用里面的方法怎么办?然后在朋友坚持不懈的讲解和csdn中安卓音乐播放器代码的启发下,我终于学会使用静态类方法来进行方法的调用。
我对静态类的理解是——为了减少不必要的对象的加载,所以可以只将这个对象的常用方法设为静态类,以便于调用,而不用在每次加载之前还要将对象实例化一遍。
然后我完善了代码:
对于点击“start”按钮的:
对于单例模式的方法的:
音乐播放器的initMediaPlay()方法和书上讲的类似,在此就不做细说。
然后只需要分别写一下play和stop方法来控制音乐开关,再在设置页面的switch中调用即可。
若说起在开发过程中遇到的bug,最多的还属两类:
·数组溢出类
·构建失败类
(因为出错时忘记截图,所以就浅浅口述一下了)
先说第一类,其实并不算难找,run中找到error的红字,再看一遍就很快发现了。这个问题主要出现于我的九阶矩阵的错误赋值或者是onTouch方法中用户点中了未提前设置的位置。
解决方法就是重新估算距离,或者做好错误处理就ok。
最头疼的是第二类bug。
无需多言,上字段。
Launching ’app’ on emulator-5554.
Installation did not succeed.
The application could not be installed.
出现这个问题,就能很快知道是虚拟机出问题了。但是到底是什么问题呢?
查询了许多博客,大多数人的此类报错后都会带有虚拟机出错的原因。
但是很可惜,我的是没有的。。。
有人说要在Gralde文件夹的local.properties文件中加入android.injected.testOnly=false,但经过我的尝试后,没有用。
还有人说要换虚拟机重试,这个方法不算太好,不过出九次bug能好七次,也还算管用(就是starting时间太长了)。
最后我学会了cold boot和wipe data,一套组合拳解决问题。
由此可知,这个问题的原因应该是虚拟机的内存不足。其实在有些版本的AS中是有提示的。好奇的朋友可以在csdn上查询到。
不过没有归没有,KO掉就是胜利(·`ω·`)y
一、填数刷新
在进行bata测试的时候,朋友们建议我说:为了方便考虑,能不能在输入完数字后自动取消点击状态。听起来简单,这个问题困扰了我很长时间。
用户的填数操作无疑只有两类。
最开始为了保留每次用户点击后的位置信息以及数字信息的存储,我定义了两个用于存储位置和数字的变量。
那么我就为这两个事件的结果开设两个存储空间。
然后设为类内的private变量,每次点击位置改变时,就给它赋值,然后一旦填数成功,就把它清空。
可以将其理解为一个深度为1的栈,将值置入栈顶,使用时就弹出即可。
之所以没能刷新成功,是在如何刷新的算法上出现了问题。因为没有很好的对coo和point的封装方式,所以初始化的很乱,很容易出现数组溢出等等的错误,苦不堪言。
之后我又想起了我的initGame方法、initSequence方法以及initMaxtria方法,为什么不直接在初始化信息时将他们一起初始化?
于是我更新了这两个方法:
问题完美解决!
Bata测试中出现了一个扑朔迷离的问题,“填数过程中,已经填写一半了,在点击九宫格时,突然闪退到主界面”。
为什么为什么为什么为什么?
我只能猜测这应该是矩阵Maxtria填数错误发生了溢出,但在自己的测试中始终找不到问题出在了哪。
然后查询run中的信息,……Integer.valueOf…
发现是int类型的数组溢出,报错在point和coo的位置,发现point没有初始化数字,赋初值以后,解决。
为了增加另外几个难度(普通、困难),所以更新了一下LevelChoose中的代码。只需要向传入的intent中多加一个difficulty的int型变量并传给PlayGround即可!
直接上代码:
这样子,在改变一下playground的传入数字的格式,把difficulty放进去就好了。
本次虽然时间紧张,但还是一鼓作气把界面和游戏算法给做出来了。
游戏中目前包含开始画面、游戏界面,大量对游戏的错误处理机制。填写方便,检查机制更符合竞赛规则。
这是我第一次从构思到机制设计到算法,完全由自己一个人完成的项目。虽然看起来麻烦冗长,但敲代码的过程是非常非常快乐专注的,而且学习的主观能动性非常强,自己查询学习了许多课内外的知识,增长了见识,而且,最重要的一点是,在自己计算、思考、改bug的过程中增长了大量的编程经验。
我遇到的太多bug主要都与我的编程习惯有关。在开始脑中和纸上都没有画过类图,在写方法时不注意private和public变量的使用,也没有提前计划好如何更好的封装我的类,所以许多功能都混杂在了一起,在出问题后,我对此使用替换查找,找到关键词充满了代码的各个角度,头疼!
其实最开始我只设置了一种状态,将input和click状态混杂在一起。这时就出现了问题——一个格子可能具有很多状态,但在我切换状态时,这些状态互相顶替,功能还有不同程度的重合,给编程带来了极大的困难,几乎是到了编码中期,我才将这两种Status封装起来,这才让app变得稍微有些层次感。
所以在接下来的编程中,我就更加注重避免耦合,将更多可以独立出来的功能封装进独立的方法中。只是下次编程前,我会封装更多的类,把主类和其余的对象分离开。
我认为这次编程是成功的,Android不仅仅是一门课,它给予我一个练习java和应用开发的平台,让我更加熟悉编程模式和软件工程知识,并且与最近正在学习的信息系统知识也更好的结合在了一起。
纸上得来终觉浅,绝知此事要躬行。此话真的不假。
数独在近几年已经逐步走向消亡,退出人们的视野中,跻身于中小学生的智力竞赛里,也只有青少年的竞赛活动中,还能看到它的身影。学校中的数独社团也越来越少……
这着实令人痛心。
我希望能通过我的努力实践,更加了解这个游戏的机制,以及玩法。有时候学会不以为着懂得,这样的实践也让我的理解进一步深入,我觉得下一次,我就可以挑战制作6×8数独、对角数独等等……
各位数独人,需共勉,再接再厉!
感谢我的室友们与我的同学们在我的开发过程中提出了许多指导意见,并协助我进行测试工作,这给予我编程莫大的帮助与鼓励。
包括但不限于将答案存放在String.xml,封装finish(),在我很多困难的时候伸出援手,带我走出黑暗的改bug和调试生活。
同时也感谢我的老师,能给予我这个千载难逢的机会,能让我以作业的理由进行我喜爱的事情。
再之,也感谢一直坚持下去的我!
不知道大家都喜不喜欢玩数独呢?我记得读书时,最大的乐趣就是课后玩数独,当时玩过任天堂的一款游戏 《脑力训练Brain Age》 ,里面有很多的数独题目都很经典,这是我真正走进数独世界的童年回忆啊。
现在想起来,虽数独很烧脑,但那份挑战带来的成就感,至今回味起来都觉得特别棒,所以我趁哥哥弟弟三四岁的时候,就带他们玩起了比较简单的数独游戏~
坦白说,之前看《最强大脑》,里面有很多选手都是玩数独的高手,他们的 观察能力、专注力、逻辑推理能力都特别强 。
所以在很多人的印象中, 玩数独的孩子=高智商的聪明人 ,就像最强大脑里的酱油少年胡宇轩一样,他只用5分钟就解出了有2688种组合方式的异形数独拼图!
但其实数独入门没那么难。
数独是一个规则简单但又难度多样、变化无穷,老少咸宜的游戏。即使出门在外,一张纸和一支笔就能玩起来。
数独难的是如何步步提升逻辑思维,孩子不靠抓阄试错随机组合,都能解读数独规律,这点突破了孩子学数独才能学好。
所以今天的文章,我和 @饼干 一起从数独的定义、数独的基础到进阶的玩法、如何借助乐高带孩子入门、以及哪些数独相关的逻辑思维方法是可以教给孩子,跟你详细说说。
“数独”(Sudoku)一词的意思是“单独的数字”,或“只出现一次的数字”,是以数字为表现形式的益智活动。
源自18世纪的瑞士,是用纸、笔进行演算的逻辑游戏。
最经典的数独游戏,一般是9×9一共81个空格,然后根据盘面上已有的数字,推理出其他空格应填的数字,以此满足行(横排)、列(竖排)、宫(3×3的格子)内的数字,分别为不重复的1-9。
为了适应小朋友参与数独游戏,会有一些四宫格入门游戏,进阶的六宫格,以及各种图形变化的宫格游戏。
数独是一种纯逻辑性的数字填充游戏,整个游戏过程 不涉及计算,每一题只有唯一答案,答题的过程就是严密的逻辑推理过程 。
因为不涉及计算/运算,所以数独对于学龄前的小朋友来说是友好的,非常适合用于训练孩子的逻辑思维能力,帮助孩子理解逻辑推理是怎样一步步展开的。
同时对于 专注力、观察力的提升 ,对 数字的敏感度 也有很大助推作用。
经常出现在低年级小朋友身上的问题:上课注意力不集中,爱走神,做作业马虎,拖拉,对学习没兴趣,需要家长督促等等,其实可以用数独游戏来帮忙。
从幼儿园开始,就已经有很多降阶版的数独启蒙游戏。不管是幼儿园的益智玩具,还是各种练习册教材,都把数独游戏作为数学启蒙和思维启蒙非常重要的组成部分。
这道题目是不是很熟悉?要使每行、每列的图案都不一样,把贴纸贴在相应的位置。
所以,小朋友们对数独类游戏并不陌生,3岁就可以玩起来。
近些年数独突然在中国孩子中火起来,很大一部分原因是很多重点小学、国际学校的幼升小考试都会涉及数独的内容,小学的奥数里也时有出现。
对于启蒙阶段的孩子,暂且把复杂的九宫格放一放。先从简单点的四宫格入手,且将枯燥抽象的数字换成有趣的图案 。
四宫格,一共有4×4=16个格子,分为四行、四列、四个宫。
这是一个由不同颜色的图形构成的四宫格:
还有卡通图案四宫格:
以及由不同颜色积木组成的乐高数独:
加点难度的还有 六宫格 ,由6×6=36个格子构成,分为六行、六列、六个宫:
已经认识数字的小朋友就可以开始玩数字数独了,也是先从四宫格开始,这是我家不到四岁的小朋友完成的四宫格:
至少入门级的数独,并不难,而且很有趣,在家长的正确引导下每个孩子都能喜欢玩数独!
1)帮孩子认识行、列、宫
行、列、宫,尤其是宫的概念,对孩子来说比较抽象,不好理解。
首先告诉孩子 “横着是行,竖着是列” ,可以用涂色游戏帮助孩子认识行。
还可以通过乐高来帮助小朋友认识列:
但是这个2×2的宫,是个抽象的概念,不像行和列那么直观。孩子的抽象思维有限,那该怎么办呢?同样我们可以用乐高帮孩子熟悉宫:
2)数独的规则
在熟悉了行、列、宫的概念之后,这时候我们告诉孩子数独游戏的规则:
在空格处填入数字1-4, 使每行、每列、每宫的数字不重复。
规则虽然简单,但是对于刚开始玩的小朋友可能考虑得不那么全面,这时我们先不着急去做数独的题目。
可以和孩子一起 动手摆一个数独 ,为了降低难度,我们先控制一个因素,只考虑另外两个因素,那么如何控制呢?
一张四宫格数独表,4组不同颜色的乐高积木,每一组由不同颜色构成。
每人两组积木,每人一行(列/宫)轮流摆放,因为每一组积木中没有重复,所以在摆放的过程中,行(列/宫)上不会出现相同的。只需注意另外2个结构方向上有没有重复。
你摆一行,我摆一行
我先摆出第一行,小朋友在摆第二行的时候,只需注意列和宫内没有重复就好。依次摆完所有积木。
你摆一列,我摆一列
玩法同上,过程略。
你摆一宫,我摆一宫
以宫为单元,轮流摆放。宫内不会重复,摆放时只要看行列上是否有重复。
发现问题没有?当我们轮流摆放到第四宫的时候,发现无解了!
这时候只需将第二列红蓝两块积木调换一下位置即可:
这是因为我们以宫为单元摆放积木的过程中,一块积木在摆放时会有多种方式,有些就会导致最后的无解,但是一行一行摆放法就不会出现无解的情况。
这样我们就可以理解,数独的出题法常使用终盘挖洞法,即在九宫格里填满数字,使得每一行、每一列、每一宫都填满1-9且不重复;
再从终盘中“挖掉”一些数字,而不是随意写上1-9的数字(即使这些数字满足数独的规则),再留一些空格就可以成为一道合格的数独题目。
在整个过程中,孩子进一步熟悉了行、列、宫;了解数独的游戏规则,行、列、宫内不能出现重复,在玩的过程中也慢慢熟悉了游戏规则。
这个过程持续到孩子比较熟练了,就可以开始做数独题目了。
1)“唯一数”法
拿到数独题目后,首先要找出 每一行、列、宫里,只剩一个空格的情况 ,比如某一行已经出现了数字1,2,3,那么第四格因为不能与前面的重复,就只能填4,4也就是唯一解。我们把这种方法叫做“唯一数”法。
我们看这道题:
我们看到第一行已经出现了数字2,3,4,那么第一行的空格处只能填写数字1,同理第四行、第二列、第二宫、第三宫,我们用唯一数法,很快得出:
那么剩下的3个空格还能用“唯一数”法来求解吗?相信大家已经看出来了,第一宫、第三列、第四列,同样可以用“唯一数”法。
是不是很简单?
但小朋友很快就会发现,有些题目“唯一数”法是解决不了的,比如,我们来看这道题:
第一行、第四行,我们根据“唯一数法”,可以填上数字4,但是剩余的空格呢?
这里要用到另一种方法:
2)排除法
根据数独的定义,每行、每列、每宫的格子内,不能出现重复的数字,通 过已知数对某宫、行或者列进行排除的方法,我们叫做“排除法” 。
我们先来看第一宫,已经出现数字1,2,还缺数字3,4:
由于第一列已经有数字4,所以4只能写到第二行第二列的位置上,那么再使用“唯一数”法,图中X的位置填写数字3。
填完了这两个数字,你会发现后面的空格,运用“唯一数”法和“排除法”相结合,很快都能解出来!
下面是几个不同难度的四宫格数独,可以给小朋友试一试:
小朋友做四宫格已经毫无压力了, 就可以给他增加难度,进入六宫格阶段。
六宫格,一共有6×6=36个格子,分为六行、六列、六个宫。刚开始的时候,也可以通过观察,用“唯一数”法+排除法相结合的方式,把能填的都填出来。但是,随着已知数的减少,难度的增加,“唯一数”法+排除法就不够用了。
这时候,就要用到今天要介绍的第三个方法:
3)占位法
以行、列、宫为单位,每个数字只能出现一次,一旦出现了,相当于把它所在的行列宫都占位了。只有行列宫都没被占位的那些空,才能填这个数。
为了便于理解,我们用一个经典六宫格题目,来看如何用占位法解题。
占位法的第一步,是先观察,找出盘面上 出现最多的那几个数来作为突破口 。
以上面的六宫格为例,稍微观察下或者数一数就能发现,盘面上出现最多的数字是5,出现了4次。所以我们先以5作为突破口。
从5开始。先把整个盘面分成6个宫,我们发现,按照每个宫的数字不重复原则,只有两个宫里还没有5。
我们先来看第二宫,有5个空格,但由于第一行已经有5,和第四列已经有5,所以第二宫的5只能填在这个位置:
小朋友刚开始不熟练的时候,可以用手指比划,或者用笔来占位(某个数字所在行或列,用铅笔挡上),但不要在题目上画线,熟练以后就可以直接用眼睛看出来。
再看第五宫,有5个空格,由于第5行已经有5,第二列、第三列分别有5,所以5只能出现在:
3,2, 1和5一样,可以用同样的方法,把6个3,6个2, 6个1填在正确的格子里。
做完这一步之后,盘面上还空着的格子,就少了很多。剩下的4和6,我们可以再结合之前的“唯一数”法、排除法,把剩下的也都填出来了。
有了上述三个方法:“唯一数”法,排除法和占位法,绝大多数的标准四宫格和六宫格的题目都可以解出来。
我们的三个方法都是建立在数独规则的基础之上(行、列、宫数字不重复),规则本身就可以帮助小朋友做好题目了,当然随着宫格越来越多,已知数越来越少,还有些技巧可以帮助孩子更快地给出答案。
我不喜欢告诉小朋友技巧,技巧应该是他感兴趣之后,自己去发现和挖掘。
如果规则理解清楚,能坚持让孩子每天玩一个,那么数感(1-4,1-9)也会得到提升;同时题目应该逐步设计深入——当你发现孩子游刃有余,就是升级的时候了。
数独可以说是数学启蒙的经典之一,可以说不懂数独的话,不能算是真正懂数学。所以在引导孩子入门时候,有两点小贴士可以记住:
1、不要试错
如果你发现孩子在玩数独时仅仅靠“试错”方法在做题,可能是孩子对数独游戏规则没有理解,也可能是没有掌握正确的逻辑推理方法。
这时候一定要告诉孩子正确的数独推理方法(我这篇文章合适打印出来跟孩子对照着玩),而不要批评和指责。
2、多问几个为什么
当孩子填上相应的数字时,我们可以问 “为什么这个格子要填**数呢?”
如果孩子还不能有条理的表述清楚时,我们可以协助他们把思路整理出来。
数学是需要时间去消化和思考的一门学科,所以数独除非孩子真正入门和上手后,否则很难靠刷题刷出来成绩。
回归到本源,就是让孩子提高自己解决问题时能用的技能储备。
不然,数独入门,很难。
。别怕,用至尊宝的一句话来说,就是如果你看完头很痛,那就记得收藏打印此文好入门。
【END】
我给孩子引入数独的时候,犯过一次错误,直接给孩子买了高阶数独的玩具,就是完整的九宫格。结果对于三四岁的孩子们来说,肯定完全都是懵的状态,无论我怎么样绞尽脑汁,但对于孩子来说都太难。
① 数独为什么要学?
数独在全球的风靡程度已经超过30年了,还记得高中的时候玩过任天堂的一款游戏《脑力训练Brain Age》,里面有很多的数独题目都很经典,这是我真正走近数独世界的童年回忆啊。坦白说数独的作用比较全面,老人家可以拿来开发脑力,保持活力,小孩子也能锻炼逻辑、提高智力,所以是一个不管男女老少都很适宜的好游戏。
数独,也称之为“几宫格”游戏,我们比较熟知的是九宫格,我们需要根据9×9的格子上的已知数字,推理所有剩余空格的数字,并且满足1-9每个数字再每一行、每一列和每一个3×3格(称之为“粗线宫”)内的数字都只出现一次。但实际上针对低幼孩子的数独游戏,还有四宫格和六宫格,都是循序渐进地发展孩子的数独能力。
比如这个数独游戏便是出自一个幼升小的习题里,比较简单,大家可以感受下:有小朋友来家里做客,请你分一分餐具,将筷子、勺子、碗豆放在空白处,使得每行、每列的餐具都不重复。
最后做出来的答案是这样子的:
还有四宫格:水平方向有四横行,垂直方向有四纵行,划分为十六小矩形。在四宫格里,每2×2为一组粗线宫。
还有六宫格是这样子的,水平方向有六横行,垂直方向有六纵行,划分为三十六小矩形。在六宫格里,每3×2为一组粗线宫。
② 数独的入门解法:寻求唯一解
数独需要我们锻炼的就是逻辑推理能力,在解答数独题的时候,要注意第一个要点是让孩子寻找“唯一解”。就是每一行、每一列、每一组粗线宫都不能有重复的数字,因此孩子的重点就是需要找到唯一数。我们要学会判断一道数独题里,唯一数是什么,以及唯一数是放在哪里。
我们先来看看这个入门题目,我选的是四宫格。在下面的方格里,每行、每列都有1~4个数字,并且每个数字都只出现一个,那么A和B应该是多少?
1)行列排除法
行列排除法就是将一行或一列作为目标,用某个数字对它进行排除,最终得到这个行列内只有一格出现该数字的方法。比如当我们研究上面题目中的红色边框,我们可以得出什么结论呢?
以A为例,A所在的行已经出现了2,而列已经出现了3和1,所以空格里只能填4才不会重复。
以B为例,B所在的行已经出现了2,而列已经出现了3,所以空格里可以放的数字是4或者1,它也需要确定A的数字是什么,才能判断B的数字。
通过运用行列排除法,其实我们也已经确定了唯一解了。那就是A只能是4,所以B只能是1。
2)宫内排除法
同样是上面那道题,如果我们要把整个四宫格都填满,又应该如何继续下去呢?我们可以结合宫内排除法。
宫内排除法就是将一个宫作为目标,用某个数字对它进行排除,最终得到这个宫内只有一格出现该数字的方法。比如当我们研究上面题目中的红色和黄色边框,我们可以得出什么结论呢?
因为2已经出现在2组粗宫格里,所以剩下的2只能在黄色边框的宫内出现,否则就会重复。
以此类推,我们可以继续结合行列排除法和宫内排除法,整个图的空格就会越来越清晰了,你现在能把答案做出来吗?可以评论告诉我。
③ 资源推荐和下载
对于数独而言,基本规则了解后,剩下的就是让孩子多玩多做,就可以帮助提高孩子数独方面的思维能力。现在数独的资料其实很多,网上随便一搜都是几百题的训练,但实际上数独的入门最好是通过生动有趣的教具和游戏,这样子才可以让孩子对数独产生兴趣,而不仅仅只是为了“做题”或者某种竞赛。
很多时候入门一定要慢,让孩子多浸泡多玩透,等到孩子进入到深度学习的时候,才会发现自己还是有足够的领悟力去帮助自己提升,这个时候提供更多的数独题目才有意义。
到进阶阶段,就可以考虑更多的题目形式了,比如我家现在目前在用的这套教案,就是由欧洲教育部、科学部、欧洲社会基金部联合给学校老师设计的《数独入门教案》,它是一份公益资料,主要给学校老师向孩子们引入数独提供方向和指导,同时也有准备一些数独题让孩子可以多玩多学多练习。
整个题目的设计还是比较循序渐进的,大家看看目录,从4宫格初阶到16宫格专家级别都有。
坦白说,刚开始跟孩子做启蒙的时候,有时候面对自己陌生的领域可能会觉得很难,甚至无从下手,但实际上当我们认真走近它的时候,他们并没有我们想象中那么艰难,关键还是我们是否愿意让自己持续保持开放,去学习、多了解。
不要担心孩子需要花大量时间去入门,我们更重要的是能否看到孩子在这个过程中逐渐沉淀的思维力量,这也是我们启蒙的心态,要相信时间的复利哦!
【END】
用户评论
有没有哪个平台可以免费玩数独游戏的?
有14位网友表示赞同!
最近迷上了数独,想找个 app 下来随时练习。
有15位网友表示赞同!
听朋友说现在手机上有很多数独游戏的,推荐个好用的吗?
有12位网友表示赞同!
我想找个难度可调节的数独游戏下载,这样可以慢慢提高我的解谜能力。
有8位网友表示赞同!
听说有些数独游戏还有提示功能,可以帮助新手解题,这真的很有用!
有12位网友表示赞同!
我玩的是纸质版数独,想试试电子版的感受,感觉更方便吗?
有9位网友表示赞同!
下载数独游戏之后会不会比较占手机内存呢?
有19位网友表示赞同!
你们玩数独的时候喜欢哪个网站或者app提供的界面设计?
有9位网友表示赞同!
希望找到一个简洁易用的数独游戏,不用太多繁杂的功能。
有18位网友表示赞同!
想要找一款和朋友一起在线解数独的软件,有什么推荐吗?
有12位网友表示赞同!
有没有什么数独游戏可以跟AI对战呢?比较有趣哦!
有8位网友表示赞同!
下载游戏之前不知道哪个版本比较好,有大佬推荐的吗?
有12位网友表示赞同!
一些数独游戏能记录解题情况吗?这样方便我总结经验。
有13位网友表示赞同!
感觉玩数独可以锻炼思维能力,希望找到一款适合我的难度等级。
有8位网友表示赞同!
数独游戏下载页面会不会有广告比较烦人呢?
有20位网友表示赞同!
听说有一些数独游戏还可以根据你的解题速度给分段评级,这真是太酷了!
有11位网友表示赞同!
看了一些评论,觉得有些数独游戏做得很好,想试一试。
有13位网友表示赞同!
数独游戏适合各个年龄层的玩家吗?我的爸爸也想试试玩玩
有12位网友表示赞同!
下载下来玩了一段时间感觉很不错,分享给身边的朋友一起玩。
有5位网友表示赞同!