-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnode.hpp
98 lines (91 loc) · 3.62 KB
/
node.hpp
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef NODE_HPP
#define NODE_HPP
#include <memory>
#include <mutex>
#include "gamestate.hpp"
struct Node {
const NodePtr previousNode;
ExtendedSteps move;
const int depth;
const GameState gameState;
const Result result;
mutable std::list<std::weak_ptr<Node> > children;
mutable std::mutex children_mutex;
explicit Node(NodePtr previousNode_,const ExtendedSteps& move_,const GameState& gameState_);
const Node& root() const;
bool isGameStart() const;
bool inSetup() const;
Placements playedPlacements() const;
std::string toPlyString() const;
std::string toPlyString(const Node& root) const;
std::string nextPlyString() const;
std::string toString() const;
std::vector<std::weak_ptr<Node> > ancestors(const Node* const final=nullptr) const;
int numMovesBefore(const Node* descendant) const;
bool isAncestorOfOrSameAs(const Node* descendant) const;
NodePtr findClosestChild(const NodePtr& descendant) const;
MoveLegality legalMove(const GameState& resultingState) const;
MoveLegality legalMove(const ExtendedSteps& move) const;
bool legalPartialMove(const ExtendedSteps& move) const;
bool hasLegalMoves(const GameState& startingState) const;
Result detectGameEnd() const;
int childIndex() const;
int cumulativeChildIndex() const;
NodePtr child(const int index) const;
bool hasChild() const;
int numChildren() const;
size_t maxChildSteps() const;
size_t maxDescendantSteps() const;
std::pair<NodePtr,int> findPartialMatchingChild(const Placements& placements) const;
std::pair<NodePtr,int> findPartialMatchingChild(const ExtendedSteps& steps) const;
std::pair<NodePtr,int> findMatchingChild(const Placements& subset) const;
std::pair<NodePtr,int> findMatchingChild(const ExtendedSteps& move) const;
private:
template<class Predicate> std::pair<NodePtr,int> findChild(Predicate predicate) const;
template<class Predicate> std::pair<NodePtr,int> findChild_(Predicate predicate) const;
static NodePtr addChild(const NodePtr& node,const ExtendedSteps& move,const GameState& newState,const bool after);
public:
static NodePtr addSetup(const NodePtr& node,const Placements& placements,const bool after);
static NodePtr makeMove(const NodePtr& node,const ExtendedSteps& move,const bool after);
static NodePtr makeMove(const NodePtr& node,const PieceSteps& move,const bool after);
void swapChildren(const Node& firstChild,const int siblingOffset) const;
static NodePtr root(const NodePtr& node);
static NodePtr reroot(NodePtr source,NodePtr target=nullptr);
static std::vector<std::weak_ptr<Node> > selfAndAncestors(const NodePtr& node,const Node* const final=nullptr);
static GameTree createTree()
{
return GameTree(1,std::make_shared<Node>(nullptr,ExtendedSteps(),GameState()));
}
template<class Container>
static NodePtr addToTree(Container& gameTree,const NodePtr& node)
{
for (auto& existing:gameTree)
if (node->isAncestorOfOrSameAs(existing.get()))
return node;
else if (existing->isAncestorOfOrSameAs(node.get())) {
existing=node;
return node;
}
return *gameTree.emplace(gameTree.end(),node);
}
template<class Container>
static NodePtr deleteFromTree(Container& gameTree,const NodePtr& node)
{
bool changed=false;
for (auto existing=gameTree.begin();existing!=gameTree.end();) {
if (node->isAncestorOfOrSameAs(existing->get())) {
existing=gameTree.erase(existing);
changed=true;
}
else
++existing;
}
if (changed) {
const auto& parent=node->previousNode;
if (parent!=nullptr)
return addToTree(gameTree,parent);
}
return nullptr;
}
};
#endif // NODE_HPP