目录
一,独立游戏
游戏最常见的划分方式就是网络游戏和单机游戏,独立游戏的概念我也不是很清楚,应该和单机游戏差不多吧,但是感觉独立游戏更小,场景单一,但是耐玩。
比如一笔画,我愿称之为独立游戏,但是单机的植物大战僵尸,我觉得不是。
游戏吸引人的关键之一,在于求胜欲。
为了胜利,有很多方法,可以砸钱,可以好好学数学和算法,掌握高深理论,也可以反复磨炼,提升手速和技巧。
我为什么只喜欢独立游戏?
第一,它不需要砸钱,只需要技巧。
第二,它的进度条是和时间解耦的,我可以玩到37关之后卸载,五年之后再继续玩第38关,这种事情我经常干,尤其是学了某种新算法之后。
我偏爱哪种独立游戏?
我喜欢的独立游戏,是那种只有思维技巧,没有操作技巧的游戏,比如一笔画,华容道,我可以盯着一个画面三分钟,然后执行下一步操作。而永不言弃这种音乐游戏,神庙逃亡这种跑酷游戏,也挺好玩的,但不属于我的真爱。
PS:扫雷也是我的真爱,这个如果不追求极致的速度,就不需要操作技巧,只需要思维技巧。
二,独立游戏的通用模型
之所以建立这个模型,主要有两个技术积累:
一是我的本科毕设作品,棋类游戏的通用框架,不过这个主要是开发框架,而我现在一边写博客一边建立的,是思考攻略的通用框架,
二是拟阵,受到了先辈的鼓舞,对建立通用模型来描述问题的统一求解方案有了更多的兴趣和信心。
模型内容:
1,状态空间
对于俄罗斯方块,每一个肉眼可见的画面,就是一个状态,而空荡荡没有一个格子的画面,就是初始状态。
对于纪念碑谷,冒险者的位置,和所有机关的状态,共同构成一个游戏状态。这个游戏的高明之处在于,在绝大部分场景下,状态空间是多维空间中的一条曲线,冒险者的位置即可确定整个状态。
总之,游戏会有很多状态,而独立游戏往往只有有限多的状态。
2,状态转移
独立游戏往往有1个初始状态,1个或多个目标状态,游戏的目标就是找到从初始状态到达目标状态的方法。
独立游戏往往只允许依次进行一种或多种操作,不允许同时叠加操作,而每次操作,都是一次状态转移,最终转移到目标状态。
3,状态空间 VS 解空间,解点 VS 解路径
算法中的解空间是每个可能的解就是空间中的一个点,算法的目标是找到一个点。
本文的状态空间是操作过程中的每一个中间状态,所以解不是一个点,而是一条路径。
4,状态空间的基本结构
状态空间的结构,是我们对游戏进行划分的重要依据。
(1)是有向图还是无向图
一般有向图是有死亡状态的,比如推箱子把箱子推到了角落就再也出不来了,而无向图肯定是没有死亡状态的,比如纪念碑谷,是不存在到了某个状态就输了的情况的。
(2)连通性
首先初始状态和目标状态当然是连通的,其次根据连接的情况,可能会有一些经典的结构,比如直线型,放射型,强连通型,环形等等
分析结构有助于我们发现下一跳,和其他手段结合起来可以推测出一些中间状态,
我们确信或者几乎确信这些状态是必经状态,或者至少会有一条解路径经过这些状态,那么我们就成功的把问题分解为若干小问题了。
(3)环
有向图如果有环,至少可以确定环内转移操作是没有风险的,无向图如果有环,那也是我们分析状态空间结构的重要依据。
而有向图如果有无向环,即从一个点到另外一个点有两条不同的有向路径,那我们就知道解并不是唯一的。
(4)其他图论特征
常见的图论特征包括出入度、二分图等等
出入度主要就是关注出度或者入度特别高的点,二分图主要就是关注,如果整个图就是一个二分图加一条线段连接起来,那么这条线段就是必经之路。
三,回合制游戏
1,重构说明
2025年6月1日,刚好是儿童节这天,我在思考“回合制游戏”这个概念,关于贪吃蛇是不是回合制游戏,有了一些想法。
当我找地方把这些想法写下来的时候,看到了很久以前写的本文第一章《独立游戏》和第二章《独立游戏的通用模型》,豁然开朗。
(1)一笔画、华容道、扫雷其实就是回合制游戏,植物大战僵尸、永不言弃、神庙逃亡其实就是非回合制游戏。
(2)可以用数学和算法去攻克的,一般也是回合制游戏。
(3)只有思维技巧,没有操作技巧的游戏,其实就是回合制游戏。
所以,第一章和第二章所描述的独立游戏可能和其他人理解的独立游戏并不一样,我这个或许应该叫回合制独立游戏。
2,回合制的定义
满足下列条件的游戏即称为回合制游戏
(1)存在常数n表示玩家数
(2)存在一个定义好的集合A,表示所有游戏状态的集合,状态的其中一个属性是轮到哪个玩家执行回合,我们把从状态中提取玩家id的函数称为f函数
(3)对于A中的任意一个状态a,轮到玩家f(a)执行回合,存在一个集合g(a),表示玩家f(a)可以执行的操作集。
(4)对于操作集g(a)中的每一种操作b,存在A中的一个状态c,使得状态a经过操作b之后一定会变成状态c,我们把这个函数记作h(a,b)=c
3,常见的回合制游戏
(1)所有的棋
(2)绝大部分桌游,包括狼人杀(发言的内容也是在一个确定的集合中选择,只是这个集合中有无限多元素)
(3)各种麻将、各种扑克
(4)部分单人游戏,如reky
4,常见的非回合制游戏
(1)抢速度的桌游,比如德国心脏病
(2)连续运动的单人游戏,比如永不言弃、神庙逃亡
5,回合制的特征
一般来说,单个回合的时间限制都比较宽松,除了专业打比赛的,平常我们下棋、打麻将根本不会去计时。
换句话说,单个回合的时间上限一般都比较多,至少有10秒。
6,回合制的相对性
像相对论一样,经典理论的概念具有相对性。
比如贪吃蛇,其实是符合回合制的定义的,但是由于一个回合只有0.3秒左右,所以不符合回合制的一般特征,让人感觉像是一种实时类型的游戏,而不是回合制类型的。
我在回合制贪吃蛇里面实现了真正的回合制,单个回合不设置时间上限,可以看出来玩法逻辑是一样的。
四,结构化游戏
1,重构说明
在写了第三章《回合制游戏》之后不久,我又看到我多年以前写的《结构化游戏》,于是我再次豁然开朗,原来我第三章中所谓的“回合制独立游戏”,更准确的叫法是“回合制结构化游戏”。
2,结构化游戏
结构化游戏指的是状态是结构化数据的游戏。
五,启发式游戏
在启发式搜索-优快云博客一文中,我提到经典搜索和启发式搜索的区别。
同样的,像数独这种游戏,更偏重于每一步都能得到确定的信息,目标也是非常具体的甚至唯一的,而像华容道这种游戏,更偏重于一种抽象的策略,目标也是相对不那么具体的。
所以,我把它们分别称为确定式游戏、启发式游戏。
六,启发式策略
确定式游戏往往有确定式策略,甚至可以直接编程求出来。
而启发式游戏可以既有确定式策略,又有启发式策略。
在学会了C++设计模式中的模板方法模式23种设计模式_设计模式23模式介绍_csuzhucong的博客-优快云博客之后,我突然思如泉涌,于是写了本文,把思路整理了下来。
我借用了模板方法模式,建立了独立游戏的通用模型,
有了清晰了模型之后,启发式策略就因运而生。
七,回合制游戏的策略综述
1,策略模型
在状态空间的基础之上,策略可以分为三类:
(1)全局状态分析策略
比如什么状态是死亡状态,什么状态是必经状态,以此为依据进行分解问题的策略就是全局策略。
全局策略是基本具有马尔可夫性质的,策略输出是下一跳。
(2)局部启发式策略
局部启发式策略,告诉我们每一个阶段的小目标是什么。
相比于具有马尔可夫效应的全局策略,局部策略是和当前状态强相关的,基于特征推导最优策略,得到接下来若干次操作的一个大概行动方向。
局部启发式策略分为三部分,一是我们需要什么辅助信息?二是怎么样启发式地推算出这个信息?三是这个辅助信息如何指导我们找到解?
有些游戏,需要什么辅助信息是比较明显的,有些游戏甚至连这个都需要天赋才能感悟出来。
(3)单点处理策略
单点处理策略,告诉我们在遇到某种强特征状态时,对应的比较具体的若干次操作是什么。
2,模型实践
我以水排序谜题水排序谜题_水排序游戏推算java_csuzhucong的博客-优快云博客为例,实践并完善了这个模型。
我按照这个模型把汽车华容道汽车华容道_汽车华容道580题目合集-优快云博客稍微修改了一下,其中的策略都能对应上本模型。
八,马尔可夫游戏、一致性算法
1,马尔可夫性质
即未来状态仅依赖于当前状态,而与过去状态无关
2,马尔可夫占比
理论上,五子棋、围棋是马尔可夫的,但是实际上,最后几处落子位置是包含了局部策略的,所有落子位置则包含了更高层面的一些策略、下棋风格等等。
于是,我用马尔可夫占比来粗略的表示一个游戏中,马尔可夫性质占了多少比例。
单人博弈:
独立钻石棋 100%
智力扣、孔明锁 100%
魔方、魔金 80%
数独 80%
扫雷 60%
多人博弈:
五子棋、围棋 80%
象棋 60%
扑克、麻将 20%
关于这些数据,我做一些说明
(1)只是大概的估算,可以理解为分为0颗星到5颗星
(2)魔方之所以不是100%,是因为有小环问题,参考下文《非一致性算法的小环》
(3)数独和扫雷比较类似,之所以不是100%,是因为正常玩法中,是需要记住部分搜索空间已经搜过,暂时得不出有效结论,需要持续更新这个已搜空间。
(4)五子棋、围棋、象棋不是100%,理由上面说过了,需要分析对方的策略、下棋风格等等。
(5)扑克、麻将不是100%,因为需要记牌、推理对方的手牌。
3,回合制游戏的非随机算法
(1)对于完全信息的单人博弈,一个非随机算法指的是,输入任意一种当前状态和固定的最终状态集,输出一个操作序列。
例如F4问题:输入一个4位数,每次只能对其中一位进行加1或者减1,使得变成每一位都相同的4位数。
F4问题的算法一:依次对第2/3/4位进行操作,使得和第一位相同。
运行示例:输入当前状态3684,最终状态集是{1111,2222,3333,4444,5555,6666,7777,8888,9999},输出的操作序列用状态序列来表示就是3684 3584 3484 3384 3374 3364 3354 3344 3334 3333
所以,F4问题的算法一就是一个非随机算法。
(2)对于非完全信息的单人博弈,一个非随机算法的输出是一个有向图
比如扫雷,我们的策略是有确定的格子就打开或者标记雷,没有确定的格子就按照概率去选,如果打开一个格子,那么接下来的状态取决于雷的随机分布,对于不同的情况我们又有不同的应对方法。
(3)对于多人博弈,一定是没法获取完全信息的,因为不知道对方会怎么选择,所以非随机算法的输出也是一个有向图。
4,回合制游戏的微随机算法
人脑中的算法,往往会抓住重要规律,忽略次要细节,所以会形成微随机算法。
F4问题的算法二:首先选择锚点,选择数字居中,即既不是最大也不是最小的那一位,如果没有居中的则在四位里面随机选一个,如果有2个居中的则在2位里面随机选一个。选择好锚点之后,依次把各个位上的数字调整成锚点数字。
运行示例:还是以3684为例,这个微随机算法的输出就是2种序列,要么是3684 4684 5684 6684 6674 6664 6665 6666,要么是3684 4684 4584 4484 4474 4464 4454 4444。
可以看出,无论是哪个序列,比算法一的输出都要快。
我之所以凭空构造出这么一个F4问题,还凭空构造出2个算法,纯粹是为了方便精准表达。
实际上,三阶魔方的层先法就是一个微随机算法,虽然都是层先法,即使都以黄色面作为复原的第一面,那么黄色面的4个棱先复原哪个棱呢?很多人就是看到哪个复原哪个,这本质上就是一种随机行为。
5,马尔可夫游戏的一致性算法
如果一个游戏的马尔可夫占比是100%,对应的一个算法是非随机算法,那一定存在一个一致性算法。
所谓的一致性,以完全信息的单人博弈为例,如果输入a状态输出的操作序列对应的状态序列是abcdefg,那么输入b状态输出的操作序列对应的状态序列则一定是bcdefg。
对于非完全信息的单人博弈、所有的多人博弈,也是存在一致性算法的,只是描述起来更繁琐。
只有非随机算法才有可能是一致性算法。
6,非一致性算法的小环
一个非一致性算法,输出当前状态a和目标状态k,输出的结果可能是这样:
这里面是存在比较小的有向环的。
在实际用这种带环的算法时,我们其实是会自动记录额外的辅助信息,避免陷入循环。
比如我们在用层先法复原三阶魔方时,就是这样一种情形。
7,马尔可夫算法、非马尔可夫算法
以麻将为例,可以永远只根据当前状态决定怎么打,这就是一种马尔可夫算法。实际上很多初学者就是这样的。
麻将也可以使用非马尔可夫算法,即我除了知道当前状态,我还知道多方的操作历史,这样有时候就能推断出对方是听胡筒子牌还是条子牌了。
魔方同样也有马尔可夫算法和非马尔可夫算法。
对于这种既有马尔可夫算法,也有非马尔可夫算法的游戏,我们怎么样保证玩家采用马尔可夫算法呢?
以魔方为例,可以搞一个百人合作挑战,500个会用层先法复原魔方的人,用一个小时讨论出完整的马尔可夫算法,当挑战正式开始之后,所有人全程不能做任何交流,每个人依次执行1次操作,即对任意面顺时针或者逆时针旋转90度,如果中途或者刚好最后一人复原魔方,则挑战成功。按照我的估计,500应该是够的。
一个人复原魔方有马尔可夫算法和非马尔可夫算法,而这种多人不交流的接力完成挑战就一定是需要马尔可夫算法了。
实际上这个挑战很难,因为有太多人,也有太多细节,只有有1个人忽略了1个细节,就可能走入“非一致性算法的小环”,虽然环还可以再走出来,但是多来几个环就很容易耗完步数。