2019년 4월 13일 토요일

# 드랍 확률을 가진 아이템 간단한 구현. ( C++ )

개별적인 드랍률을 가진 여러개의 아이템을 100번정도 드랍한다는 상황.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <vector>
#include <ctime>

// 참고한 레퍼런스 문서
// #1) http://rosagigantea.tistory.com/595
// #2) http://www.vcskicks.com/random-element.php
// #3) https://stackoverflow.com/questions/25991198/game-design-theory-loot-drop-chance-spawn-rate

#define MAX_ITEM 10
#define MAX_ITEM_DROP 100
#define MAX_ITEM_DROP_RATE 100
using namespace std;

struct GameItem
{
public:
 int id;
 float dropRate;
};

int GetRandomItemID(const vector<int>&  cumulativeProbabilities);
void SimulateItemDrop(vector<int>& lootedItems, const vector<int>& cumulativeProbabilities);
void CalcCumulativeProbabilities(const vector<int>& itemDropRates);
void InitItems(vector<GameItem>& items);
void PrintLootedItems(const vector<int>& lootedItems);

vector<int> itemDropRates;
vector<int> cumulativeProbabilities;
vector<GameItem> items;
void main() {
 srand((unsigned int)time(NULL));

 itemDropRates.push_back(1);
 itemDropRates.push_back(2);
 itemDropRates.push_back(3);
 itemDropRates.push_back(4);
 itemDropRates.push_back(5);
 itemDropRates.push_back(5);
 itemDropRates.push_back(20);
 itemDropRates.push_back(20);
 itemDropRates.push_back(20);
 itemDropRates.push_back(20);

 InitItems(items);
 CalcCumulativeProbabilities(itemDropRates);

 vector<int> lootedItems;
 SimulateItemDrop(lootedItems, cumulativeProbabilities);

 PrintLootedItems(lootedItems);
}

void PrintLootedItems(const vector<int>& lootedItems) {
 int idx = 0;
 for each (auto itemId in lootedItems) {
  cout << "[ " << idx++ << " ]";
  cout << "획득한 아이템 ID : " << itemId << endl;
 }
}

void InitItems(vector<GameItem>& items) {
 int itemIdx = 0;
 for each (auto dropRate in itemDropRates) {
  GameItem item;
  item.id = itemIdx++;
  item.dropRate = dropRate;
  items.push_back(item);
 }
}

void CalcCumulativeProbabilities(const vector<int>& itemDropRates) {
 cumulativeProbabilities.clear();
 float cumulative = 0.0f;
 for each (auto dropRate in itemDropRates) {
  cumulative += dropRate;
  cumulativeProbabilities.push_back(cumulative);
 }
}

void SimulateItemDrop(vector<int>& lootedItems, const vector<int>& cumulativeProbabilities) {
 bool isDropedRareItem = false;
 for (int idx = 0; idx < MAX_ITEM_DROP; idx++) {
  int id = GetRandomItemID(cumulativeProbabilities);
  lootedItems.push_back(id);
 }
}

int GetRandomItemID(const vector<int>& cumulativeProbabilities) {
 int itemId = 0;
 int randVal = rand() % MAX_ITEM_DROP_RATE;
 while (cumulativeProbabilities[itemId] <= randVal) {
  itemId++;
 }
 return itemId;
}

댓글 없음:

댓글 쓰기