public AvgPathMove(int[,] p, string move, AvgPathMove parent) { if (parent == null) level = 0; else level = parent.level + 1; this.parent = parent; this.p = p; this.move = move; pos = GenPos(); score = GetScore(p); }
public static string[] Solve(int[,] initial, ref int countStep, int maxStep, long durationPerClickMs, long timeLimitMs) { #if TRIAL maxStep = 25; #endif InitializeDatabase(); int[] count = new int[maxStep + 1]; AvgPathMove bestAnswer = null; BinaryHeap[] nextQueue = new BinaryHeap[6]; for (int color = 1; color < 6; color++) nextQueue[color] = new BinaryHeap(); Hashtable used = new Hashtable(); for (int color = 1; color < 6; color++) { int[,] initialColor = new int[9, 9]; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) initialColor[i, j] = (initial[i, j] == color) ? 1 : 0; AvgPathMove firstMove = new AvgPathMove(initialColor, null, null); nextQueue[color].Insert(firstMove.score, firstMove); used[firstMove.pos] = true; if (FoundSolution(firstMove, maxStep)) { bestAnswer = firstMove; break; } } long startTime = System.DateTime.Now.Ticks; while (bestAnswer == null) { if (((System.DateTime.Now.Ticks - startTime) / TimeSpan.TicksPerMillisecond) > timeLimitMs) return null; bool isBreak = true; for (int color = 1; color < 6; color++) if (nextQueue[color].Count > 0) isBreak = false; if (isBreak == true) break; countStep++; bool end = false; for (int color = 1; color < 6; color++) { AvgPathMove m = (AvgPathMove)(nextQueue[color].Remove()); AvgPathMove[] newMoves = new AvgPathMove[] { m.next(0,'U'),m.next(1,'U'), m.next(2,'U'), m.next(0,'D'),m.next(1,'D'), m.next(2,'D'), m.next(0,'R'),m.next(1,'R'), m.next(2,'R'), m.next(0,'L'),m.next(1,'L'), m.next(2,'L') }; for (int i = 0; i < newMoves.Length; i++) { if (used[newMoves[i].pos] != null) continue; if (FoundSolution(newMoves[i], maxStep)) { bestAnswer = newMoves[i]; end = true; break; } #if TRIAL if (newMoves[i].level >= 19) continue; #else if (newMoves[i].level >= (maxStep - 6)) continue; #endif count[newMoves[i].level]++; used[newMoves[i].pos] = true; nextQueue[color].Insert(newMoves[i].score, newMoves[i]); } if (end == true) break; } if (end == true) break; } if (bestAnswer == null) return null; //refAnswer = bestAnswer; string[] steps = new string[bestAnswer.level]; AvgPathMove b = bestAnswer; for (int i = steps.Length - 1; i >= 0; i--) { steps[i] = b.move; b = b.parent; } string[] contSteps = GetSolution(bestAnswer); string[] final = new string[steps.Length + contSteps.Length]; for (int i = 0; i < steps.Length; i++) final[i] = steps[i]; for (int i = 0; i < contSteps.Length; i++) final[i + steps.Length] = contSteps[i]; conn.Close(); return final; }
private static bool FoundSolution(AvgPathMove bestPathMove, int maxStep) { DbCommand cmd = conn.CreateCommand(); #if TRIAL cmd.CommandText = "SELECT COUNT(1) FROM block_colors WHERE pos='" + bestPathMove.pos + "' AND num_steps = " + (25 - bestPathMove.level); #else cmd.CommandText = "SELECT COUNT(1) FROM block_colors WHERE pos='" + bestPathMove.pos + "' AND num_steps <= " + (maxStep - bestPathMove.level); #endif long num = (long)cmd.ExecuteScalar(); cmd.Dispose(); if (num > 0) return true; else return false; }
private static string[] GetSolution(AvgPathMove bestPathMove) { List<string> buffer = new List<string>(); while (true) { if (bestPathMove.IsFinish()) break; DbCommand cmd = conn.CreateCommand(); cmd.CommandText = "SELECT move FROM block_colors WHERE pos='" + bestPathMove.pos + "'"; string move = (string)cmd.ExecuteScalar(); if (move == "") break; char[] c = move.ToCharArray(); if (c[1] == 'U') c[1] = 'D'; else if (c[1] == 'D') c[1] = 'U'; else if (c[1] == 'L') c[1] = 'R'; else if (c[1] == 'R') c[1] = 'L'; string reverseMove = c[0] + "" + c[1]; buffer.Add(reverseMove); cmd.Dispose(); bestPathMove = bestPathMove.next(int.Parse(c[0] + ""), c[1]); } return buffer.ToArray(); }