Euphoria
shufflebag.h
Go to the documentation of this file.
1 #pragma once
2 
3 
4 
5 #include "range/v3/view/span.hpp"
6 
7 #include "assert/assert.h"
8 #include "base/random.h"
9 #include "base/cint.h"
10 
11 namespace eu::core
12 {
13  template <typename T>
14  struct Shufflebag
15  {
16  Shufflebag() = default;
17 
18  void reserve(int count)
19  {
20  data.reserve(c_int_to_sizet(count));
21  }
22 
23  void add(const T& item, int amount)
24  {
25  ASSERT(amount > 0);
26 
27  for(int step = 0; step < amount; step++)
28  {
29  data.push_back(item);
30  }
31 
32  cursor = get_size() - 1;
33  }
34 
35  [[nodiscard]] const T& get_random_item(Random* rand)
36  {
37  ASSERT(rand);
38  ASSERT(!data.empty()); // needs data
39 
40  if(cursor < 1)
41  {
42  cursor = get_size() - 1;
43  return data[0];
44  }
45 
46  const auto next_position = get_random_in_range(rand, static_cast<int>(cursor));
47 
48  std::swap(data[next_position], data[cursor]);
49  cursor -= 1;
50 
51  return data[cursor + 1];
52  }
53 
54  [[nodiscard]] int get_size() const
55  {
56  return c_sizet_to_int(data.size());
57  }
58 
59  private:
60  std::vector<T> data;
61  unsigned long cursor = 0;
62  };
63 
64 
65  template<typename T>
66  [[nodiscard]]
67  constexpr Shufflebag<T>
68  create_shuffle_bag(const ranges::span<const T>& items, int amount)
69  {
70  auto b = Shufflebag<T>{};
71  b.reserve(c_sizet_to_int(items.size()) * amount);
72  for(const auto& it: items)
73  {
74  b.add(it, amount);
75  }
76  return b;
77  }
78 
79 
80  template<typename T>
81  [[nodiscard]]
82  constexpr Shufflebag<T>
83  create_shuffle_bag(const std::vector<T>& items, int amount)
84  {
85  return create_shuffle_bag(ranges::span<T>{items.begin(), items.end()}, amount);
86  }
87 
88 }
89 
#define ASSERT(x)
Definition: assert.h:29
constexpr Shufflebag< T > create_shuffle_bag(const ranges::span< const T > &items, int amount)
Definition: shufflebag.h:68
int c_sizet_to_int(size_t t)
Definition: cint.cc:11
size_t c_int_to_sizet(int i)
Definition: cint.cc:35
T get_random_in_range(Random *rand, const Range< T > &range)
Definition: random.h:50
WEL512 Random Number Generator.
Definition: random.h:21
void add(const T &item, int amount)
Definition: shufflebag.h:23
void reserve(int count)
Definition: shufflebag.h:18
int get_size() const
Definition: shufflebag.h:54
const T & get_random_item(Random *rand)
Definition: shufflebag.h:35