Xiangiqgame
AI engine for Xiangqi
Loading...
Searching...
No Matches
utility_functs.hpp
Go to the documentation of this file.
1
3
4#pragma once
5
6#include <algorithm>
7#include <array>
8#include <config.hpp>
9#include <random>
10#include <string>
11#include <unordered_map>
12#include <vector>
13
15namespace utility_functs {
16
17// using json = nlohmann::json;
18using namespace std;
19
20template <typename T>
21T random(T range_from, T range_to) {
22 random_device rand_dev;
23 mt19937 generator(rand_dev());
24 uniform_int_distribution<T> distr(range_from, range_to);
25 return distr(generator);
26}
27
28inline bool ends_with(string const &value, string const &ending) {
29 if (ending.size() > value.size())
30 return false;
31 return equal(ending.rbegin(), ending.rend(), value.rbegin());
32}
33
34template <typename FromKey, typename ToKey, typename Value>
35unordered_map<ToKey, Value> replace_keys(
36 unordered_map<FromKey, Value> orig_map,
37 std ::unordered_map<FromKey, ToKey> key_substitutions
38) {
39 unordered_map<ToKey, Value> new_map;
40 for (auto entry : key_substitutions) {
41 new_map[entry.second] = orig_map[entry.first];
42 }
43 return new_map;
44}
45
46// replaces KEYS in original map with VALUES of matching KEYS in
47// key_substitutions
48template <typename FromKey, typename ToKey, typename Value>
49unordered_map<ToKey, Value> replace_keys_forward(
50 unordered_map<FromKey, Value> orig_map,
51 unordered_map<FromKey, ToKey> key_substitutions
52) {
53 unordered_map<ToKey, Value> new_map;
54 for (auto entry : key_substitutions) {
55 new_map[entry.second] = orig_map[entry.first];
56 }
57 return new_map;
58}
59
60// replaces KEYS in original map with KEYS of matching VALUES in
61// key_substitutions
62template <typename FromKey, typename ToKey, typename Value>
63unordered_map<ToKey, Value> replace_keys_reverse(
64 unordered_map<FromKey, Value> orig_map,
65 unordered_map<ToKey, FromKey> key_substitutions
66) {
67 unordered_map<ToKey, Value> new_map;
68 for (auto entry : key_substitutions) {
69 new_map[entry.first] = orig_map[entry.second];
70 }
71 return new_map;
72}
73
74template <typename two_d_array_t>
75two_d_array_t vertical_flip_array(two_d_array_t orig_array) {
76 auto flipped_array = orig_array;
77 reverse(flipped_array.begin(), flipped_array.end());
78 return flipped_array;
79}
80
81template <typename two_d_array_t>
82two_d_array_t two_array_sum(two_d_array_t a, two_d_array_t b) {
83 two_d_array_t result{};
84 for (auto row = 0; row < a.size(); row++) {
85 for (auto col = 0; col < a[0].size(); col++) {
86 result[row][col] = a[row][col] + b[row][col];
87 }
88 }
89 return result;
90}
91
92template <typename two_d_array_t, typename array_element_t>
93two_d_array_t array_plus_const(two_d_array_t array, array_element_t offset) {
94 two_d_array_t result{};
95 for (auto row = 0; row < array.size(); row++) {
96 for (auto col = 0; col < array[0].size(); col++) {
97 result[row][col] = array[row][col] + offset;
98 }
99 }
100 return result;
101}
102
103template <typename two_d_array_t, typename array_element_t>
104bool operator==(two_d_array_t &a, two_d_array_t &b) {
105 bool are_equal = true;
106
107 for (auto rank = 0; rank < a.size(); rank++) {
108 for (auto file = 0; file < a[0].size(); file++) {
109 if (a[rank][file] != b[rank][file]) {
110 are_equal = false;
111 return are_equal;
112 }
113 }
114 }
115 return are_equal;
116}
117
118template <typename T>
120 const std::vector<T> &vec,
121 int lookback_length,
122 int period
123) {
124 // Ensure lookback_length is a multiple of period and the vector has at least
125 // lookback_length elements
126 if (lookback_length % period != 0 || vec.size() < lookback_length) {
127 return false;
128 }
129
130 // Get the number of repetitions
131 int repetitions = lookback_length / period;
132
133 // Check if the pattern with period repeats for the last lookback_length
134 // elements
135 for (int i = 0; i < period; ++i) {
136 T patternElement = vec[vec.size() - lookback_length + i];
137 for (int j = 1; j < repetitions; ++j) {
138 if (vec[vec.size() - lookback_length + i + j * period] !=
139 patternElement) {
140 return false;
141 }
142 }
143 }
144
145 return true;
146}
147
148template <typename T, typename M>
149typename std::vector<T>::const_iterator find_by_member(
150 const std::vector<T> &vec,
151 M T::*member,
152 const M &value
153) {
154 return std::find_if(vec.begin(), vec.end(), [member, &value](const T &item) {
155 return item.*member == value;
156 });
157}
158
159const string get_data_file_abs_path(const std::string data_file);
160
161
162} // namespace utility_functs
Free functions that don't clearly belong in any other namespace.
unordered_map< ToKey, Value > replace_keys_reverse(unordered_map< FromKey, Value > orig_map, unordered_map< ToKey, FromKey > key_substitutions)
bool operator==(two_d_array_t &a, two_d_array_t &b)
T random(T range_from, T range_to)
bool ends_with(string const &value, string const &ending)
const string get_data_file_abs_path(const std::string data_file)
unordered_map< ToKey, Value > replace_keys(unordered_map< FromKey, Value > orig_map, std ::unordered_map< FromKey, ToKey > key_substitutions)
two_d_array_t array_plus_const(two_d_array_t array, array_element_t offset)
unordered_map< ToKey, Value > replace_keys_forward(unordered_map< FromKey, Value > orig_map, unordered_map< FromKey, ToKey > key_substitutions)
two_d_array_t two_array_sum(two_d_array_t a, two_d_array_t b)
bool hasRepeatingPattern(const std::vector< T > &vec, int lookback_length, int period)
std::vector< T >::const_iterator find_by_member(const std::vector< T > &vec, M T::*member, const M &value)
two_d_array_t vertical_flip_array(two_d_array_t orig_array)