数织游戏简介

数织是一种逻辑解谜游戏,拥有简单的规则,解谜的过程也富有趣味。
引用nonograms网站的游戏规则介绍:
游戏棋盘是一张正方形网格,其中的每个格子最终需要涂成黑色或标记为X。 棋盘每一行左边或每一列上方的数字表示该行或该列上每一组相邻的黑色方格的长度。 游戏目标是要找出所有的黑色方格。
规则粗看似乎有些云里雾里,但只要一开始游玩,或是观看他人完成一局,就能立刻上手这个游戏。
为了给出具体的印象,下面给出一个30x30大小的数织游戏网格:

为了辅助对游戏规则的理解,下面给出一张数织游戏的未完成图:

数织的规则正是其游戏性的精华所在,这个游戏与其说是挑战智商的游戏,倒不如说是一个挑战大脑运算速度和准确度的游戏。

数织中的程序思维

数织游戏的答案无法通过暴力的手段破解,因为这种手段的时间复杂度是指数级的。但游玩数织游戏的途中,玩家们无意中展现出的程序思维,却给数织的自动化解答提供了帮助。
数织有两个很有意思的特点:
一是确定性。所有方格的状态最终都必然能够依靠已知的线索确认,一旦确定,该状态就不会被新的线索所改变,即所有的线索都只指向唯一的答案。反例是:知名的游戏‘扫雷’的高级难度中,就经常会因为线索不足,在最后面临‘二选一’的拼运气局面;而一些解谜游戏中,也常常出现‘多解’的情况。这个特性使得数织的游戏进度只有前进而不会后退。(除非某个格子推理错误)
二是变量少。数织几乎没有什么强大的限制条件(譬如数独每行每列填入1~x数字的强大限制),而整个核心线索也只有简单的一些数字,这使得玩家只需要不停地轮番套入几个公式,就足以完成一场数织游戏。事实是,在玩家进行游戏时,的确总是有意无意地执行着几个核心推理公式来推进游戏。这使得机器完成游戏和玩家完成游戏的差异极少。
而正是这两个特点,使得数织游戏充满了程序思维,也使得它的解法可以很好且简单地用机器重现。唯一的区别是,玩家通常用自己的数学逻辑直觉,机器直接执行函数。
下面,我将自己游玩游戏时产生的逻辑直觉数学化,把数织游戏的攻略定理列出。某些定理没有经过严格的数学证明,纰漏业余之处,还请巨佬指正。

数织定理

