欢迎光临散文网 会员登陆 & 注册

《用Python实现原神中算法》文字版

2023-03-31 08:52 作者:英雄哪里出来  | 我要投稿

       第一次在B站上发文章,可能排版什么的,不是很好看,也希望大家多多包涵。

       由于 上周发的视频 内容较难,看到很多同学在 评论区弹幕 里面说想要这个视频的文字版,所以想了想,还是给大家写出来了,主要是代码的内容以及详细的注释,当然也希望大家自己去实现一下代码,不要光听我说,听见了没?听见了。

       早上四点起来写的,比较仓促,有什么写错的地方,也请在评论区指出,或者有什么问题,也可以在评论区提问,我看到后都会进行回复。本文主要包含四个内容:

抽卡算法状态机图香菱火圈拓扑排序


抽卡算法

        当然,我实现的只是一个最简单的版本,原神怎么实现的,我不可能知道,只是出一个大概的算法框架,给对这方面有疑惑的朋友一点灵感,你也可以自己去设计这方面的算法。

1、抽一次

抽卡算法 - 抽一次

第 3 行,定义一个 chou 函数,cishu代表目前是上一次五星限定角色抽完以后的第几次抽卡,wai代表这期间歪了几次,取值为 [0, 1]。

第 4 - 5 行,如果次数小于等于 73 次,概率为 0.6%,这里统一乘上了 100。

第 6 - 7 行,如果次数等于第 90 次,概率为 100%,说明必定出五星。

第 9 行,是一个一次函数,代表从 73 抽以后,每抽一次,出五星的概率增加 6%。

第 10 - 11 行,如果随机出来的概率,不在边界概率 p,那么代表不是五星,可能是一些辣鸡的武器,返回 2。

第 12 - 13 行,否则,一定出五星,这时候如果歪过一次,则这次一定不歪,返回 0。

第 14 行,如果没有歪过,那么 50% 是歪,50% 不歪,返回 0 和 1 中随机的一个数即可。

2、十连三金需要的抽卡次数

抽卡算法 - 十连三金

第 21 行,shilian 代表已经十连的次数,初始化为 0。

第 22 行,cishu 代表第几抽。

第 23 行,wai 代表歪过几次。

第 26 行,x 代表本次十连中有多少个五星角色。

第 27 - 28 行,连续抽 10 次。

第 29 - 32 行,代表抽到了五星限定角色,则次数和歪的次数都要重置。

第 33 - 36 行,代表歪了,则歪的次数加一,次数重置。

第 38 行,代表抽到奇奇怪怪的东西,次数+1。

第 39 行,如果有 3 个五星角色,则输出是第几次 十连 的时候达到的这个盛况。 


状态机图

       这里主要涉及到的知识点是图的概念,并且讲到是一个状态机,利用邻接矩阵来存储图,并且通过随机函数进行状态转移,从而实现随机序列的生成。

1、C语言实现

无限动画 - C语言实现

第 4 - 9 行,定义的是一个C语言中的二维数组,其中第 i 行 第 j 列的数值,代表了第 i 号节点和第 j 号节点的有向关系,当且仅当 adj[i][j] 为 1 时,第 i 号节点 能够走到 第 j 号节点。

第 11 - 13 行,定义了一个函数,用于输出第 aniId 号节点的值。

第 17 行,pos 代表当前处于哪个节点。

第 18 行,定义一个死循环,让程序可以无限进行输出。

第 19 号,随机生成下一个节点的编号 x。

第 20 - 22 行,如果 adj[pos][x] 为 0,代表 pos 不能直接走到 x,那么 x 需要重新随机 ,所以这里采用了 while 循环的方式;如果 adj[pos][x] 为 1,代表 pos 可以直接走到 x 这个节点,则跳出循环。

第 23 行,输出 x 这个节点(播放 x 号动画)。

第 24 行,将 x 赋值给 pos,代表一次迭代,下次就是从 x 开始往后随机。

2、Python实现

无限动画 - Python实现

第 2 行,引入 random,用于做随机数生成。

第 4 - 9 行,定义一个 Python 2维列表,含义和 C语言 类似。只不过C语言用的是花括号,Python用的是方括号。

第 11 - 12 行,定义了一个函数,用于输出第 aniId 号节点的值。

第 16 行,类似 C语言中的 main 函数。

第 17 行,pos 代表当前处于哪个节点。

第 18 行,定义一个死循环,让程序可以无限进行输出。

第 19 号,随机生成下一个节点的编号 x。

第 20 - 21 行,如果 adj[pos][x] 为 0,代表 pos 不能直接走到 x,那么 x 需要重新随机 ,所以这里采用了 while 循环的方式;如果 adj[pos][x] 为 1,代表 pos 可以直接走到 x 这个节点,则跳出循环。

第 23 行,输出 x 这个节点(播放 x 号动画)。

第 24 行,将 x 赋值给 pos,代表一次迭代,下次就是从 x 开始往后随机。

大体上,和C语言的语句结构,还是非常相似的。


香菱火圈

香菱火圈

第 6 行,获取标准输出的句柄。

第 7 行,记录一个时间 t。

第 8 行,定义一个循环。

第 9 行,定义火圈的位置。

第 10 行,定义香菱的位置。

第 11 行,定义火圈的半径为 R。

第 12 行,利用余弦函数,计算香菱火圈的 x 坐标,由于光标的 y 轴是 x 轴的两倍,所以这里火圈的 x 轴半径是 2R。

第 13 行,利用正弦函数,计算香菱火圈的 y 坐标。

第 14 行,清空屏幕,避免火圈残留。

第 15  - 16 行,设置光标当前位置,并且打印 "香菱"。

第 17 - 18 行,设置火圈当前位置,并且打印 "火圈"。

第 19 - 20 行,FALSE 代表将光标进行隐藏。


拓扑排序

1、建图的过程

拓扑排序 - 建图

首先,定义邻接矩阵,代表有向图的点和边的关系。

visited 数组代表当前这个节点是否被访问过。

degree数组代表当前这个节点的入度(有多少条边指向它)。

遍历任意两个点,如果 adj[i][j] 为 1,则给 j 的入度 加 1。

2、拓扑排序的过程

拓扑排序

整个过程就是迭代去找 尚未被访问 且 入度为 0 的点,存储到 u 中:

找点

如果找不到则跳出循环,否则标记 已访问

标记

然后将它转换成字母后进行输出:

输出

最后将 u 对应所有出边的 端点 的入度减一,此所谓删边的操作:

删边

重复迭代,这个拓扑排序的过程就完成了。

       好啦,如果你想学习更多算法,可以 关注公众号:夜深人静写算法回复 666 ,获取 算法学习路线。有什么相关问题,也可以从公众号找到我的联系方式进行咨询,或者从这个链接直达(无法放站外链接,所以需要自己复制粘贴到浏览器打开):https://ufbva3m5zn.feishu.cn/docs/doccnIQ95UPr5yabjQg2bFHl79f#


《用Python实现原神中算法》文字版的评论 (共 条)

分享到微博请遵守国家法律