Ported shogi.
[tagua/yd.git] / src / hlvariant / pool.h
blobaafb866f98011321f9c26194825da949c6040728
1 #ifndef HLVARIANT__POOL_H
2 #define HLVARIANT__POOL_H
4 #include <map>
6 namespace HLVariant {
8 template <typename _Piece>
9 class Pool {
10 public:
11 typedef _Piece Piece;
12 private:
13 typedef typename Piece::Color Color;
14 typedef typename Piece::Type Type;
15 typedef std::map<Type, int> Data;
17 Color m_owner;
18 Data m_data;
19 public:
20 Pool(Color owner);
21 virtual ~Pool();
23 virtual bool operator==(const Pool<Piece>& other) const;
24 virtual bool operator!=(const Pool<Piece>& other) const;
26 virtual int count(Type type) const;
27 virtual int add(Type type);
28 virtual int remove(Type type);
30 virtual bool empty() const;
31 virtual int size() const;
32 virtual int insert(int index, const Piece& piece);
33 virtual Piece get(int index) const;
34 virtual Piece take(int index);
36 typedef Data RawData;
37 const RawData& rawData() const { return m_data; }
41 // IMPLEMENTATION
43 template <typename Piece>
44 Pool<Piece>::Pool(Color owner)
45 : m_owner(owner) { }
47 template <typename Piece>
48 Pool<Piece>::~Pool() { }
50 template <typename Piece>
51 bool Pool<Piece>::operator==(const Pool<Piece>& other) const {
52 return m_owner == other.m_owner && m_data == other.m_data;
55 template <typename Piece>
56 bool Pool<Piece>::operator!=(const Pool<Piece>& other) const {
57 return !((*this) == other);
60 template <typename Piece>
61 int Pool<Piece>::count(Type type) const {
62 typename Data::const_iterator it = m_data.find(type);
63 if (it != m_data.end()) {
64 return it->second;
66 else {
67 return 0;
71 template <typename Piece>
72 int Pool<Piece>::add(Type type) {
73 return ++m_data[type];
76 template <typename Piece>
77 int Pool<Piece>::remove(Type type) {
78 int n = --m_data[type];
79 if (n <= 0) {
80 m_data.erase(type);
81 return 0;
84 return n;
87 template <typename Piece>
88 bool Pool<Piece>::empty() const {
89 return m_data.empty();
92 template <typename Piece>
93 int Pool<Piece>::size() const {
94 int count = 0;
95 for (typename Data::const_iterator end = m_data.end(), it = m_data.begin(); it != end; ++it)
96 count += it->second;
97 return count;
100 template <typename Piece>
101 int Pool<Piece>::insert(int index, const Piece& piece) {
102 if (m_owner != piece.color())
103 return -1;
105 int fill = 0;
106 for (typename Data::iterator end = m_data.end(), i = m_data.begin();
107 i != end && i->first < piece.type();
108 ++i) {
109 fill += i->second;
112 int nump = add(piece.type());
114 if (index < fill)
115 return fill;
116 if (index >= fill + nump)
117 return fill + nump - 1;
118 return index;
121 template <typename Piece>
122 Piece Pool<Piece>::get(int index) const {
123 if (index < 0)
124 return Piece();
126 int fill = 0;
127 for (typename Data::const_iterator end = m_data.end(), i = m_data.begin(); i != end; ++i) {
128 if (index < fill + i->second)
129 return Piece(m_owner, i->first);
130 fill += i->second;
133 return Piece();
136 template <typename Piece>
137 Piece Pool<Piece>::take(int index) {
138 if (index < 0)
139 return Piece();
141 int fill = 0;
142 for (typename Data::iterator end = m_data.end(), i = m_data.begin(); i != end; ++i) {
143 if(index < fill + i->second) {
144 Type type = i->first;
145 remove(type);
146 return Piece(m_owner, type);
149 fill += i->second;
152 return Piece();
157 #endif // HLVARIANT__POOL_H