Shuffle Bags让你的随机不那么随机
前言
当我最初写游戏时,我经常使用标准Random()函数,然后写一堆if和else条件来我获得预期结果。如果结果不太好,我会写更多的条件进行过滤或者筛选,直到我觉得游戏变得有趣。最近我发现有更好的方法。内置的Random类并没有问题,问题是使用内置的Random类很难达到我们的预期效果。
现实生活中,以抛硬币为例,时而会抛出连续多次花或者字。那么如果在游戏中,可能表现为多次连续的暴击或是硬直,尽管有时暴击和硬直的概率很低,但依旧有可能连续出现,让人感觉诡异。那么为了解决类似的问题,前辈们想了很多种方法,比如说特殊值过滤等等。我们今天介绍的是Shuffle Bag技术,可以让你的随机数不那么随机,由你掌控。
什么是Shuffle Bag呢?
Shuffle Bag是一项让我们可以控制随机数分布的技术。
其主要原理为:
- 设计一个特定分布数值的集合。
- 把集合中数值转载至背包中。
- 将背包中数值随机打乱。
- 从背包中以任意顺序(从前往后,从后往前都无所谓)一个一个的抽取数值,抽完不放回,直到背包为空。
- 背包为空后,将数据放回,并重新打乱,之后循环利用。
- 不会产生集合之外的数据。
- 它仍然具有随机性,元素出现的顺序还是随机的。
- 非重复抽取,如果数据集中某个元素只有一个,至多连续出现两次。
如何实现Shuffle Bag?
using System.Collections.Generic;
using UnityEngine;
public class ShuffleBag<T> {
private List<T> data;
private T currentItem;
private int currentPosition = -1;
private int Capacity { get { return data.Capacity; } }
public int Size { get { return data.Count; } }
public ShuffleBag(int initCapacity)
{
data = new List<T>(initCapacity);
}
public void Add(T item, int amount)
{
for (int i = 0; i < amount; i++)
data.Add(item);
currentPosition = Size - 1;
}
public T Next()
{
if (currentPosition < 1)
{
currentPosition = Size - 1;
currentItem = data[0];
return currentItem;
}
var pos = Random.Range(0,currentPosition);
currentItem = data[pos];
data[pos] = data[currentPosition];
data[currentPosition] = currentItem;
currentPosition--;
return currentItem;
}
}
如何使用Shuffle Bag?
在我的项目中,我希望NPC播放受伤动画的概率为十分之一,并且我不希望看到他偶尔连续播放受伤动画多次,也不想长时间不播放受伤动画。
ShuffleBag<bool> hurtBag = new ShuffleBag<bool>(10);
hurtBag.Add(false, 9);
hurtBag.Add(true, 1);
//当触发受伤时,调用以下逻辑
if(hurtBag.Next())
{
Play();
}
附录
附上参考的原文链接 Shuffle Bags: Making Random() Feel More Random 英文好的同学可以直接看原文 。另外,这个原文题目有些让人疑惑,所以我的译文标题做了一些更改。
Shuffle Bags让你的随机不那么随机的更多相关文章
- 随机采样和随机模拟:吉布斯采样Gibbs Sampling实现文档分类
http://blog.csdn.net/pipisorry/article/details/51525308 吉布斯采样的实现问题 本文主要说明如何通过吉布斯采样进行文档分类(聚类),当然更复杂的实 ...
- Atitit.并发测试解决方案(2) -----获取随机数据库记录 随机抽取数据 随机排序 原理and实现
Atitit.并发测试解决方案(2) -----获取随机数据库记录 随机抽取数据 随机排序 1. 应用场景 1 2. 随机抽取数据原理 1 3. 常用的实现方法:::数据库随机函数 1 4. Mssq ...
- 随机采样和随机模拟:吉布斯采样Gibbs Sampling实现高斯分布参数推断
http://blog.csdn.net/pipisorry/article/details/51539739 吉布斯采样的实现问题 本文主要说明如何通过吉布斯采样来采样截断多维高斯分布的参数(已知一 ...
- 5随机到7随机的C++实现
一.5随机到7随机 //给定条件 int Rand1To5(){ + ; } //实现代码,使用插空法和筛的过程 int Rand1To7(){ ; do{ tmp = (Rand1To5() - ) ...
- 随机总数字里面选取随机数字进行随机排序案例(JAVA实现)
随机总数字里面选取随机数字进行随机排序案例,案例如下: 代码code: package com.sec; import java.util.Arrays; import java.util.Scann ...
- scrapy抓取拉勾网职位信息(六)——反爬应对(随机UA,随机代理)
上篇已经对数据进行了清洗,本篇对反爬虫做一些应对措施,主要包括随机UserAgent.随机代理. 一.随机UA 分析:构建随机UA可以采用以下两种方法 我们可以选择很多UserAgent,形成一个列表 ...
- sql server随机排序和随机取出n条数据
问题:博主在2010-2011学年,广东技术师范大学大四的时候,去过红海人力集团面试数据库职位,很清楚记得当时有一道笔试题目是:编写sql从表里面随机取出10条记录. 解决方案:在sql server ...
- 7. 进行图片的数据补全和增强(随机亮度,随机饱和度,随机翻转) Image.open(进行图片的读入) 2.ImageEnhance.Brightness(亮度变化) 3.ImageEnhance.Contrast(饱和度变化) 4.enhance_image.transpose(图片随机翻转) 5.enhance_image.save(进行图片保存)
1.Image.open(image_path) 进行图片的打开 参数说明:image_path 表示图片的路径 2. ImageEnhance.Brightness(image) # 进行图片的 ...
- JMeter - 生成随机数/随机字符串/随机变量/随机日期
1. Random - 随机数 1.1 作用 1.2 声明 1.3 例子 2. __RandomDate - 随机日期 2.1 作用 2.2 声明参数 2.3 例子 3. RandomString - ...
随机推荐
- 使用transient关键字解决ehcache序列化错误
使用Ehcache时发现个不起眼的小问题 在一个Model中有以下代码: public class MyModel implements Serializable { private static f ...
- [HNOI2005]汤姆的游戏
嘟嘟嘟 直接O(n ^ 2)暴力判断就行了. 对于圆,判断该点和圆心的距离是否小于半径. 然而为啥我这么写编译不过: scanf("%lf%lf%lf%lf", &a[++ ...
- 【转】tomcat搭建本地服务器 实现apk更新下载
转自:http://www.kankanews.com/ICkengine/archives/121748.shtml 做apk的更新下载功能,测试的时候需要个服务器. 所以就选用 Apache To ...
- iRedMail搭建完后登录提示【连接至IMAP服务器失败】(转)
http://ask.apelearn.com/question/8080(参考) ================搭建步骤如下=====================登录www.net.cn,产品 ...
- 沟通修炼 I型沟通->U型沟通
沟通的目的 来源:邀请你看<01课 沟通管理:学会U型沟通,沟通效率翻倍>https://url.cn/51YaHrq?sf=uri 案例: 女友太困,不想早起去上班 你的回答? 正确做法 ...
- 前端实现文件在线预览txt,pdf,doc,xls,ppt几种格式
做法就是使用iframe标签 1.text,pdf的文件预览 <iframe class="filename" :src="文件的地址" width='1 ...
- 存储类、链接和内存管理(c prime plus)
首先介绍三个概念: (1)作用域:作用域描述了程序中可以访问一个标识符的一个或多个区域. 一共有三种作用域:代码块作用域.函数原型作用域和文件作用域 a.代码块作用域:一个代码块是包含在开始花括号和对 ...
- iOS swift项目IM实现,从长连接到数据流解析分析之Socket
iOS swift项目IM实现,从长连接到底层数据解析分析之Socket 一:项目简介: 去年开始接手了一个国企移动项目,项目的需求是实现IM即时通讯功能. * 一期版本功能包括了: ...
- Scala_单例对象
在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object. 对象的无参构造器在第一次使用时被调用,且单例对象没有有残构造器. Enu ...
- 洛谷 1440 求m区间内的最小值
洛谷 1440 求m区间内的最小值 题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. ...