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
| public class Node { public State state; public bool boatOnLeft; public int parent; public Node(State state, bool boatOnLeft, int parent) { this.state = state; this.boatOnLeft = boatOnLeft; this.parent = parent; } }
public int Hash(State state, bool boatOnLeft) { return state.preist * 10 + state.devil + (boatOnLeft ? 1 : 0) * 100;
}
public Tuple<int, int> GetNextStep(int x, int y, bool boatOnLeft) { if (!ContainState(new State(x, y))) { Debug.Log("wrong state"); Debug.Log(x); Debug.Log(y); return Tuple.Create(0, 0); }
Dictionary<int, bool> vis = new Dictionary<int, bool>(); foreach (State state in states) { vis[Hash(state, false)] = false; vis[Hash(state, true)] = false; }
List<Node> que = new List<Node>(); que.Add(new Node(new State(x, y), boatOnLeft, -1)); vis[Hash(que[0].state, boatOnLeft)] = true; Node front = que[0];
int[] dirx = { 1, 0, 2, 0, 1 }; int[] diry = { 0, 1, 0, 2, 1 }; int head = 0, tail = -1, xx, yy;
while (head <= que.Count) { front = que[head]; xx = front.state.preist; yy = front.state.devil; boatOnLeft = front.boatOnLeft;
if (xx == 0 && yy == 0) { break; }
for (int i = 0; i < 5; i++) { if (!boatOnLeft) { if (xx >= dirx[i] && yy >= diry[i]) { State nextState = new State(xx - dirx[i], yy - diry[i]); Node nextNode = new Node(nextState, !boatOnLeft, head); int hash = Hash(nextState, !boatOnLeft); if (ContainState(nextState) && !vis[hash]) { que.Add(nextNode); vis[hash] = true; } } } else { if (count - xx >= dirx[i] && count - yy >= diry[i]) { State nextState = new State(xx + dirx[i], yy + diry[i]); Node nextNode = new Node(nextState, !boatOnLeft, head); int hash = Hash(nextState, !boatOnLeft); if (ContainState(nextState) && !vis[hash]) { que.Add(nextNode); vis[hash] = true; } } } }
head++; if (head == tail) { tail = que.Count; } }
while (front.parent != 0 && front.parent != -1) { front = que[front.parent]; }
if (front.parent == 0) { return Tuple.Create(Math.Abs(front.state.preist - x), Math.Abs(front.state.devil - y)); }
return Tuple.Create(0, 0); }
|