src/game/npuzzle_data/lib.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../util/traits/others/lib.hpp" | ||
| 4 | |||
| 5 | namespace tifa_libs { | ||
| 6 | |||
| 7 | // n = k*k-1 | ||
| 8 | class npuzzle_data { | ||
| 9 | static inline vecu fin_node, fin_pos; | ||
| 10 | static inline vvecu costs; | ||
| 11 | |||
| 12 | u32 k, p0{0}, cost_{0}; | ||
| 13 | |||
| 14 | public: | ||
| 15 | static inline u32 limit = UINT32_MAX; | ||
| 16 | 28 | static CEXP void set_fin(u32 k, vecu CR fin) NE { | |
| 17 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
|
28 | assert(fin.size() == k * k), fin_node = fin, fin_pos.resize(k * k); |
| 18 |
2/2✓ Branch 2 taken 252 times.
✓ Branch 3 taken 28 times.
|
280 | flt_ (u32, i, 0, k * k) fin_pos[fin_node[i]] = i; |
| 19 | 28 | costs.resize(k * k, vecu(k * k)); | |
| 20 |
2/2✓ Branch 0 taken 224 times.
✓ Branch 1 taken 28 times.
|
252 | flt_ (u32, p, 1, k * k) |
| 21 |
2/2✓ Branch 4 taken 2016 times.
✓ Branch 5 taken 224 times.
|
2240 | flt_ (u32, q, 0, k * k) costs[p][q] = u32(abs(i32(p / k) - i32(q / k)) + abs(i32(p % k) - i32(q % k))) / 2 + (p != q); |
| 22 | 28 | } | |
| 23 | |||
| 24 | vecu node; | ||
| 25 | strn moves; | ||
| 26 | |||
| 27 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
|
84 | CEXPE npuzzle_data(u32 k) NE : k{k}, node(k* k), moves() { assert(k < 65535); } |
| 28 | |||
| 29 | 5989220 | ND CEXP auto CR cost() CNE { return cost_; } | |
| 30 | 164484 | ND CEXP bool solved() CNE { return node == fin_node; } | |
| 31 | 164456 | ND CEXP vec<npuzzle_data> next() CNE { | |
| 32 |
2/2✓ Branch 1 taken 27 times.
✓ Branch 2 taken 164429 times.
|
164456 | cchr lst = moves.empty() ? ' ' : moves.back(); |
| 33 | 164456 | strn nxts; | |
| 34 |
4/4✓ Branch 0 taken 116051 times.
✓ Branch 1 taken 48405 times.
✓ Branch 2 taken 73947 times.
✓ Branch 3 taken 42104 times.
|
164456 | if (p0 / k && lst != 'D') nxts += 'U'; |
| 35 |
4/4✓ Branch 0 taken 101695 times.
✓ Branch 1 taken 62761 times.
✓ Branch 2 taken 61689 times.
✓ Branch 3 taken 40006 times.
|
164456 | if (p0 / k != k - 1 && lst != 'U') nxts += 'D'; |
| 36 |
4/4✓ Branch 0 taken 115678 times.
✓ Branch 1 taken 48778 times.
✓ Branch 2 taken 73339 times.
✓ Branch 3 taken 42339 times.
|
164456 | if (p0 % k && lst != 'R') nxts += 'L'; |
| 37 |
4/4✓ Branch 0 taken 101951 times.
✓ Branch 1 taken 62505 times.
✓ Branch 2 taken 61971 times.
✓ Branch 3 taken 39980 times.
|
164456 | if (p0 % k != k - 1 && lst != 'L') nxts += 'R'; |
| 38 | 164456 | vec<npuzzle_data> ans; | |
| 39 |
2/2✓ Branch 5 taken 270946 times.
✓ Branch 6 taken 164456 times.
|
435402 | for (cchr d : nxts) { |
| 40 | 270946 | auto nxt = *this; | |
| 41 |
1/2✓ Branch 1 taken 270946 times.
✗ Branch 2 not taken.
|
270946 | if (nxt.move(d); nxt.cost_ <= limit) ans.push_back(nxt); |
| 42 | 270946 | } | |
| 43 | 164456 | return ans; | |
| 44 | 164456 | } | |
| 45 | 270946 | CEXP void move(chr dir) NE { | |
| 46 | 270946 | moves.push_back(dir), ++cost_; | |
| 47 | 270946 | cu32 pre = p0; | |
| 48 |
4/5✓ Branch 0 taken 73947 times.
✓ Branch 1 taken 61689 times.
✓ Branch 2 taken 73339 times.
✓ Branch 3 taken 61971 times.
✗ Branch 4 not taken.
|
270946 | switch (dir) { |
| 49 | 73947 | case 'U': p0 -= k; break; | |
| 50 | 61689 | case 'D': p0 += k; break; | |
| 51 | 73339 | case 'L': --p0; break; | |
| 52 | 61971 | case 'R': ++p0; break; | |
| 53 | } | ||
| 54 | 270946 | cost_ -= costs[pre][fin_pos[node[pre]]] + costs[p0][fin_pos[node[p0]]]; | |
| 55 | 270946 | cost_ += costs[pre][fin_pos[node[p0]]] + costs[p0][fin_pos[node[pre]]]; | |
| 56 | 270946 | swap(node[pre], node[p0]); | |
| 57 | 270946 | } | |
| 58 | 8201936 | CEXP auto operator<=>(npuzzle_data CR r) CNE { return node <=> r.node; } | |
| 59 | CEXP bool operator==(npuzzle_data CR r) CNE { return std::is_eq(*this <=> r); } | ||
| 60 | 28 | friend auto& operator>>(istream_c auto& is, npuzzle_data& np) NE { | |
| 61 |
2/2✓ Branch 6 taken 252 times.
✓ Branch 7 taken 28 times.
|
280 | for (auto& i : np.node) is >> i; |
| 62 | 28 | np.p0 = u32(find(np.node, 0) - begin(np.node)); | |
| 63 |
2/2✓ Branch 1 taken 252 times.
✓ Branch 2 taken 28 times.
|
280 | flt_ (u32, p, 0, (u32)np.node.size()) |
| 64 |
2/2✓ Branch 1 taken 224 times.
✓ Branch 2 taken 28 times.
|
252 | if (np.node[p]) np.cost_ += costs[p][fin_pos[np.node[p]]]; |
| 65 | 28 | return is; | |
| 66 | } | ||
| 67 | }; | ||
| 68 | |||
| 69 | } // namespace tifa_libs | ||
| 70 |