Libsaki
Core library of Pancake Mahjong
table.h
1 #ifndef SAKI_TABLE_H
2 #define SAKI_TABLE_H
3 
4 #include "choices.h"
5 #include "kan_ctx.h"
6 #include "mount.h"
7 #include "table_env.h"
8 #include "table_view.h"
9 #include "table_observer.h"
10 #include "girl.h"
11 #include "../form/tile_count.h"
12 #include "../util/rand.h"
13 
14 #include <memory>
15 #include <iostream>
16 
17 
18 
19 namespace saki
20 {
21 
22 
23 
24 struct Furiten
25 {
26  bool sutehai = false;
27  bool doujun = false;
28  bool riichi = false;
29  bool any() const { return sutehai || doujun || riichi; }
30  bool none() const { return !any(); }
31 };
32 
33 
34 
39 {
40 protected:
41  TablePrivate(std::array<int, 4> points,
42  Rule rule, Who tempDealer, const TableEnv &env);
43  explicit TablePrivate(const TablePrivate &copy) = default;
44  TablePrivate &operator=(const TablePrivate &assign) = delete;
45  ~TablePrivate() = default;
46 
47 protected:
48  util::Rand mRand;
49  Mount mMount;
50  const Rule mRule;
51  KanCtx mKanContext;
52  TableFocus mFocus;
53 
54  std::array<int, 4> mPoints;
55  std::array<int, 4> mRiichiHans;
56  std::array<int, 4> mLayPositions;
57  std::array<Furiten, 4> mFuritens;
58  std::array<Hand, 4> mHands;
59  std::array<River, 4> mRivers;
60  std::array<std::bitset<24>, 4> mPickeds;
61  std::array<Choices, 4> mChoicess;
62  std::array<Action, 4> mActionInbox;
63  std::array<int, 4> mNonces;
64 
65  int mRound = 0;
66  int mExtraRound = -1; // work with beforeEast1()
67  int mDeposit = 0;
68  int mDice;
69 
70  Who mDealer;
71  Who mInitDealer;
72 
73  bool mAllLast = false;
74  bool mToChangeDealer = false;
75  bool mPrevIsRyuu = false;
76  bool mToEstablishRiichi;
77  bool mToFlip;
78 
79  std::bitset<4> mIppatsuFlags;
80  std::array<std::bitset<34>, 4> mGenbutsuFlags;
81 
82  const TableEnv &mEnv;
83 };
84 
85 
86 
87 class Table : private TablePrivate
88 {
89 public:
90  enum class CheckResult { OK, EXPIRED, ILLEGAL };
91 
92  struct InitConfig
93  {
94  std::array<int, 4> points;
95  std::array<std::unique_ptr<Girl>, 4> girls;
96  Rule rule;
97  Who tempDealer;
98  };
99 
100  explicit Table(InitConfig config, std::vector<TableObserver *> obs, const TableEnv &env);
101  explicit Table(const Table &orig, std::vector<TableObserver *> obs);
102 
103  Table(const Table &copy) = delete;
104  Table &operator=(const Table &assign) = delete;
105 
106  void start();
107  void action(Who who, const Action &act, int nonce);
108  CheckResult check(Who who, const Action &action, int nonce) const;
109 
110  const Hand &getHand(Who who) const;
111  const River &getRiver(Who who) const;
112  const Girl &getGirl(Who who) const;
113  std::unique_ptr<TableView> getView(Who who) const;
114  const Furiten &getFuriten(Who who) const;
115  const std::array<int, 4> &getPoints() const;
116  int getRound() const;
117  int getExtraRound() const;
118  TileCount visibleRemain(Who who) const;
119  int riverRemain(T34 t) const;
120  int getRank(Who who) const;
121  const TableFocus &getFocus() const;
122  const T37 &getFocusTile() const;
123  bool genbutsu(Who whose, T34 t) const;
124  bool lastDiscardLay() const;
125  bool riichiEstablished(Who who) const;
126  bool duringKan() const;
127  bool isAllLast() const;
128  bool beforeEast1() const;
129  bool inIppatsuCycle() const;
130  bool anyActivated() const;
131 
132  Who findGirl(Girl::Id id) const;
133  Who getDealer() const;
134  int getDice() const;
135  int getDeposit() const;
136  int getSelfWind(Who who) const;
137  int getRoundWind() const;
138  int getNonce(Who who) const;
139  const Rule &getRule() const;
140  FormCtx getFormCtx(Who who) const;
141  const Choices &getChoices(Who who) const;
142  const Mount &getMount() const;
143  const TableEnv &getEnv() const;
144 
145  void popUp(Who who) const;
146 
147 private:
148  bool checkLegality(Who who, const Action &action) const;
149  void process();
150  void singleAction(Who who, const Action &act);
151 
152  void setupObservers(const std::vector<TableObserver *> obs);
153  void nextRound();
154  void clean();
155  void rollDice();
156  void deal();
157  void flipKandoraIndic();
158  void notifyFlipped();
159  void tryDraw(Who who);
160  void swapOut(Who who, const T37 &out);
161  void spinOut(Who who);
162  void barkOut(Who who, const T37 &out);
163  void discardEffects(Who who, bool spin);
164  void declareRiichi(Who who, const Action &action);
165  bool finishRiichi();
166  void chii(Who who, ActCode dir, const T37 &out, bool showAka5);
167  void pon(Who who, const T37 &out, int showAka5);
168  void daiminkan(Who who);
169  void pick();
170  void ankan(Who who, T34 tile);
171  void kakan(Who who, int barkId);
172  void finishKan(Who who);
173  void activate();
174  void everyonePassed();
175  bool filterChoices();
176  bool kanOverflow(Who kanner);
177  bool noBarkYet() const;
178  bool checkDeathWinds() const;
179  void checkChankan(bool only13 = false);
180  void checkBarkRon();
181  void checkSutehaiFuriten();
182  void passRon(Who who);
183  bool checkNagashimangan(Who who) const;
184  void exhaustRound(RoundResult result, const util::Stactor<Who, 4> &openers);
185  void finishRound(const util::Stactor<Who, 4> &openers, Who gunner);
186  void checkNextRound();
187  void endTable();
188 
189 private:
190  std::array<std::unique_ptr<Girl>, 4> mGirls;
191  std::vector<TableObserver *> mObservers;
192 };
193 
194 
195 
196 } // namespace saki
197 
198 
199 
200 #endif // SAKI_TABLE_H
Default-copy-constructable part of Table.
Definition: table.h:38
Definition: table.h:92
Definition: rule.h:13
Definition: form_ctx.h:11
Definition: table_focus.h:13
Definition: mount.h:54
Definition: table.h:87
Definition: rand.h:19
Definition: tile.h:25
Definition: kan_ctx.h:13
Definition: tile_count.h:17
Choice set of one player.
Definition: choices.h:122
Definition: table_env.h:11
Definition: action.h:27
Definition: ai.cpp:18
Definition: table.h:24
Definition: hand.h:17
Definition: tile.h:353
Stactor = statically allocated vector.
Definition: stactor.h:247
Base class for skill implementation.
Definition: girl.h:35
Definition: who.h:14