1 package puzzle.solver;
2
3 import puzzle.state.Direction;
4 import puzzle.state.PuzzleState;
5
6 import java.util.EnumSet;
7 import java.util.Optional;
8
9 public class Node {
10
11 private PuzzleState state;
12 private EnumSet<Direction> operators;
13 private Optional<Node> parent;
14 private Optional<Direction> direction;
15
16 public Node(PuzzleState state) {
17 this.state = state;
18 parent = Optional.empty();
19 direction = Optional.empty();
20 operators = state.getLegalMoves();
21 }
22
23 public Node(PuzzleState state, Node parent, Direction direction) {
24 this(state);
25 this.parent = Optional.of(parent);
26 this.direction = Optional.of(direction);
27 }
28
29 public PuzzleState getState() {
30 return state;
31 }
32
33 public Optional<Node> getParent() {
34 return parent;
35 }
36
37 public Optional<Direction> getDirection() {
38 return direction;
39 }
40
41 public boolean hasNextChild() {
42 return !operators.isEmpty();
43 }
44
45 public Optional<Node> nextChild() {
46 if (! hasNextChild()) {
47 return Optional.empty();
48 }
49 var iterator = operators.iterator();
50 var direction = iterator.next();
51 iterator.remove();
52 var newState = state.clone();
53 newState.move(direction);
54 return Optional.of(new Node(newState, this, direction));
55 }
56
57 @Override
58 public boolean equals(Object o) {
59 if (o == this) {
60 return false;
61 }
62 return (o instanceof Node other) && state.equals(other.getState());
63 }
64
65 @Override
66 public int hashCode() {
67 return state.hashCode();
68 }
69
70 @Override
71 public String toString() {
72 return direction.isPresent() ? String.format("%s %s", direction.get(), state) : state.toString();
73 }
74
75 }