Libsaki
Core library of Pancake Mahjong
tile_count.h
1 #ifndef SAKI_TILECOUNT_H
2 #define SAKI_TILECOUNT_H
3 
4 #include "parsed.h"
5 
6 #include <vector>
7 #include <initializer_list>
8 #include <numeric>
9 
10 
11 
12 namespace saki
13 {
14 
15 
16 
17 class TileCount
18 {
19 public:
20  enum AkadoraCount { AKADORA0, AKADORA3, AKADORA4 };
21 
23  {
24  explicit Explain4Closed(T34 p) : pair(p) {}
25  T34 pair;
26  std::vector<T34> triplets;
27  std::vector<T34> sequences;
28  };
29 
30  TileCount();
31  explicit TileCount(AkadoraCount fillMode);
32  explicit TileCount(std::initializer_list<T37> t37s);
33 
34  TileCount(const TileCount &copy) = default;
35  TileCount &operator=(const TileCount &assign) = default;
36 
37  int ct(T34 t) const;
38  int ct(const T37 &t) const;
39  int ct(Suit s) const;
40  int ctAka5() const;
41  int ctZ() const;
42  int ctYao() const;
43 
44  template<typename V>
45  int ct(const V &ts) const
46  {
47  auto aux = [this](int s, T34 t) { return s + ct(t); };
48  return std::accumulate(ts.begin(), ts.end(), 0, aux);
49  }
50 
51  bool has(Suit s) const;
52  bool hasZ() const;
53  bool hasYao() const;
54 
55  bool covers(const TileCount &that) const;
56 
57  void inc(const T37 &t, int delta);
58  void clear(T34 t);
59 
60  TileCount &operator-=(const TileCount &rhs);
61 
62  int step(int barkCt) const;
63  int stepGb(int barkCt) const;
64  int step4(int barkCt) const;
65  int step7() const;
66  int step7Gb() const;
67  int step13() const;
68 
69  bool hasEffA(int barkCt, T34 t) const;
70  bool hasEffA4(int barkCt, T34 t) const;
71  bool hasEffA7(T34 t) const;
72  bool hasEffA13(T34 t) const;
73 
75  util::Stactor<T37, 13> t37s13(bool allowDup = false) const;
76 
77  bool dislike4(T34 t) const;
78 
79  Parseds parse(int barkCt) const;
80  Parsed4s parse4(int barkCt) const;
81  Parsed7 parse7() const;
82  Parsed13 parse13() const;
83 
84  std::vector<Explain4Closed> explain4(T34 pick) const;
85  bool onlyInTriplet(T34 pick, int barkCt) const;
86 
87  int sum(const std::vector<T34> &ts) const;
88  int sum() const;
89 
90  template<typename Ret, typename... Params, typename... Args>
91  Ret peekDraw(T34 t, Ret (TileCount::*f) (Params...) const, Args && ... args) const
92  {
93  return peekDelta(t, 1, f, std::forward<Args>(args) ...);
94  }
95 
96  template<typename Ret, typename... Params, typename... Args>
97  Ret peekDelta(T34 t, int delta, Ret (TileCount::*f) (Params...) const, Args && ... args) const
98  {
99  T34Delta guard(mutableCounts(), t, delta);
100  (void) guard;
101  return (this->*f)(std::forward<Args>(args) ...);
102  }
103 
104 private:
105  // using T34, assume const query functions are free from 34/37 matters
106  class T34Delta
107  {
108  public:
109  T34Delta(std::array<int, 34> &mCounts, T34 t, int delta);
110  ~T34Delta();
111 
112  T34Delta(const T34Delta &copy) = delete;
113  T34Delta &operator=(const T34Delta &assign) = delete;
114 
115  private:
116  std::array<int, 34> &mCount;
117  T34 mTile;
118  int mDelta;
119  };
120 
121  class NonEmptyGuard
122  {
123  public:
124  explicit NonEmptyGuard(std::vector<Parsed4::Heads> &p);
125  ~NonEmptyGuard();
126 
127  private:
128  std::vector<Parsed4::Heads> &mParseds;
129  };
130 
131  std::array<int, 34> &mutableCounts() const;
132  int cutMeld(int i, int maxCut) const;
133  std::vector<Parsed4::Heads> cutMeldOut(int i, int maxCut) const;
134  int cutSubmeld(int i, int maxCut) const;
135  std::vector<Parsed4::Heads> cutSubmeldOut(int i, int maxCut) const;
136  bool decomposeBirdless4(Explain4Closed &exp, const std::array<int, 34> &mCounts) const;
137 
138 private:
139  std::array<int, 34> mCounts;
140  std::array<int, 3> mAka5s;
141 };
142 
143 
144 
145 } // namespace saki
146 
147 
148 
149 #endif // SAKI_TILECOUNT_H
Parsed4s parse4(int barkCt) const
Parse this hand as 4-meld shape with minimal shanten number.
Definition: tile_count.cpp:354
util::Stactor< T34, 13 > t34s13() const
List all kind of tiles in this set.
Definition: tile_count.cpp:269
Definition: parsed.h:112
Definition: tile_count.h:22
bool dislike4(T34 t) const
Check if &#39;t&#39; is trivially not an effA4.
Definition: tile_count.cpp:318
Definition: tile.h:25
util::Stactor< T37, 13 > t37s13(bool allowDup=false) const
List all tiles in this set.
Definition: tile_count.cpp:287
Definition: tile_count.h:17
Definition: ai.cpp:18
bool covers(const TileCount &that) const
Definition: tile_count.cpp:120
Definition: parsed.h:80
Definition: tile.h:353
Stactor = statically allocated vector.
Definition: stactor.h:247
Definition: parsed.h:96
Definition: parsed.h:56