Libsaki
Core library of Pancake Mahjong
irs_ctrl.h
1 #ifndef SAKIIRS_CHANCE_H
2 #define SAKIIRS_CHANCE_H
3 
4 #include "table.h"
5 
6 #include <type_traits>
7 
8 
9 
10 namespace saki
11 {
12 
13 
14 
18 struct IrsResult
19 {
20  bool handled;
21  Girl::IrsCtrlGetter next; // getter of next controller in an IRS-Chain
22 };
23 
24 
25 
29 class IrsCtrl
30 {
31 public:
32  virtual ~IrsCtrl() = default;
33  virtual const Choices &choices() const = 0;
34  virtual IrsResult handle(Girl &girl, const Table &table, Mount &mount, const Action &action) = 0;
35 };
36 
37 
38 
42 template<typename G>
43 class IrsCtrlPlus : public IrsCtrl
44 {
45 public:
46  virtual IrsResult handle(G &girl, const Table &table, Mount &mount, const Action &action) = 0;
47 
48  IrsResult handle(Girl &girl, const Table &table, Mount &mount, const Action &action) final
49  {
50  return handle(static_cast<G &>(girl), table, mount, action);
51  }
52 };
53 
54 
55 
59 template<typename G>
60 class IrsCtrlCheck : public IrsCtrlPlus<G>
61 {
62 public:
64  {
65  mChoices.setIrsCheck(mode);
66  }
67 
68  const Choices &choices() const override
69  {
70  return mChoices;
71  }
72 
73  IrsResult handle(G &girl, const Table &table, Mount &mount, const Action &action) override
74  {
75  setMode(action.mask());
76  girl.onIrsChecked(table, mount);
77  return { true, nullptr };
78  }
79 
80  const IrsCheckItem &itemAt(int index) const
81  {
82  return mChoices.irsCheck().list.at(index);
83  }
84 
85  void setAbleAt(int index, bool v)
86  {
87  Choices::ModeIrsCheck mode = mChoices.irsCheck();
88  mode.list[static_cast<size_t>(index)].setAble(v);
89  mChoices.setIrsCheck(mode);
90  }
91 
92  void setOnAt(int index, bool v)
93  {
94  Choices::ModeIrsCheck mode = mChoices.irsCheck();
95  mode.list[static_cast<size_t>(index)].setOn(v);
96  mChoices.setIrsCheck(mode);
97  }
98 
99 private:
100  void setMode(unsigned mask)
101  {
102  Choices::ModeIrsCheck mode = mChoices.irsCheck();
103  for (size_t i = 0; i < mode.list.size(); i++) {
104  bool on = mask & (1 << (mode.list.size() - 1 - i));
105  mode.list[i].setOn(on);
106  }
107 
108  mChoices.setIrsCheck(mode);
109  }
110 
111 private:
112  Choices mChoices;
113 };
114 
115 
116 
120 template<typename G>
122 {
123 public:
125  : IrsCtrlCheck<G>(mode)
126  , mPtrToMem(mem)
127  {
128  }
129 
130  const Choices &choices() const override
131  {
132  return mCheck ? checkChoices() : mChoicesClick;
133  }
134 
135  const Choices &checkChoices() const
136  {
137  return IrsCtrlCheck<G>::choices();
138  }
139 
140  IrsResult handle(G &girl, const Table &table, Mount &mount, const Action &action) override
141  {
142  switch (action.act()) {
143  case ActCode::IRS_CLICK:
144  mCheck = true;
145  return { true, mPtrToMem };
146  case ActCode::IRS_CHECK:
147  mCheck = false;
148  return IrsCtrlCheck<G>::handle(girl, table, mount, action);
149  default:
150  return { false, nullptr };
151  }
152  }
153 
154  void setClickHost(Choices normal)
155  {
156  mChoicesClick.setIrsClick(normal);
157  }
158 
159 private:
160  Choices mChoicesClick;
161  bool mCheck = false;
162  IrsCtrlClickCheck G::*mPtrToMem;
163 };
164 
165 
166 
167 } // namespace saki
168 
169 
170 
171 #endif // SAKIIRS_CHANCE_H
Definition: irs_ctrl.h:43
Definition: irs_ctrl.h:121
Definition: mount.h:54
Definition: choices.h:13
Definition: table.h:87
Choice set of one player.
Definition: choices.h:122
Definition: irs_ctrl.h:29
Definition: action.h:27
Definition: irs_ctrl.h:60
Definition: ai.cpp:18
Definition: choices.h:130
Wrapper of a "T Girl::*" value where T implements IrsCtrl.
Definition: girl.h:77
Definition: irs_ctrl.h:18
Base class for skill implementation.
Definition: girl.h:35