-
Notifications
You must be signed in to change notification settings - Fork 0
/
moveiterator.h
62 lines (56 loc) · 1.54 KB
/
moveiterator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#pragma once
#include "board.h"
#include "move.h"
#include "hashset.h"
class MoveIterator { //only returns valid moves...
const Board & base_board; //base board
Board after; // board after making the move
Move move;
bool unique;
HashSet hashes;
public:
MoveIterator(const Board & b, int Unique = -1) : base_board(b), move(M_SWAP, b.orient()) {
unique = (Unique == -1 ? base_board.num_moves() <= Board::unique_depth : Unique);
if(base_board.won() >= 0){
move = Move(36, 8); //already done
} else {
if(unique)
hashes.init(base_board.moves_avail());
++(*this); //find the first valid move
}
}
const Board & board() const { return after; }
const Move & operator * () const { return move; }
const Move * operator -> () const { return & move; }
bool done() const { return (move.l >= 36); }
bool operator == (const MoveIterator & rhs) const { return (move == rhs.move); }
bool operator != (const MoveIterator & rhs) const { return (move != rhs.move); }
MoveIterator & operator ++ (){ //prefix form
while(true){
move.r++;
if(move.r >= 8){
move.r = 0;
do{
move.l++;
if(move.l >= 36) //done
return *this;
}while(!base_board.valid_move_fast(move));
}
after = base_board;
bool move_success = after.move(move);
assert(move_success);
if(unique){
uint64_t h = after.hash();
if(!hashes.add(h))
continue;
}
break;
}
return *this;
}
MoveIterator operator ++ (int){ //postfix form, discouraged from being used
MoveIterator newit(*this);
++(*this);
return newit;
}
};