定义1:网格中的每一格都拥有三种状态:空白、黑、叉。称空白状态的格子为‘空白格’,表示没有被确定为黑或叉的一种状态;称黑状态的格子为‘黑格’,表示已被确定为涂成黑色;称叉状态的格子为‘叉格’,表示已被确定画X。当所有的空白格转化为黑格与叉格时,游戏结束。
定义2:一组连续n个空白格称为‘空白条’,一组连续n个黑格称为‘连续条’,一组连续n个格子,其组成为:左右为叉格或边界,内部为空白格与黑格,称其为‘待完成条’,待完成条中不应有已确定的连续条。(n>=1)
定义3:若称一格子‘已确定’,则表明该格的状态可立刻转变为黑或叉;若称一连续条‘已确认’,则表明该连续条不会再增长,且与某一数字完成了对应。
定义4:将空白条中的一些格子转化为黑状态,形成连续条,该动作命名为‘放入’。
定义5:定义函数block(n):block(n)={n,if n≥00,if n<0block(n)= \begin{cases} n, & \text {if $n\geq0$} \\ 0, & \text{if $n<0$} \end{cases} block(n)={n,0,​if n≥0if n<0​

定理1(同质定理):将网格的行与列交换、行与行交换、列与列交换,若干变化后,对于每行每列,数织所有定理依然适用;一个空白条可被分割为若干长度各异的空白条与连续条,对于每一个分割出的子条,数织所有定理依然适用。

定理2(驻格定理):对于k个长分别为n1n_1n1​,n2n_2n2​,…nkn_knk​的连续条,于m长的空白条中放入,对于第L个连续条,必有block(∑i=1kni+nL+k−1+m)block(\sum _ { i = 1 } ^ { k } n_ i+n_L+k-1+m)block(∑i=1k​ni​+nL​+k−1+m)个格子已确定。对于整个连续条,必有block((k+1)∑i=1kni+k(k−1−m))block((k+1)\sum _ { i = 1 } ^ { k } n_ i+k(k-1-m))block((k+1)∑i=1k​ni​+k(k−1−m))个格子已确定。

[推论]k=1时,特别的有block(2n−m)block(2n-m)block(2n−m)个格子已确认.
如何确定位置,及定理可视化说明:


定理3(坐落定理):欲在m长的待完成条中放入一长为n的连续条,此时空白条中已有一长为nTn_TnT​的连续条,左余L个空白格,右余R个空白格。

  • 当L+nT<n或R+nT<nL+n_T<n 或 R+n_T<nL+nT​<n或R+nT​<n成立时,必有max(n−nT−L,n−nT−R)max(n-n_T-L,n-n_T-R)max(n−nT​−L,n−nT​−R)个格子已确定。
  • 当L+nT<n与R+nT<nL+n_T<n 与 R+n_T<nL+nT​<n与R+nT​<n同时成立,可直接用定理2判明。

[推论](终端延长定理):当一待完成条的末端已有一格被确定,则有一连续条被全部确定。
如何确定位置,及定理可视化说明:

定理4(超体-oversize定理):

  • m长的空白条欲放入n长的连续条,m<n,则称该空白条对于该连续条超体。
  • m长的待完成条欲放入n长的连续条,且已放入nTn_TnT​长的连续条,左余L个空白格,右余R个空白格,若L+nT>n或R+nT>nL+n_T>n 或 R+n_T>nL+nT​>n或R+nT​>n成立,则必有block(n+nT−L)+block(n+nT−R)block(n+n_T-L)+block(n+n_T-R)block(n+nT​−L)+block(n+nT​−R)个格子于该连续条超体。
  • 一个已被确认的连续条,其相邻的空白格应直接转换为叉格。
  • 一行或一列中,某空白格或某空白条对于所有连续条超体,则该空格或该空白条的所属空白格应全部转换为叉格。
  • 一行或一列中,所有连续条已被填入完成,则剩余空白格应全部转换为叉格。
    如何确定位置,及定理可视化说明:

定理5(不可连接定理):一列/行中存在一条以上的连续条,取其中相邻的两个连续条,其长分别为m,n,中间相隔l个空白格。设该行/列未被确认的最大数字为max,若m+n+l>max,且m+l<max或n+l<max成立,则两个连续条不可被划分入相同的待完成条,且与该连续条相邻的空白格,不应被划分入相邻连续条存在的待完成条。
定理6(确认定理):当一连续条的长度与同行/列的某一数字相匹配时,进行如下判断,若为有一条为真,则立刻确认。

  • 最大匹配:在所有待匹配数字中,该连续条所匹配的数字是唯一最大的。
  • 唯一匹配:该连续条无法扩大(即两侧为叉格或边界),且匹配的数字是该行/列唯一的。
  • 边缘匹配:在所有待匹配数字中,该连续条所匹配的数字在最左/最右,该连续条的左方/右方没有黑格,且左方/右方的所有空白条长度小于该连续条。

数织的程序解法

想要通过程序解出数织游戏的解,一种思路就是将玩家逻辑简化,抛弃一些复杂的逻辑,把总结性的定理写成函数,循环执行,得出最后的解;另一种思路,则是依靠定理,对暴力破解手段进行大幅度剪枝。这里我们选择的是第一种思路,因为暴力手段再怎么剪枝,也不会变成线性复杂度。而我们知道,只要人类不出错,完成一局数织所需要的时间,与网格的数量大致是成线性关系的。
现在,我对其中的一些问题进行解答,并对解法程序化提出新的问题。
Q:为什么可以抛弃一些复杂的逻辑,这样还能得出最终解吗?
A:之前说过,数织有一特点是确定性,即遵守游戏规则、依靠逻辑推理得出的格子必定是对的。

Q:如何进行循环执行?
A:一开始,对于每行每列都执行定理2化成的函数,对整个网格进行初始化。此后,对于每行每列循环执行定理3、4、5,且每次执行完,都应执行定理6。当所有数字被匹配后,即可认为程序结束,但此时还应再对每行每列执行一次定理4,即可将剩下的所有空白格转化为叉格,将网格填满。

现在的问题是,仅靠我们上面推出的定理,想要直接转化为函数,然后循环得出答案,是无法成功的。因为想要完成数织的程序解法,我们还需要解决另外一些问题。这些问题在人脑看来是非常容易解决的,而想要依靠机器实现,却还需要编程者大量的思考。那就是:各个待完成条如何分割,才能得出最好的结果?对于各个条的细分,又该如何储存?在黑格、连续条对数字的匹配中,是否要加上特殊的记号以避免一些错误?确定机制太过复杂,如何简化?
此外,还涉及到许多相关的工作。对于细节部分,以及如何完成一个数织的自动解答程序,本人以后将专门再写一篇博客,提出自己的想法。

后记:这个博客的主要想法是在半年前诞生的,当时沉迷于杀时间的数织游戏,甚至为之写出了一些攻略。最近国庆假期,不经意间翻出了当初的草稿,于是花时间写出了这篇博客。事实上,本人的专业水平(不论是数学还是计算机)都算不上高,在撰写博客的途中,也发现了许多的错误。在写定理时,突然发现半年前的自己推出的定理并不完整,于是花时间完善了定理,但事实上如今的状态已经不入以往(数织退坑挺久了),因此难免有所错漏。如果有时间,自然会写出实现程序的博客,当然,下一篇的技术含量肯定比这篇高多了。

数织游戏中的程序思维和数织的程序解法相关推荐

  1. java制作扫雷游戏中埋雷的难点_月薪30K程序员花了一个小时,用c++做出经典扫雷游戏 !...

    上次发过一个俄罗斯方块的游戏源码,由于是通过Easy X实现的,但是很多和我一样的新手,一开始不知道Easy X是什么,到时源码拿过去之后,运行报错,我这次发的扫雷, 也是通过Easy X实现,Eas ...

  2. 电影、电视和游戏中的帧率

    之前在即刻上看到一个搬运自极客湾的视频,知乎上也有更详尽的文字解释https://www.zhihu.com/question/21081976/answer/34748080.我这里再简单总结一下. ...

  3. 《从一到无穷大》中的程序思维

    这篇文章是最近几天看李永乐老师的<从一到无穷大>读书专栏而想到的一篇文章.在第一章 「做做数学游戏」 的简单数学,以及第二章 「空间.时间和爱因斯坦」 的拓扑学中(其实也是因为李老师目前只 ...

  4. ✨数织游戏✨:Python 制作的成本一毛钱却诚意满满的小礼物!!

    前文 今天就是七夕了,晓得你们有对象的或者正在追妹子的,肯定又在绞尽脑汁想买什么别出新裁的礼物,如果女生感觉你的礼物花心思了,那肯定是好感度倍增啊. 今天给各位分享一个用 Python 制作的成本一毛 ...

  5. 思维的惯性之游戏中buf管理

    http://blog.codingnow.com/2007/11/inertia_thinking.html 晚上在办公室晃荡,对面的同事在加班写代码.我凑上去看看在写什么.我向他了解了后明白了,大 ...

  6. 编写程序,实现猜数小游戏。

    编写程序,实现猜数小游戏.随机生成一个0~99(包括0和99)的数字,从控制台输入猜测的数字,输出提示太大还是太小,继续猜测,直到猜到为止,游戏过程中,记录猜对所需的次数,游戏结束后公布结果.程序运行 ...

  7. python画海绵宝宝_《1,2,3到动物园》数数书,适合幼儿园小班宝宝亲子共读,从游戏中了解数字的概念...

    大家好,我是神桐妈妈,最近开始陆续给几个幼儿园做了有关绘本方面的师资培训,然后又有新的幼儿园要有了嵌入式幼儿园绘本馆,有了绘本,有了书香氛围,又有孩子们开始接触绘本,每天拿着一本绘本带回家,和爸爸或者 ...

  8. 小程序[渲染层网络层错误] failed to load image_游戏中水的渲染技术

    水的渲染一直是图形学需要解决的问题,本篇博客主要介绍用傅里叶变换算法实现的水反射,也是一种假反射效果,目的是优化效率.实现的效果如下图所示: 使用傅里叶系数来表示地形高度的假反射效果,在我们开发的游戏 ...

  9. Andriod小程序——简单制作游戏中控制任务移动的轮盘

    Andriod小程序--简单制作游戏中控制人物移动的轮盘 说明 自定义自己的view继承于View类 重写onDraw()方法 当我们看到这个控件的时候那个样子,如图 完善onDraw()方法 重写O ...

  10. 小程序游戏中存在的内容安全风险

    受全球疫情影响,从2020年春节开始,小游戏用户开始激增.除了微信小程序,快手.豆音.百度等平台都推出了小游戏. 小游戏可以满足用户打发碎片时间的需求,也可以反哺产品的社交关系.所以相对于大容量的手机 ...

最新文章

  1. Qt自动填写表单并点击按钮,包括调用js方法
  2. 相似图片检测:感知哈希算法之aHash,dHash,pHash的Python实现
  3. pageX/Y, offset(), position(), scrollTop(), screenX/Y, clientX/Y, pageX/Y
  4. SQL点滴22—性能优化没有那么神秘
  5. 新闻事件报道重要性判定项目
  6. python结构化数据_python新手入门必备—— 使用json保存结构化数据
  7. apex英雄机器人探路者怎么玩_LOL有哪些英雄,是你怎么玩都玩不会的?
  8. ubuntu16.04下ROS操作系统学习笔记(九)Moveit
  9. 《Tableau数据可视化实战》——1.3节连接Excel文件
  10. 阿里旺旺垃圾消息分析及解决方案探讨
  11. L13 操作系统的这棵树
  12. 哥德尔不完全性定理 悖论式陈述 PM不可判定命题,和哥德尔可表达性定理——哥德尔读后之十八
  13. Java画UML类图
  14. 【allegro 17.4软件操作保姆级教程八】布线操作基础之三
  15. 计算机一级讲义,2017计算机一级MSoffice复习讲义
  16. 1-18 Collections工具类和StreamAPI流式编程
  17. 调查问卷如何制作图片调查
  18. OVAL验证框架帮助文档
  19. 编程:5 位评委对参赛选手进行打分,将所有的打分结果存储在对应类型的数组中,将所有评分结果 去除一个最低分,去除一个最高分,然后获取剩余 3 位评委的平均分数为选手的最终得分。设计程序, 用键盘输入
  20. 《互联网软件应用与开发(网络程序设计)》

热门文章

  1. 英语六级口语 计算机,关于四六级口语,你所要知道的一些事
  2. 广和通L610_ADP对腾讯云通信笔记——02(STM32F411控制L610)
  3. 2023校招美团笔试
  4. 高中计算机课听课记录表,初中信息技术课听课记录中学信息技术评课笔记
  5. mysql数据库之基本函数,列属性,数据库管理
  6. iot会议纪要 20180105
  7. matlab串联矩阵如何表示,MATLAB串联矩阵
  8. (error) MOVED 4848 172.26.158.xxx:xxxx
  9. 什么是项目管理?怎么管?(一)
  10. 2021SAAE上海第七届教育装备展览会