]>
Commit | Line | Data |
---|---|---|
1 | #include "sliding_tile_lib.h" | |
2 | ||
3 | #include <istream> | |
4 | #include <stdexcept> | |
5 | ||
6 | signed char adjacent[BOARD_SIZE][5] = { | |
7 | 1, 4, -1, -1, -1, | |
8 | 0, 2, 5, -1, -1, | |
9 | 1, 3, 6, -1, -1, | |
10 | 2, 7, -1, -1, -1, | |
11 | 0, 5, 8, -1, -1, | |
12 | 1, 4, 6, 9, -1, | |
13 | 2, 5, 7, 10, -1, | |
14 | 3, 6, 11, -1, -1, | |
15 | 4, 9, 12, -1, -1, | |
16 | 5, 8, 10, 13, -1, | |
17 | 6, 9, 11, 14, -1, | |
18 | 7, 10, 15, -1, -1, | |
19 | 8, 13, -1, -1, -1, | |
20 | 9, 12, 14, -1, -1, | |
21 | 10, 13, 15, -1, -1, | |
22 | 11, 14, -1, -1, -1, | |
23 | }; | |
24 | ||
25 | bool Board::is_valid() const { | |
26 | bool seen[BOARD_SIZE]; | |
27 | for (int i = 0; i < BOARD_SIZE; i++) { | |
28 | seen[i] = false; | |
29 | } | |
30 | ||
31 | for (int i = 0; i < BOARD_SIZE; i++) { | |
32 | if (board[i] < 0 || board[i] >= BOARD_SIZE || seen[board[i]]) { | |
33 | return false; | |
34 | } | |
35 | seen[board[i]] = true; | |
36 | } | |
37 | ||
38 | // Redundant because pigeon-hole-principle, but check anyway | |
39 | for (int i = 0; i < BOARD_SIZE; i++) { | |
40 | if (!seen[i]) { | |
41 | return false; | |
42 | } | |
43 | } | |
44 | ||
45 | return true; | |
46 | } | |
47 | ||
48 | std::istream& operator>>(std::istream& is, Board& board) { | |
49 | for (int i = 0; i < BOARD_SIZE; i++) { | |
50 | if (!is.good()) { | |
51 | is.setstate(std::istream::failbit); | |
52 | break; | |
53 | } | |
54 | if (i > 0 && is.get() != ',') { | |
55 | is.setstate(std::istream::failbit); | |
56 | break; | |
57 | } | |
58 | int numeric; | |
59 | is >> numeric; | |
60 | board.board[i] = numeric; | |
61 | } | |
62 | if (!board.is_valid()) { | |
63 | is.setstate(std::istream::failbit); | |
64 | } | |
65 | return is; | |
66 | } | |
67 | ||
68 | signed char Board::hole() const { | |
69 | for (int i = 0; i < BOARD_SIZE; i++) { | |
70 | if (board[i] == 0) { | |
71 | return i; | |
72 | } | |
73 | } | |
74 | throw std::runtime_error("Board with no hole"); | |
75 | } |