List <int> Search(List <int> keys, List <Chest> chests, List <List <int> > keyToChest, Visited v, int depth) { int hash = v.GetHashCode() & ((1 << VisitedHashLen) - 1); foreach (var h in VisitedList[hash]) { if (h == v) { return(null); } } VisitedList[hash].Add(v); VisitedListCount++; if (VisitedListCount > VisitedListCapacity) { for (int i = 0; i < VisitedList.Length; i++) { VisitedList[i] = new List <Visited>(); } } List <int> nexts = new List <int>(); foreach (var k in keys.Distinct()) { if (k < keyToChest.Count) { nexts.AddRange(keyToChest[k]); } } nexts.Sort(); foreach (var n in nexts) { if (v[n] == false) { List <int> nkeys = keys.ToList(); nkeys.Remove(chests[n].ToOpen); nkeys.AddRange(chests[n].Keys); nkeys.Sort(); Visited nv = v.Clone(); nv[n] = true; if (depth < chests.Count - 1) { List <int> r = Search(nkeys, chests, keyToChest, nv, depth + 1); if (r != null) { r.Insert(0, n + 1); return(r); } } else { return(new List <int> { n + 1 }); } } } return(null); }
private static float FindResult(char[,] board, int x, int y, Visited[,] visited, int xSlide, int ySlide, int time, float speed, int reactionTime) { if (x >= board.GetLength(0) || x < 0) return float.MaxValue; if (y >= board.GetLength(1) || y < 0) return float.MaxValue; Visited v = GetFromCoordinates(xSlide, ySlide); if ((visited[x, y] & v) == v) { #if DEBUG for (int i = 0; i < time; i++) { Console.Write(" "); } Console.WriteLine("(V) - {2} {0},{1} . - {3} {4} [{5}]", x, y, time, xSlide, ySlide, board[x, y]); #endif return float.MaxValue; } if (board[x, y] == '#') return float.MaxValue; if (board[x, y] == 'O') { #if DEBUG Console.WriteLine("Found it! 0 "); #endif return speed; } visited = (Visited[,])visited.Clone(); visited[x, y] = visited[x, y] | v; float result = 0; #if DEBUG for (int i = 0; i < time; i++) { Console.Write(" "); } Console.WriteLine("(B) - {2} {0},{1} . - {3} {4} [{5}]", x, y, time, xSlide, ySlide, board[x, y]); #endif int mul = 1; int newX = 0; int newY = 0; bool stopped = true; if (xSlide != 0 || ySlide != 0) { result = speed; stopped = false; while (!stopped) { newX = x + mul * xSlide; newY = y + mul * ySlide; visited[newX, newY] = visited[newX, newY] | GetFromCoordinates(xSlide, ySlide); #if DEBUG for (int i = 0; i < time; i++) { Console.Write(" "); } Console.WriteLine("(S) - {2} {0},{1} . - {3} {4} ({5}) [{6}]", newX, newY, time, xSlide, ySlide, result, board[newX, newY]); #endif if (board[newX, newY] == 'O') { #if DEBUG Console.WriteLine("Found it! {0} ", result); #endif return result + speed; } if (board[newX, newY] == '#') stopped = true; else { result += speed; mul++; } } } mul--; //Debug! float sum = result; #if DEBUG Console.WriteLine(sum); #endif x = x + mul * xSlide; y = y + mul * ySlide; if (stopped) { sum += reactionTime; } float[] results = { FindResult(board, x + 1, y, visited, 1, 0, time + 1, speed, reactionTime), FindResult(board, x - 1, y, visited, -1, 0, time + 1, speed, reactionTime), FindResult(board, x, y - 1, visited, 0, -1, time + 1, speed, reactionTime), FindResult(board, x, y + 1, visited, 0, 1, time + 1, speed, reactionTime), }; float min = results.Min(); #if DEBUG if (min < float.MaxValue) { for (int i = 0; i < time; i++) { Console.Write(" "); } Console.WriteLine("(E) - {2} {0},{1} . - {3} {4} [{5}]", x, y, time, xSlide, ySlide, sum + min); } #endif return sum + min; }