]>
git.scottworley.com Git - slidingtile/blob - sliding_tile_lib.cc
82402a5a185cd49453f17318705c9a81a805da77
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 std::istream
& operator>>(std::istream
& is
, Board
& board
) {
53 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
55 is
.setstate(std::istream::failbit
);
58 if (i
> 0 && is
.get() != ',') {
59 is
.setstate(std::istream::failbit
);
64 board
.board
[i
] = numeric
;
66 if (!board
.is_valid()) {
67 is
.setstate(std::istream::failbit
);
72 std::ostream
& operator<<(std::ostream
& os
, const Board
& board
) {
73 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
77 os
<< int(board
.board
[i
]);
82 signed char Board::hole() const {
83 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
88 throw std::runtime_error("Board with no hole");
91 InvertedBoard
Board::invert() const {
93 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
94 inv
.pos
[board
[i
]] = i
;
99 int Board::distance(const Board
& o
) const {
100 return distance(o
.invert());
103 int Board::distance(const InvertedBoard
& invo
) const {
105 for (int i
= 0; i
< BOARD_SIZE
; i
++) {
106 dist
+= std::abs(i
% BOARD_DIM
- invo
.pos
[board
[i
]] % BOARD_DIM
) +
107 std::abs(i
/ BOARD_DIM
- invo
.pos
[board
[i
]] / BOARD_DIM
);
112 std::vector
<Step
*> Step::successors(std::shared_ptr
<Step
> shared_this
) {
113 std::vector
<Step
*> suc
;
114 signed char hole_pos
= board
.hole();
115 for (int i
= 0; adjacent
[hole_pos
][i
] > 0; i
++) {
116 suc
.emplace_back(new Step
{board
, shared_this
});
117 std::swap(suc
.back()->board
.board
[hole_pos
], suc
.back()->board
.board
[adjacent
[hole_pos
][i
]]);
122 std::ostream
& operator<<(std::ostream
& os
, const Step
& step
) {
123 if (step
.prev
!= nullptr) {
125 signed char this_hole
= step
.board
.hole();
126 signed char prev_hole
= step
.prev
->board
.hole();
127 os
<< int(step
.board
.board
[prev_hole
]) << " ";
128 switch (this_hole
- prev_hole
) {
129 case -1: os
<< "right"; break;
130 case 1: os
<< "left"; break;
131 case -BOARD_DIM
: os
<< "down"; break;
132 case BOARD_DIM
: os
<< "up"; break;
133 default: os
<< "somehow!"; break;