-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathState.java
More file actions
129 lines (108 loc) · 4.44 KB
/
State.java
File metadata and controls
129 lines (108 loc) · 4.44 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public class State {
private State parent;
private Vector2[] boxLocations;
private Vector2 playerStart;
private int boxMoved;
private int dirMoved;
private State(State parent, Vector2[] boxLocations, Vector2 playerStart, int boxMoved, int dirMoved) {
this.parent = parent;
this.boxLocations = boxLocations;
this.playerStart = playerStart;
this.boxMoved = boxMoved;
this.dirMoved = dirMoved;
}
public State(Vector2[] boxLocations, Vector2 playerStart) {
this(null, boxLocations, playerStart, -1, -1);
}
public State(Vector2[] boxLocations) {
this(null, boxLocations, Vector2.zero, -1, -1);
}
public State getParent() {
return parent;
}
public Vector2 getPlayerLocation() {
return playerStart;
}
public Vector2[] getBoxLocations() {
return boxLocations;
}
public Vector2 getBoxLocation(int index) {
return boxLocations[index];
}
public Vector2 getMovedBoxLocation() {
return boxMoved == -1 ? null : boxLocations[boxMoved];
}
public int getMovedBox() {
return boxMoved;
}
public int getMovedDirection() {
return dirMoved;
}
public List<State> getStates(boolean reverse) {
List<State> states = new ArrayList<State>(boxLocations.length << 2);
CachedSearch search = new CachedSearch(getPlayerLocation(), Arrays.asList(boxLocations));
for(int box = 0; box < boxLocations.length; box++) {
for(int dir = 0; dir < Vector2.directions.length; dir++) {
State found = (reverse ? getPreviousBoxState(search, box, dir, null, 1) : getNextBoxState(search, box, dir, null, 1));
if(found != null) states.add(found);
}
}
return states;
}
public State getRandomState(Set<Vector2> floor, boolean reverse, int newFloorCost) {
CachedSearch search = new CachedSearch(getPlayerLocation(), Arrays.asList(boxLocations));
for(int box : Generator.randomSequence(0, boxLocations.length)) {
for(int dir : Generator.randomSequence(0, Vector2.directions.length)) {
State s = reverse ? getPreviousBoxState(search, box, dir, floor, newFloorCost) : getNextBoxState(search, box, dir, floor, newFloorCost);
if(s != null) return s;
}
}
return null;
}
public void print() {
for(Vector2 v : boxLocations) System.out.print("box(" + v.x + " " + v.y + ") ");
System.out.println();
}
private State getNextBoxState(CachedSearch search, int box, int dir, Set<Vector2> floor, int newFloorCost) {
Vector2 newBoxLocation = Vector2.add(boxLocations[box], Vector2.directions[dir]);
Vector2 playerAccess = Vector2.subtract(boxLocations[box], Vector2.directions[dir]);
if(!search.hasObstical(newBoxLocation) && search.addMinimumPath(playerAccess, floor, newFloorCost)) {
Vector2[] newBoxLocations = boxLocations.clone();
newBoxLocations[box] = newBoxLocation;
return new State(this, newBoxLocations, boxLocations[box], box, dir);
}
return null;
}
private State getPreviousBoxState(CachedSearch search, int box, int dir, Set<Vector2> floor, int newFloorCost) {
Vector2 newBoxLocation = Vector2.add(boxLocations[box], Vector2.directions[dir]);
Vector2 playerAccess = Vector2.add(boxLocations[box], Vector2.scale(Vector2.directions[dir], 2));
if(!search.hasObstical(newBoxLocation) && search.addMinimumPath(playerAccess, floor, newFloorCost)) {
floor.add(boxLocations[box]);
floor.add(newBoxLocation);
Vector2[] newBoxLocations = boxLocations.clone();
newBoxLocations[box] = newBoxLocation;
return new State(this, newBoxLocations, playerAccess, box, dir);
}
return null;
}
public boolean boxHasNextState(boolean reverse, Set<Vector2> floor, int box) {
CachedSearch search = new CachedSearch(getPlayerLocation(), Arrays.asList(boxLocations));
for(int dir=0; dir<Vector2.directions.length; dir++) {
State s = reverse ? getPreviousBoxState(search, box, dir, null, 1) : getNextBoxState(search, box, dir, null, 1);
if(s != null && floor.contains(Vector2.subtract(s.getPlayerLocation(), Vector2.directions[dir])) && floor.contains(s.getMovedBoxLocation())) {
return true;
}
}
return false;
}
@Override
public boolean equals(Object o) {
if(o == null || !(o instanceof State)) return false;
State s = (State)o;
return boxLocations.equals(s.boxLocations) && playerStart.equals(s.playerStart) && boxMoved == s.boxMoved && dirMoved == s.dirMoved;
}
}