]>
git.scottworley.com Git - slidingtile/blob - sliding_tile_lib.cc
1 #include "sliding_tile_lib.h"
10 signed char Step::adjacent
[BOARD_SIZE
][5] = {
29 bool Board::is_valid() const {
30 bool seen
[BOARD_SIZE
];
31 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
35 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
36 if (board
[i
] < 0 || board
[i
] >= BOARD_SIZE
|| seen
[board
[i
]]) {
39 seen
[board
[i
]] = true;
42 // Redundant because pigeon-hole-principle, but check anyway
43 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
52 bool Board::operator==(const Board
& o
) const {
53 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
54 if (board
[i
] != o
.board
[i
]) {
61 bool Board::operator!=(const Board
& o
) const {
62 return !operator==(o
);
65 std::istream
& operator>>(std::istream
& is
, Board
& board
) {
66 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
68 is
.setstate(std::istream::failbit
);
71 if (i
> 0 && is
.get() != ',') {
72 is
.setstate(std::istream::failbit
);
77 board
.board
[i
] = numeric
;
79 if (!board
.is_valid()) {
80 is
.setstate(std::istream::failbit
);
85 std::ostream
& operator<<(std::ostream
& os
, const Board
& board
) {
86 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
90 os
<< int(board
.board
[i
]);
95 signed char Board::hole() const {
96 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
101 throw std::runtime_error("Board with no hole");
104 InvertedBoard
Board::invert() const {
106 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
107 inv
.pos
[board
[i
]] = i
;
112 int Board::distance(const Board
& o
) const {
113 return distance(o
.invert());
116 int Board::distance(const InvertedBoard
& invo
) const {
118 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
119 dist
+= std::abs(i
% BOARD_DIM
- invo
.pos
[board
[i
]] % BOARD_DIM
) +
120 std::abs(i
/ BOARD_DIM
- invo
.pos
[board
[i
]] / BOARD_DIM
);
125 std::vector
<Step
*> Step::successors(std::shared_ptr
<Step
> shared_this
) {
126 std::vector
<Step
*> suc
;
127 signed char hole_pos
= board
.hole();
128 for (int i
= 0; adjacent
[hole_pos
][i
] > 0; i
++) {
129 suc
.emplace_back(new Step
{board
, shared_this
});
130 std::swap(suc
.back()->board
.board
[hole_pos
], suc
.back()->board
.board
[adjacent
[hole_pos
][i
]]);
135 std::ostream
& operator<<(std::ostream
& os
, const Step
& step
) {
136 if (step
.prev
!= nullptr) {
138 signed char this_hole
= step
.board
.hole();
139 signed char prev_hole
= step
.prev
->board
.hole();
140 os
<< int(step
.board
.board
[prev_hole
]) << " ";
141 switch (this_hole
- prev_hole
) {
142 case -1: os
<< "right"; break;
143 case 1: os
<< "left"; break;
144 case -BOARD_DIM
: os
<< "down"; break;
145 case BOARD_DIM
: os
<< "up"; break;
146 default: os
<< "somehow!"; break;