728x90
반응형
가중치를 주어서 랜덤값을 추출하는 소스입니다.
1. 클래스
클래스 : 가중치 랜덤 추출 |
public static class WeightedRandomizer { public static WeightedRandomizer<R> From<R>(Dictionary<R, int> spawnRate) { return new WeightedRandomizer<R>(spawnRate); } } public class WeightedRandomizer<T> { private static System.Random _random = new System.Random(); private Dictionary<T, int> _weights; public WeightedRandomizer(Dictionary<T, int> weights) { _weights = weights; } public T TakeOne() { var sortedSpawnRate = Sort(_weights); int sum = 0; foreach (var spawn in _weights) { sum += spawn.Value; } int roll = _random.Next(0, sum); T selected = sortedSpawnRate[sortedSpawnRate.Count - 1].Key; foreach (var spawn in sortedSpawnRate) { if (roll < spawn.Value) { selected = spawn.Key; break; } roll -= spawn.Value; } return selected; } private List<KeyValuePair<T, int>> Sort(Dictionary<T, int> weights) { var list = new List<KeyValuePair<T, int>>(weights); list.Sort( delegate (KeyValuePair<T, int> firstPair, KeyValuePair<T, int> nextPair) { return firstPair.Value.CompareTo(nextPair.Value); } ); return list; } } |
2. 데모
using System.Collections.Generic;
using UnityEngine;
public class DemoWeightedRandomizer : MonoBehaviour
{
enum Card { Bronze, Silver, Gold, Diamond }
private Dictionary<Card, int> m_Cards = new Dictionary<Card, int>();
[SerializeField] private Card m_Card = Card.Bronze;
void Start()
{
m_Cards.Add(Card.Bronze, 90);
m_Cards.Add(Card.Silver, 6);
m_Cards.Add(Card.Gold, 3);
m_Cards.Add(Card.Diamond, 1);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.S))
{
m_Card = WeightedRandomizer.From(m_Cards).TakeOne();
Debug.Log(m_Card.ToString());
}
}
public static class WeightedRandomizer
{
public static WeightedRandomizer<R> From<R>(Dictionary<R, int> spawnRate)
{
return new WeightedRandomizer<R>(spawnRate);
}
}
public class WeightedRandomizer<T>
{
private static System.Random _random = new System.Random();
private Dictionary<T, int> _weights;
public WeightedRandomizer(Dictionary<T, int> weights)
{
_weights = weights;
}
public T TakeOne()
{
var sortedSpawnRate = Sort(_weights);
int sum = 0;
foreach (var spawn in _weights)
{
sum += spawn.Value;
}
int roll = _random.Next(0, sum);
T selected = sortedSpawnRate[sortedSpawnRate.Count - 1].Key;
foreach (var spawn in sortedSpawnRate)
{
if (roll < spawn.Value)
{
selected = spawn.Key;
break;
}
roll -= spawn.Value;
}
return selected;
}
private List<KeyValuePair<T, int>> Sort(Dictionary<T, int> weights)
{
var list = new List<KeyValuePair<T, int>>(weights);
list.Sort(
delegate (KeyValuePair<T, int> firstPair,
KeyValuePair<T, int> nextPair)
{
return firstPair.Value.CompareTo(nextPair.Value);
}
);
return list;
}
}
}
3. 결과
728x90
반응형
'프로그램 > 유니티 스크립트 소스' 카테고리의 다른 글
[유니티 스크립트 소스] UI.Text 타이핑 효과 (1) | 2020.03.05 |
---|---|
[유니티 스크립트 소스] 비행 오브젝트를 부드럽게 따라다니는 오브젝트(카메라) (0) | 2020.02.26 |
[유니티 스크립트 소스] 자식 오브젝트들 얻기 (0) | 2020.02.26 |
[유니티 스크립트 소스] 화면 캡처 및 프린트(Windows) (0) | 2020.02.21 |
[유니티 스크립트 소스] csv 파일 읽고 쓰기 (0) | 2020.02.21 |