精华内容
下载资源
问答
  • 大家好,我是欢聚时代高扬,这次跟大家分享内容是深度学习在游戏AI中应用这样一个话题。NPC驱动粗分可以分成低级、中级、高级、特高级,这样几个类别。当然,按照其它方式分也未尝不可,这里主要是针对...
  • 深度分析游戏随机概率

    千次阅读 2017-10-30 14:50:06
    这段时间公司开发的游戏上线测试,许多玩家在抽卡时抱怨脸黑,很难抽到所需要的卡牌,而又一部分玩家反应运气好能连着抽到紫卡,检查了下随机相关逻辑代码,并没有找出问题所在,玩家运气好与坏只是觉得真可能是...

    1-(28)500.jpg

    这段时间公司开发的游戏上线测试,许多玩家在抽卡时抱怨脸黑,很难抽到所需要的卡牌,而又有一部分玩家反应运气好能连着抽到紫卡,检查了下随机相关逻辑代码,并没有找出问题所在,玩家运气好与坏只是觉得真有可能是概率原因。

    测试开服了几天之后,需要开放某个限时抽卡活动,在内部测试时,我们发现玩家反应的问题在限时抽卡中格外明显,尤其是其中最主要的一张稀有卡牌,猜测因为限时抽卡库配置的种类较少,然后就拿该活动来检查了下我们游戏随机机制问题。

    5%概率?20次出现一次?

    大部分游戏策划使用权值来配置随机概率,因为权值有个好处就是可以在增加随机物品时,可以不对之前的配置进行更改,比如:白卡 30,蓝卡 10,紫卡 10,转为概率即是:白卡 60%,蓝卡 20%,紫卡 20%。

    而上述限时抽卡的例子中,我们的权值配置是5和95,模拟50000次随机(使用系统随机函数,如C的rand函数,Python的random库)得到如下结果:

    rnd1.jpg

    上图绘制的是权值为5的卡牌的随机状态,红色的图是分布图,X轴是出现的次数,Y轴是相同卡牌再次出现的间隔。绿色的图是分布概率图,X轴是间隔数,Y轴是概率。按策划的想法,5%概率应该等同于20次出现一次,那上图很明显并不满足20次出现一次出现规则,实际间隔从近到远呈下坡形状分布,就是说相邻的概率最大,间隔最大超过160,这与玩家所吐槽的抽卡体验是一致的。但50000次随机总共出现了2508次,从统计的意义上来说又是符合5%概率的。所以这个问题,究其原因就是所谓的概率是统计意义上的还是分布意义上的问题。

    最原始的实现

    我用列表里取元素的方式来模拟20次出现一次,为了方便比较异同,直接随机的方式我也贴上相关代码。

    1
    2
    pool = [0]*5 + [1]*95
    result = [random.choice(a) for in xrange(N)]

    上面是直接随机的方式,只保证5%概率。

    1
    2
    3
    4
    5
    6
    7
    8
    pool = []
    result = []
    for in xrange(N):
    if not pool:
    pool = [0]*1 + [1]*19
    random.shuffle(pool)
    result.append(pool[-1])
    del pool[-1]

    上面是打乱列表,然后依次取元素的方式,保证20次出现一次,而5%概率则是隐含在内的,生成效果如下图。

    rnd2.jpg

    该图明显跟第一个实现的图不一样,上图表明了间隔基本上是落在[0, 40]的区间内,并且均匀分布在20那条蓝色对称线附近。这个才是最终想要的随机的效果。红色的线是正态分布曲线,是不是很相似?后面我会讲到。

    眼尖的会发现在第一个实现中我用的pool是[0]*5 + [1]*95,而第二个实现中我用的是[0]*1 + [1]*19。

    这里20次出现一次并不等同于100次出现五次,也是从分布的意义上来说的,100次出现五次是存在5次连续出现的可能。

    针对策划的配置,我们需要进行预处理,怎么处理?GCD啊~,5和95的最大公约数是5,所以在第二个实现的代码中我直接使用了1和19。

    但这里有个问题,一般策划配置的随机库中肯定有多个物品。权值如果配置的比较随意的话,很可能就导致GCD为1,这样想要实现XX次出现一次就不可行了。比如刚才的权值配置5和95,再加一个权值为11的话,就只能实现111次出现5次。

    所以这两种依赖列表的随机方式并不适用,一是需要维护的列表内存会比较大,二是对策划配置方式有过多约束。

    更通用更优美的实现

    20次出现一次是以20为标准周期,当然不能每次都是间隔20出现,这样就太假了,根本没有随机感受可言,为了模拟随机并可以控制一定的出现频率,我选择正态分布来进行伪随机分布生成,原因是分布会更自然一些。

    rnd3_Normal_distribution.jpg

    关于正态分布这里就不详细描述了,只需关心分布的两个参数即可,位置参数为μ、尺度参数为σ。根据正态分布,两个标准差之内的比率合起来为95%;三个标准差之内的比率合起来为99%。

    rnd4_normal_sigma.jpg

    用上面的例子来定下参数,μ=20,σ=20/3,这样每次按正态分布随机,就能得到一个理想的随机分布和概率区间。

    C语言标准函数库中只有rand,如何生成符合正态分布的随机数可以参见WiKi上的介绍。这里我直接使用Python中random库中的normalvariate函数,当然gauss函数也是一样的,官方文档上说gauss函数会快些,StackOverFlow上说gauss是非线程安全函数,所以会快。我自己简单测试了下,在单线程情况下,gauss是会快些,但只是快了一点点而已。

    首先,我直接生成权值为5的卡牌的间隔,检验下正态分布的随机效果。

    1
    2
    3
    NN = int(N*0.05)
    mu, sigma = 20, 20/3.
    delta = [int(random.normalvariate(mu, sigma)) for in xrange(NN)]

    rnd3.jpg

    这图是不是比第二个实现的图更好看一些,分布也更平滑一些呢。OK,接下来就是替换旧的随机算法了。

    细节和优化

    刚才说了随机库中会有很多物品,都需要按照各自的权值随机,并各自出现频率符合正态分布。下面我们来说说细节。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    wtp = [1.*x/sum(wt) for in wt]
    result = []
    p = [random.normalvariate(1./x, 1./x/3.) for in wtp]
    for in xrange(N):
    minp = 1.e9
    minj = -1
    for j, pp in enumerate(p):
    if pp < minp:
    minp = pp
    minj = j
    result.append(minj)
    for j, pp in enumerate(p):
    p[j] -= minp
    p[minj] = random.normalvariate(1./wtp[minj], 1./wtp[minj]/3.)

    这里我使用了统一的随机种子,随机测试了500万次后,所得的结果与多个随机种子差别不大。

    简单解释下代码:初始化对所有物品按权值进行正态分布随机,每次取位置最小值的物品(也就是最先出现的),然后其它物品均减去该值,被取出的物品再单独进行一次正态分布随机,再次循环判断位置最小值。

    这里,每次都需要对所有物品进行求最小值和减法,都是需要遍历的运算,我们可以有如下优化。

    例如:(1,3,4) -> 取1减1, (0,2,3) -> 随机1, (1,2,3),其实我们只是为了保持各物品之间位置的相对顺序即可,将对其它物品的减法变成对自己的加法,操作量级立马从O(N)缩为O(1) 。

    如上面的例子:(1,3,4) -> 取1, (0,3,4) -> 随机1加1, (2,3,4),这样的操作不会改变物品序列的正确性。

    熟悉最小堆的朋友,将查找最小值优化到O(1)应该也没啥问题吧。

    1
    2
    3
    4
    5
    6
    7
    8
    wtp = [1.*x/sum(wt) for in wt]
    result = []
    p = [(random[i].normalvariate(1./x, 1./x/3.), i) for in wtp]
    heapq.heapify(p)
    for in xrange(N):
    minp, minj = heapq.heappop(p)
    result.append(minj)
    heapq.heappush(p, (random[minj].normalvariate(1./wtp[minj], 1./wtp[minj]/3.)+minp, minj))

    测试结果

    问题分析和算法实现就到这了,替换进我的游戏里看看什么效果,我已经迫不及待了。

    物品测试权值序列[10, 30, 50, 110, 150, 200, 250, 500],随机测试500万次。

    rnd_rand.jpg

    第一个随机实现

    第一个实现是只符合统计要求,不符合分布要求。

    rnd_weight.jpg

    第二个随机实现

    第二个实现中对权值序列进行了GCD,可以看到只有绿色是符合分布要求的,而蓝色和青色退化成第一种实现。

    rnd_normal.jpg

    基于正态分布的随机实现

    完美!

    其它

    当然,实现20次出现一次这样的分布伪随机还有其它方法,比如保存一个计数器,每随机一次就加到计数器上,当计数器的值大于或等于1,即必然出现。但这种实现需要计数器,每个玩家每个随机库每个物品都需要这么一个计数器字段,空间上实在太大了。

    关于随机种子,除非是全服竞争类资源,不然最好每个玩家有各自的随机种子,否则会造成体验上的误差,比如抽卡、关卡掉落等这些只针对玩家自身的系统随机。服从正态分布的全局随机序列,不同玩家任意取走序列中一段或者一些值,就可能导致对于每个玩家而言,各自取出的随机序列不再服从正态分布。

    结束

    我只能感叹Python的库太强大了,matplotlib绘制出来的图形也挺漂亮的,感兴趣的童鞋可以查阅用Python做科学計算

    展开全文
  • 针对目前连连看游戏路径查找算法不够精练问题,基于深度优先搜索和栈思想,设计了一个全新路径查找算法。别于其它查找路径与记录路径轨迹需要分两步进行算法,本算法判断两个点之间如果存在路径,则同时会记录...
  • 数独游戏的深度优先遍历解法

    千次阅读 2015-02-17 17:45:13
    数独 是一种逻辑性数字填充游戏,玩家须以数字填进每一格,而每行、每列和每个宫(即3x3大格)齐1至9所有数字。游戏设计者会提供一部份数字,使谜题只有一个答案。一个已解答数独其实是一种多了宫限制...

    数独
    数独简介:
    数独 是一种逻辑性的数字填充游戏,玩家须以数字填进每一格,而每行、每列和每个宫(即3x3的大格)有齐1至9所有数字。游戏设计者会提供一部份的数字,使谜题只有一个答案。一个已解答的数独其实是一种多了宫的限制的拉丁方阵,因为同一个数字不可能在同一行、列或宫中出现多于一次。
    深度优先遍历算法:
    学过数据结构的同学都知道,深度遍历算法最开始是为解决树的遍历发展出来的,而后用于图的遍历。就像走迷宫似的,走到一个点之后发现不能满足当前条件,于是必须得退回到前一个状态继续探索迷宫。主要思想过程我就不用再说了,本科期间大家已经很熟了。
    算法过程分析:
    先假设已经生成了一个数独谜题,例如上题中的数独谜题,先填第一行第二列中的空格,首先遍历横排,再遍历竖排,最后遍历方格。如此循环,如果碰到数字相同的情况,则需要换另外一个数字,如果1到9的全部数字情况都不满足的情况下,则需要返回到前一个状态,如果前一个状态还不满足,则继续返回知道满足在继续遍历。
    算法代码:

    #include <iostream>
    using namespace std;
    char map[10][10];
    struct
    {
        int h;
        int l;
    
    }cor[90];
    int count;
    bool fit(char number,int x,int y)//判断是否符合填入条件
    {
        int i,j;
        for(i=0;i<9;i++)
            if(map[x][i]==number||map[i][y]==number)
            return false;
        int kh=x-x%3;
        int kl=y-y%3;
        for(i=kh;i<kh+3;i++)
            for(j=kl;j<kl+3;j++)
            if(map[i][j]==number)
            return false;
        return true;
    }
    void search(int x)
    {
        int i,j;
        if(x>count)//遍历成功则打印
        {
            for(i=0;i<9;i++)
            {
                for(j=0;j<8;j++)
                    cout<<map[i][j]<<" ";
                    cout<<map[i][8]<<endl;
            }
            return ;
        }
        for(i=1;i<=9;i++)
        {
            char number=i+'0';
            if(fit(number,cor[x].h,cor[x].l))
            {
                map[cor[x].h][cor[x].l]=number;
                search(x+1);//遍历下一个?处的数字
                map[cor[x].h][cor[x].l]='?';//需要改变到前一个状态
            }
        }
    }
    int main()
    {
        int i,j;
        while(true)
        {
             count=-1;
            for(i=0;i<9;i++)
            for(j=0;j<9;j++){
                cin>>map[i][j];//用?号代替没有填入数字的空格
                if(map[i][j]=='?')
                {
                    ++count;//记录空格的数量
                    cor[count].h=i;//记录空格的行
                    cor[count].l=j;//记录空格的列
                }
            }
            search(0);//开始遍历
            cout<<endl;
        }
        return 0;
    }
    

    测试事例:
    谜题就用上图出现过的数字
    这里写图片描述

    测试后:

    这里写图片描述

    测试成功!!!!

    展开全文
  • 我第一个项目做了8年,作为一个一般本科学校毕业人来说,一个共有通病,就是认为坚持就是胜利,认为天道酬勤,这些观念在我第一个项目中体现淋漓尽致,8年,日本人都被打跑了,我项目却死了。后来我加入...

    其实我写这些文章,最想写的就是这一篇,最不想写的也是这一篇,这一篇文章记录了我如何的从入门到放弃。
    我个人是做游戏开发的,从pc mmo,到手游。我05年入行,至今做了15个年头。我第一个项目做了8年,作为一个一般本科学校毕业的人来说,有一个共有的通病,就是认为坚持就是胜利,认为天道酬勤,这些观念在我第一个项目中体现的淋漓尽致,8年,日本人都被打跑了,我的项目却死了。后来我加入一家手游公司,亲眼目睹了,一款现象级产品的诞生和公司迅速的成长,彻底的颠覆了我的人生观。天道并不酬勤。
    说了这么多废话,我到底要说什么,游戏的开发,风险性特别大,成功率特别的低,而且非常的难以把握,可以统计一下,做成一款大成项目之后,再做一款大成项目的的概率有多大?(这里我们只讨论制作人,不讨论代理),可以说风毛菱角,几乎没有。也就是说,从一款成功项目中总结的方法论并不具有可操作性。整个行业都在寻求一种可控的方式能增大游戏的成功概率,其实本质的问题就是从成功或者失败的项目中建立模型来指导在研项目。或者说对已上线项目进行分析和提升。目前的很多决策大部分是基于以往的经验积累和个人的情绪化判断。
    我之所以想到深度学习落地到游戏研发是因为看到巨人网络收购以色列公司 playtika.playtika 这家公司他本身并不开发游戏,他的主要工作是收购已经运营一段时间的游戏,并对这些游戏做提升。提升的方法就是对他的运营数据做分析建模,做游戏的都知道,游戏的几个核心数据,留存,付费率,roi,如果能够及时的发现用户的流失倾向做对应的安抚和召回,如果能发现潜在的付费用户做付费引导,如果能够预测用户的付费深度,做相应的挖掘。就能提升游戏的整体表现。
    首先我要提醒的是,初学的朋友不要把大数据和神经网络搞混了,虽然他们有很多的相关性但是完全不是一回事,我在前期就犯了这个错误,大数据是一个很成熟的产业有很多的体系和分支,一入豪门深似海,当时我一头扎进hadoop的生态,一顿摸索和折腾,然后2个月过去了,发现和机器学习没有鸟关系。另外我要给初学的朋友一些建议,就是深度学习领域也有很多的流派和框架,就和编程有很多语言一样,除非你有很特殊的需求,不然最后选最大众化的,因为从统计学来讲,发展最好的框架,肯定不会太差,是吧。再有就是这些框架的学习资料也最多,所以我推荐用tensorflow.另外是2.0版本,千万不要下载个1.0的,版本差别很大,并不兼容。这个一定要谨记。
    说了这么多,我为什么会放弃呢,这要说我的初衷,我想让深度学习在游戏开发中后期能发挥作用,提升游戏的成功概率,前面我讲到的以色列公司,是个好的例子,但是他的具体运作我并不清楚,但是国内有一家公司,深极智能科技,前段时间,被字节跳动收购了,让我还是很欣喜的,毕竟有个公司做着同样的事情,而且还是大公司收购了,说明这条路是对的。我今天突然想起来这个公司,然后看了他们发的文章,基于机器学习的游戏付费用户特征挖掘,使用机器学习做游戏留存数据挖掘的一种尝试,这两篇文章一顿操作猛如虎,但是结论确实没有太多的实际价值。然后结合我最近半年对深度学习的研究,发现确实落地的并不是很好,研究图像识别,定位,翻译的朋友们可以搞一搞,深度学习挺适合这些行业的。像我这种初衷的,我基本属于半放弃状态,看看之后有没有好的结合的点。

    展开全文
  • GitChat的娱乐版块已经经历了动漫和游戏,那么第三场娱乐Chat是什么呢?是的,那就是电影!...本场Chat我会尽量避免那种大众知道的大片,避免太重口的大片,避免太没有深度的影片。当然,本场Chat依然会看图猜...

    GitChat的娱乐版块已经经历了动漫和游戏,那么第三场娱乐Chat是什么呢?是的,那就是电影!本场Chat我们一起来回顾我们这些年看过的奇葩和印象深刻的电影吧。本场电影Chat:不限制题材不限制类型;不限制上映时间;不限制上映国家。是的,最重要的是不分等级!请注意及时自带马赛克。

    本场Chat我会尽量避免那种大众知道的大片,避免太重口的大片,避免太没有深度的影片。当然,本场Chat依然会有看图猜电影送红包的活动哦~记得来哟!

    阅读全文: http://gitbook.cn/gitchat/activity/5915c3fb6e3a045287e0cd25

    您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

    FtooAtPSkEJwnW-9xkCLqSTRpBKX

    展开全文
  • 机器学习从学习种类来说,最常见我们习惯分作两种,一种叫无监督学习,一种叫监督学习。 无监督学习:是指人们在获得训练向量数据后在没有标签情况下尝试找出其内部蕴含关系一种挖掘工作,这个过程中...
  • 在Win10游戏本中搭建MindSpore-GPU的深度学习环境背景一、“金字塔”项目目标二、...自从华为开源了MIndSpore深度学习框架,题主就始终惦记着要充分利用手里且仅有的游戏本,给它加持一套高大上支持GPUMindSpore
  • 训练游戏首先要有游戏是吧,接着算法要输入输出是吧 这部分是用来为算法提供输入输出 深度强化学习算法训练几块需要注意: 1.感知 流程 1. 从4399爬取游戏本体到电脑上 2. 获取小游戏的窗口屏幕信息 ...
  • 以太坊网络上备受瞩目的游戏Fomo3D(Fomo3D:Long)第一轮在前天(北京时间 8 月 22 日下午 3 点左右)结束了。最终,地址为 0xa169... 的玩家获得了 10469.66 Eth 的奖金,其取款交易被记录在了 6191962 区块中,该...
  • 在这个游戏中,蛇试图在不触及盒子边界情况下吃掉尽可能多食物。 神经网络十六个输入神经元和四个输出神经元。 蛇在任何给定时间看 8 个方向:(北、东北、东、东南、南、西南、西和西北)。 如果适用于任何...
  • 使用深度优先算法实现自动走迷宫 功能描述 随机迷宫、读取本地文件迷宫 程序环境技术标签等 Java GUI Eclipse-GBK编码 JDK8 演示文件 (GIF因为跳帧问题,画面显示异常,程序正常使用,如上图一致) 联系...
  • 文/青之一号 序: 在开发某网络游戏的过程中,我们团队一个重要的理念:为用户创造激动人心的游戏乐趣。 于是,思考:乐趣是什么,从何而来?写下了一点点心得。 正文: “要养成两种习惯——治救病人,起码...
  • =======幻灯片拼图======= 该游戏是在人工智能学科上开发。 目的是在8游戏中应用A *搜索算法,广泛搜索和深度搜索。 开发团队: , 和 。
  • (但是人们在定义时候难免会或多或少错误,难免计算机调用时候会错误),现在计算机深度学习就是,我们不再告诉计算机,猫是什么了。而是给计算机一堆猫图片。告诉计算机这里面猫。计算机通过计算去...
  • BAliceM1块石子,BobM2块石子,游戏一开始,所有石头放在树节点处,除了树根。Alice先移然后两人轮流移动,每次移动只能选择自己一个石子,而且只能从当前位置移到父亲节点处,游戏过程中允许一个节点处放多...
  • 与以前研究不同,格斗游戏假设两个玩家相当多动作,在这项研究中,采用深度Q网络(DQN)用于视觉格斗游戏AI比赛。动作次数减少到11,并利用视觉格斗平台测试了几个控制参数灵敏度。实验结果表明,对于双人...
  • 游戏有了,接下来是程序输入了 获取窗口名称 windows里面所有进程都一个自己名字(一知半解.jpg) #获取窗口名字 def winEnumHandler(hwnd,non): if win32gui.IsWindowVisible(hwnd): name=win32gui....
  • 如果您任何问题要报告,请查看我们。 如果您对处理代码感兴趣(开发mod或向存储库贡献一些东西),还可以在找到说明。 链接: 官方网站: 论坛: : Wiki: : 先决条件: 视窗 具有C#8.0支持 (建议...
  • HTML5游戏引擎深度测评

    千次阅读 2019-10-04 12:06:50
    最近看到网上一篇文章,标题叫做《2016年 最火 15 款 HTML5 游戏引擎》。目前针对HTML5游戏的解决方案已经非常多,但谁好谁差却没有对比性资料。...针对技术类产品对比,通常多个维度进行对比,不仅...
  • 每个岛屿地形和机关算法自动生成,也就是每个岛屿玩法都不一样。 对于进攻方:打掉岛屿上一个水晶,就能把敌人强制传送出岛屿,并且占领岛屿成功。防守方需要杀掉全部入侵敌人。 AI占领岛屿会固定...
  • 深度剖析动态规划算法求解跳跃游戏 题目描述:在一个N*N大小棋盘中,每个格子都标1到9当中一个整数。游戏规则是,从棋盘最左上角出发,最终到达最右下角。在此过程中,按照相应数值大小可以向右或者向下...
  • 成为一个游戏建模师,需要具备什么? 热情、时间、自制力、心态。 这行没你想月入过万,事实上和你说建模毕业月入过万都是耍流氓。 建模行业,三个月到6个月转正。工资可能会5-6k。 工资经验两年左右,才...
  • 正所谓买的没有卖的精明——笔者身在游戏业内也曾策划和参与了许多的游戏活动。今天就在这里针对国内最为主要的几种游戏活动进行一定的介绍,希望玩家们能搽亮双眼选择地参与从而更多地体验游戏的乐趣和里面的实惠...
  • 这里算前期资料收集,我想试着用python带有的库来学习一下深度强化学习方面算法 (虽然会更偏向于使用,但这东西总要能看到结果才能更好地学习不是吗?) 所以——这个又是一个抄作业博客 收集资料事情怎么...
  • 这是一篇总结文,说说优秀的深度学习从业者拥有一些习惯,从看论文到写代码,从刷论坛到刷比赛。 1 拥有一台GPU 虽然各类深度学习框架caffe,tensorflow等都是可以支持CPU,但是如果没有一台GPU,学深度...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,607
精华内容 642
关键字:

有深度的游戏