]>
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 bool Board::operator<(const Board
& o
) const {
66 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
67 if (board
[i
] < o
.board
[i
]) {
69 } else if (board
[i
] > o
.board
[i
]) {
76 std::istream
& operator>>(std::istream
& is
, Board
& board
) {
77 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
79 is
.setstate(std::istream::failbit
);
82 if (i
> 0 && is
.get() != ',') {
83 is
.setstate(std::istream::failbit
);
88 board
.board
[i
] = numeric
;
90 if (!board
.is_valid()) {
91 is
.setstate(std::istream::failbit
);
96 std::ostream
& operator<<(std::ostream
& os
, const Board
& board
) {
97 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
101 os
<< int(board
.board
[i
]);
106 signed char Board::hole() const {
107 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
112 throw std::runtime_error("Board with no hole");
115 InvertedBoard
Board::invert() const {
117 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
118 inv
.pos
[board
[i
]] = i
;
123 int Board::distance(const Board
& o
) const {
124 return distance(o
.invert());
127 int Board::distance(const InvertedBoard
& invo
) const {
129 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
130 dist
+= std::abs(i
% BOARD_DIM
- invo
.pos
[board
[i
]] % BOARD_DIM
) +
131 std::abs(i
/ BOARD_DIM
- invo
.pos
[board
[i
]] / BOARD_DIM
);
136 std::vector
<Step
*> Step::successors(std::shared_ptr
<Step
> shared_this
) const {
137 std::vector
<Step
*> suc
;
138 signed char hole_pos
= board
.hole();
139 for (int i
= 0; adjacent
[hole_pos
][i
] > 0; i
++) {
140 suc
.emplace_back(new Step
{board
, shared_this
});
141 std::swap(suc
.back()->board
.board
[hole_pos
], suc
.back()->board
.board
[adjacent
[hole_pos
][i
]]);
146 std::ostream
& operator<<(std::ostream
& os
, const Step
& step
) {
147 if (step
.prev
!= nullptr) {
149 signed char this_hole
= step
.board
.hole();
150 signed char prev_hole
= step
.prev
->board
.hole();
151 os
<< int(step
.board
.board
[prev_hole
]) << " ";
152 switch (this_hole
- prev_hole
) {
153 case -1: os
<< "right"; break;
154 case 1: os
<< "left"; break;
155 case -BOARD_DIM
: os
<< "down"; break;
156 case BOARD_DIM
: os
<< "up"; break;
157 default: os
<< "somehow!"; break;