Libsaki
Core library of Pancake Mahjong
mount.h
1 #ifndef SAKI_MOUNT_H
2 #define SAKI_MOUNT_H
3 
4 #include "../form/tile_count.h"
5 #include "../util/rand.h"
6 
7 #include <optional>
8 #include <array>
9 #include <vector>
10 #include <list>
11 
12 
13 
14 namespace saki
15 {
16 
17 
18 
19 class Exist
20 {
21 public:
22  static const int BASE_MK = 10;
23 
24  struct Polar
25  {
26  struct Cy
27  {
28  explicit Cy(const T37 &t, int e) : t(t), e(e) {}
29  T37 t;
30  int e;
31  };
32 
33  std::vector<Cy> pos;
34  std::vector<Cy> npos;
35  };
36 
37  Exist();
38  Exist(const Exist &copy) = default;
39  Exist &operator=(const Exist &assign) = default;
40 
41  void incMk(const T37 &t, int delta);
42  void incMk(T34 t, int delta);
43  void addBaseMk(const TileCount &stoch);
44 
45  Polar polarize(const TileCount &stoch) const;
46 
47 private:
48  std::array<int, 34> mBlack;
49  std::array<int, 3> mRed;
50 };
51 
52 
53 
54 class Mount
55 {
56 public:
57  enum Exit { PII, RINSHAN, DORAHYOU, URAHYOU, NUM_EXITS };
58 
59  explicit Mount(TileCount::AkadoraCount fillMode);
60 
61  Mount(const Mount &copy) = default;
62  Mount &operator=(const Mount &assign) = default;
63 
64  void initFill(util::Rand &rand, TileCount &init, Exist &exist);
65  const T37 &initPopExact(const T37 &t);
66  T37 pop(util::Rand &rand, bool rinshan = false);
67 
68  int remainPii() const;
69  int remainRinshan() const;
70  int remainA(T34 t) const;
71  int remainA(const T37 &t) const;
72 
73  const util::Stactor<T37, 5> &getDrids() const;
74  const util::Stactor<T37, 5> &getUrids() const;
75 
76  const TileCount &getStockA() const;
77 
78  void lightA(T34 t, int delta, bool rinshan = false);
79  void lightA(const T37 &t, int delta, bool rinshan = false);
80  void lightB(T34 t, int delta, bool rinshan = false);
81  void lightB(const T37 &t, int delta, bool rinshan = false);
82  void incMk(Exit exit, size_t pos, T34 t, int delta, bool bSpace);
83  void incMk(Exit exit, size_t pos, const T37 &t, int delta, bool bSpace);
84  void collapse(Exit exit, std::size_t pos, const T37 &t);
85  void loadB(const T37 &t, int count);
86 
87  void flipIndic(util::Rand &rand);
88  void digIndic(util::Rand &rand);
89 
90 private:
91  struct Erwin
92  {
93  Exist exA;
94  Exist exB;
95  T37 tile;
96  bool earlyCollapse;
97  Erwin() : earlyCollapse(false) {}
98  Erwin(const T37 &t) : tile(t), earlyCollapse(true) {}
99  };
100 
101  using ErwinQueue = std::list<std::optional<Erwin>>;
102 
103  Erwin &prepareSuperpos(Exit exit, std::size_t pos);
104  T37 popFrom(util::Rand &rand, Exit exit);
105  std::vector<T37> popExist(util::Rand &rand, Exist &exist, int need);
106  T37 popExist(util::Rand &rand, Exist &exA, Exist &exB);
107  std::vector<T37> popPolar(util::Rand &rand, Exist::Polar &polar, TileCount &stoch, int need);
108  T37 popScientific(util::Rand &rand);
109 
110 private:
111  util::Stactor<T37, 5> mDrids;
112  util::Stactor<T37, 5> mUrids;
113  int mKanCt = 0;
114  int mRemain = 136 - 14;
115 
116  TileCount mStockA;
117  TileCount mStockB;
118 
119  std::array<ErwinQueue, NUM_EXITS> mErwinQueues;
120 };
121 
122 int operator%(const util::Stactor<T37, 5> &indics, T34 t);
123 
124 
125 
126 } // namespace saki
127 
128 
129 
130 #endif // SAKI_MOUNT_H
Definition: mount.h:54
Definition: mount.h:24
Definition: rand.h:19
Definition: tile.h:25
Definition: tile_count.h:17
Definition: mount.h:19
Definition: ai.cpp:18
Definition: tile.h:353
Definition: mount.h:26
Stactor = statically allocated vector.
Definition: stactor.h:247