4 #include "../util/assume.h" 5 #include "../util/stactor.h" 6 #include "../util/int_iter.h" 21 enum class Suit { M = 0, P = 1, S = 2, F = 3, Y = 4 };
23 enum class Wait { NONE, ISORIDE, BIBUMP, CLAMP, SIDE, BIFACE };
28 static char charOf(Suit s)
31 case Suit::M:
return 'm';
32 case Suit::P:
return 'p';
33 case Suit::S:
return 's';
34 case Suit::F:
return 'f';
35 case Suit::Y:
return 'y';
40 static Suit suitOf(
char c)
42 switch (std::tolower(c)) {
43 case 'm':
return Suit::M;
44 case 'p':
return Suit::P;
45 case 's':
return Suit::S;
46 case 'f':
return Suit::F;
47 case 'y':
return Suit::Y;
52 static bool isValidSuit(
char c)
54 c =
static_cast<char>(std::tolower(c));
55 return c ==
'm' || c ==
'p' || c ==
's' || c ==
'f' || c ==
'y';
66 explicit T34(
int id34)
69 assert(0 <= id34 && id34 < 34);
70 assume_opt_out(0 <= id34 && id34 < 34);
73 explicit T34(Suit suit,
int val)
74 : mId34(id34Of(suit, val))
78 constexpr
explicit T34(
int val, Suit suit)
79 : mId34(id34Of(val, suit))
83 explicit T34(
const char *str)
84 : mId34(id34Of(suitOf(str[1]), str[0] -
'0'))
86 assert(str[2] ==
'\0');
89 T34(
const T34 ©) =
default;
90 T34 &operator=(
const T34 &assign) =
default;
101 unsigned uId34()
const 103 return static_cast<unsigned>(id34());
109 assert(mInitialized);
111 if (0 <= mId34 && mId34 < 9)
114 if (9 <= mId34 && mId34 < 18)
117 if (18 <= mId34 && mId34 < 27)
120 if (27 <= mId34 && mId34 < 31)
123 if (31 <= mId34 && mId34 < 34)
132 assert(mInitialized);
134 if (0 <= mId34 && mId34 < 27)
135 return mId34 % 9 + 1;
137 if (27 <= mId34 && mId34 < 31)
138 return mId34 - 27 + 1;
140 if (31 <= mId34 && mId34 < 34)
141 return mId34 - 31 + 1;
146 const char *str34()
const 148 static const std::array<const char *, 34> STRS {
149 "1m",
"2m",
"3m",
"4m",
"5m",
"6m",
"7m",
"8m",
"9m",
150 "1p",
"2p",
"3p",
"4p",
"5p",
"6p",
"7p",
"8p",
"9p",
151 "1s",
"2s",
"3s",
"4s",
"5s",
"6s",
"7s",
"8s",
"9s",
152 "1f",
"2f",
"3f",
"4f",
156 return STRS[uId34()];
161 return suit() == Suit::F || suit() == Suit::Y;
171 return isNum() && (val() == 1 || val() == 9);
174 bool isNum1928()
const 176 return isNum() && (val() == 1 || val() == 2 || val() == 8 || val() == 9);
181 return isZ() || val() == 1 || val() == 9;
184 bool isYakuhai(
int selfWind,
int roundWind)
const 186 assert(1 <= selfWind && selfWind <= 4);
187 assert(1 <= roundWind && roundWind <= 4);
189 return suit() == Suit::Y
190 || (suit() == Suit::F && (val() == selfWind || val() == roundWind));
193 bool operator==(
T34 rhs)
const 195 return id34() == rhs.id34();
198 bool operator!=(
T34 rhs)
const 200 return !(*
this == rhs);
203 bool operator<(
T34 rhs)
const 205 return id34() < rhs.id34();
208 bool operator|(
T34 up)
const 210 return isNum() && suit() == up.suit() && val() + 1 == up.val();
213 bool operator||(
T34 up)
const 215 return isNum() && suit() == up.suit() && val() + 2 == up.val();
218 bool operator^(
T34 up)
const 220 return isNum() && suit() == up.suit() && val() + 3 == up.val();
223 bool operator%(
T34 dora)
const 225 return suit() == dora.suit() && val() % period() + 1 == dora.val();
230 assert(isNum() && val() >= 2);
231 assume_opt_out(isNum() && val() >= 2);
232 return T34(suit(), val() - 1);
237 assert(isNum() && val() >= 3);
238 assume_opt_out(isNum() && val() >= 3);
239 return T34(suit(), val() - 2);
244 assert(isNum() && 1 <= val() && val() <= 8);
245 assume_opt_out(isNum() && 1 <= val() && val() <= 8);
246 return T34(suit(), val() + 1);
251 assert(isNum() && 1 <= val() && val() <= 7);
252 assume_opt_out(isNum() && 1 <= val() && val() <= 7);
253 return T34(suit(), val() + 2);
258 return T34(suit(), val() % period() + 1);
261 T34 indicator()
const 267 return T34(suit(), (val() - 1 + period() - 1) % period() + 1);
286 Wait waitAsSequence(
T34 pick)
const 288 if (suit() != pick.suit())
295 if ((va == 1 && vb == 3) || (va == 7 && vb == 7))
303 if (va == vb || va + 2 == vb)
310 static int id34Of(Suit suit,
int val)
312 assert(1 <= val && val <= 9);
313 assume_opt_out(1 <= val && val <= 9);
315 return id34Of(val, suit);
318 static constexpr
int id34Of(
int val, Suit suit)
320 return suit == Suit::F ? 27 + val - 1
321 : suit == Suit::Y ? 31 + val - 1
322 : 9 *
static_cast<int>(suit) + val - 1;
328 bool mInitialized =
true;
332 inline std::ostream &operator<<(std::ostream &os,
T34 t)
334 return os << t.str34();
338 inline std::ostream &operator<<(std::ostream &os, const util::Stactor<T34, MAX> &ts)
340 for (
size_t i = 0; i < ts.size(); i++) {
342 if (i < ts.size() - 1 && ts[i].suit() != ts[i + 1].suit())
343 os << T34::charOf(ts[i].suit());
346 os << T34::charOf(ts.back().suit());
356 static bool isValidStr(
const char *str)
365 return '0' <= str[0] && str[0] <=
'9';
367 return '1' <= str[0] && str[0] <=
'4';
369 return '1' <= str[0] && str[0] <=
'3';
381 T37(
const T37 ©) =
default;
383 explicit T37(
int id34)
389 explicit T37(Suit suit,
int val)
390 :
T34(suit, val == 0 ? 5 : val)
395 constexpr
explicit T37(
int val, Suit suit)
396 :
T34(val == 0 ? 5 : val, suit)
401 explicit T37(
const char *str)
402 :
T34(suitOf(str[1]), str[0] ==
'0' ? 5 : str[0] -
'0')
403 , mAka5(str[0] ==
'0')
405 assert(str[2] ==
'\0');
417 case Suit::M:
return "0m";
418 case Suit::P:
return "0p";
419 case Suit::S:
return "0s";
420 default: unreached();
432 bool looksSame(
const T37 &rhs)
const 434 return id34() == rhs.id34() && mAka5 == rhs.mAka5;
440 assume_opt_out(val() == 5);
441 return T37(id34(),
true);
444 T37 toInverse5()
const 447 assume_opt_out(val() == 5);
448 return T37(id34(), !mAka5);
452 explicit T37(
int id34,
bool aka5)
465 for (
const T37 &ind : inds)
471 inline std::ostream &operator<<(std::ostream &os,
const T37 &t)
473 return os << t.
str37();
477 inline std::ostream &operator<<(std::ostream &os, const util::Stactor<T37, MAX> &ts)
479 for (
size_t i = 0; i < ts.size(); i++) {
480 os << (ts[i].isAka5() ? 0 : ts[i].val());
481 if (i < ts.size() - 1 && ts[i].suit() != ts[i + 1].suit())
482 os << T34::charOf(ts[i].suit());
485 os << T34::charOf(ts.back().suit());
497 constexpr
T34 operator""_m(
unsigned long long val)
499 return T34(static_cast<int>(val), Suit::M);
502 constexpr
T34 operator""_p(
unsigned long long val)
504 return T34(static_cast<int>(val), Suit::P);
507 constexpr
T34 operator""_s(
unsigned long long val)
509 return T34(static_cast<int>(val), Suit::S);
512 constexpr
T34 operator""_f(
unsigned long long val)
514 return T34(static_cast<int>(val), Suit::F);
517 constexpr
T34 operator""_y(
unsigned long long val)
519 return T34(static_cast<int>(val), Suit::Y);
522 const std::array<T34, 13> YAO13
524 1_m, 9_m, 1_p, 9_p, 1_s, 9_s,
525 1_f, 2_f, 3_f, 4_f, 1_y, 2_y, 3_y
528 const std::array<T34, 7> Z7
530 1_f, 2_f, 3_f, 4_f, 1_y, 2_y, 3_y
556 constexpr
T37 operator""_m(
unsigned long long val)
558 return T37(static_cast<int>(val), Suit::M);
561 constexpr
T37 operator""_p(
unsigned long long val)
563 return T37(static_cast<int>(val), Suit::P);
566 constexpr
T37 operator""_s(
unsigned long long val)
568 return T37(static_cast<int>(val), Suit::S);
571 constexpr
T37 operator""_f(
unsigned long long val)
573 return T37(static_cast<int>(val), Suit::F);
576 constexpr
T37 operator""_y(
unsigned long long val)
578 return T37(static_cast<int>(val), Suit::Y);
581 const std::array<T37, 37> ORDER37
583 1_m, 2_m, 3_m, 4_m, 0_m, 5_m, 6_m, 7_m, 8_m, 9_m,
584 1_p, 2_p, 3_p, 4_p, 0_p, 5_p, 6_p, 7_p, 8_p, 9_p,
585 1_s, 2_s, 3_s, 4_s, 0_s, 5_s, 6_s, 7_s, 8_s, 9_s,
586 1_f, 2_f, 3_f, 4_f, 1_y, 2_y, 3_y
599 #endif // SAKI_TILE_H T37()
Garbage value.
Definition: tile.h:376
Definition: int_iter.h:54
const char * str37() const
String representation of the tile.
Definition: tile.h:413
Stactor = statically allocated vector.
Definition: stactor.h:247