Libsaki
Core library of Pancake Mahjong
hand.h
1 #ifndef SAKI_HAND_H
2 #define SAKI_HAND_H
3 
4 #include "rule.h"
5 #include "form_ctx.h"
6 #include "tile_count.h"
7 #include "../unit/action.h"
8 #include "../unit/meld.h"
9 
10 
11 
12 namespace saki
13 {
14 
15 
16 
17 class Hand
18 {
19 public:
20  Hand() = default;
21  explicit Hand(const TileCount &count);
22  explicit Hand(const TileCount &count, const util::Stactor<M37, 4> &barks);
23 
24  ~Hand() = default;
25 
26  Hand(const Hand &copy) = default;
27  Hand(Hand &&move) = default;
28  Hand &operator=(const Hand &assign) = default;
29  Hand &operator=(Hand &&moveAssign) = default;
30 
31  const TileCount &closed() const;
32  const T37 &drawn() const;
33  const T37 &outFor(const Action &action) const;
34  const util::Stactor<M37, 4> &barks() const;
35 
36  bool hasDrawn() const;
37  bool isMenzen() const;
38  bool over4() const;
39  bool nine9() const;
40 
41  int ct(T34 t) const;
42  int ctAka5() const;
43 
44  bool canChii(T34 t) const;
45  bool canChiiAsLeft(T34 t) const;
46  bool canChiiAsMiddle(T34 t) const;
47  bool canChiiAsRight(T34 t) const;
48  bool canPon(T34 t) const;
49  bool canCp(T34 pick, const Action &action) const;
50  bool canDaiminkan(T34 t) const;
51  bool canAnkan(util::Stactor<T34, 3> &choices, bool riichi) const;
52  bool canKakan(util::Stactor<int, 3> &barkIds) const;
53  bool canRon(T34 t, const FormCtx &info, const Rule &rule, bool &doujun) const;
54  bool canTsumo(const FormCtx &info, const Rule &rule) const;
55  bool canRiichi(util::Stactor<T37, 13> &swappables, bool &spinnable) const;
56 
57  bool ready() const;
58  int step() const;
59  int stepGb() const;
60  int step4() const;
61  int step7() const;
62  int step7Gb() const;
63  int step13() const;
64 
65  bool hasEffA(T34 t) const;
66  bool hasEffA4(T34 t) const;
67  bool hasEffA7(T34 t) const;
68  bool hasEffA13(T34 t) const;
69 
70  util::Stactor<T34, 34> effA() const;
71  util::Stactor<T34, 34> effA4() const;
72 
73  Parseds parse() const;
74  Parsed4s parse4() const;
75 
76  int estimate(const Rule &rule, int sw, int rw, const util::Stactor<T37, 5> &drids) const;
77 
78  int peekPickStep(T34 pick) const;
79  int peekPickStep4(T34 pick) const;
80  int peekPickStep7(T34 pick) const;
81  int peekPickStep7Gb(T34 pick) const;
82  int peekPickStep13(T34 pick) const;
83 
84  template<typename Ret, typename... Params, typename... Args>
85  Ret peekDiscard(const Action &a, Ret (Hand::*f) (Params...) const, Args && ... args) const
86  {
87  switch (a.act()) {
88  case ActCode::SWAP_OUT:
89  return peekSwap(a.t37(), f, std::forward<Args>(args) ...);
90  case ActCode::SPIN_OUT:
91  return peekSpin(f, std::forward<Args>(args) ...);
92  default:
93  unreached();
94  }
95  }
96 
97  template<typename Ret, typename... Params, typename... Args>
98  Ret peekSwap(const T37 &t, Ret (Hand::*f) (Params...) const, Args && ... args) const
99  {
100  DeltaSwap guard(const_cast<Hand &>(*this), t);
101  (void) guard;
102  return (this->*f)(std::forward<Args>(args) ...);
103  }
104 
105  template<typename Ret, typename... Params, typename... Args>
106  Ret peekSpin(Ret (Hand::*f) (Params...) const, Args && ... args) const
107  {
108  DeltaSpin guard(const_cast<Hand &>(*this));
109  (void) guard;
110  return (this->*f)(std::forward<Args>(args) ...);
111  }
112 
113  template<typename Ret, typename... Params, typename... Args>
114  Ret peekCp(const T37 &pick, const Action &action,
115  Ret (Hand::*f) (Params...) const, Args && ... args) const
116  {
117  assert(action.isCp());
118  DeltaCp guard(const_cast<Hand &>(*this), pick, action, action.t37());
119  (void) guard;
120  return (this->*f)(std::forward<Args>(args) ...);
121  }
122 
123  void draw(const T37 &in);
124  void swapOut(const T37 &out);
125  void spinOut();
126  void barkOut(const T37 &out);
127  void chiiAsLeft(const T37 &pick, bool showAka5);
128  void chiiAsMiddle(const T37 &pick, bool showAka5);
129  void chiiAsRight(const T37 &pick, bool showAka5);
130  void pon(const T37 &pick, int showAka5, int layIndex);
131  void daiminkan(const T37 &pick, int layIndex);
132  void ankan(T34 t);
133  void kakan(int barkId);
134 
135 private:
136  class DeltaSpin
137  {
138  public:
139  explicit DeltaSpin(Hand &hand);
140  ~DeltaSpin();
141 
142  DeltaSpin(const DeltaSpin &copy) = delete;
143  DeltaSpin &operator=(const DeltaSpin &assign) = delete;
144 
145  private:
146  Hand &mHand;
147  };
148 
149  class DeltaSwap
150  {
151  public:
152  explicit DeltaSwap(Hand &hand, const T37 &out);
153  ~DeltaSwap();
154 
155  DeltaSwap(const DeltaSwap &copy) = delete;
156  DeltaSwap &operator=(const DeltaSwap &assign) = delete;
157 
158  private:
159  Hand &mHand;
160  const T37 &mOut;
161  };
162 
163  class DeltaCp
164  {
165  public:
166  explicit DeltaCp(Hand &hand, const T37 &pick, const Action &a, const T37 &out);
167  ~DeltaCp();
168 
169  DeltaCp(const DeltaCp &copy) = delete;
170  DeltaCp &operator=(const DeltaCp &assign) = delete;
171 
172  private:
173  Hand &mHand;
174  const T37 &mOut;
175  };
176 
177  using SwapOk = std::function<bool(T34)>;
178 
179  bool usingCache() const;
180  const Parseds &loadCache() const;
181 
182  bool hasSwappableAfterChii(T34 mat1, T34 mat2, SwapOk ok) const;
183  bool shouldShowAka5(T34 show, bool showAka5) const;
184  T37 tryShow(T34 t, bool showAka5);
185  util::Stactor<T37, 13> makeChoices(SwapOk ok) const;
186 
187  template<typename Ret, typename... Params, typename... Args>
188  Ret peekStay(Ret (TileCount::*f)(Params...) const, Args... args) const
189  {
190  return mHasDrawn ? mClosed.peekDraw<Ret, Params...>(mDrawn, f, args...)
191  : (mClosed.*f)(args...);
192  }
193 
194 private:
195  TileCount mClosed;
196  T37 mDrawn;
197  bool mHasDrawn = false;
198  util::Stactor<M37, 4> mBarks;
199  mutable std::optional<Parseds> mParseCache;
200  mutable int mSkipCacheLevel = 0;
201 };
202 
203 int operator%(T34 ind, const Hand &hand);
204 int operator%(const util::Stactor<T37, 5> &inds, const Hand &hand);
205 
206 
207 
208 } // namespace saki
209 
210 
211 
212 #endif // SAKI_HAND_H
Definition: rule.h:13
Definition: form_ctx.h:11
Definition: parsed.h:112
Definition: tile.h:25
Definition: tile_count.h:17
Definition: action.h:27
Definition: ai.cpp:18
Definition: hand.h:17
Definition: tile.h:353
Stactor = statically allocated vector.
Definition: stactor.h:247
Definition: parsed.h:56