public string Decode(string text) { string decodedtext = string.Empty; Queue<char> charsInText = new Queue<char>(); text.ToList().ForEach(p => charsInText.Enqueue(p)); string token = charsInText.Dequeue().ToString(); Dictionary<string, char> reversedCodeCombinations = ReversePolarity(CodeCombinations); while (charsInText.Count()>=0) { if (reversedCodeCombinations.ContainsKey(token)) { decodedtext += reversedCodeCombinations[token]; if (charsInText.Count > 0) { token = charsInText.Dequeue().ToString(); } else { break; } } else { token += charsInText.Dequeue().ToString(); } } return decodedtext; }
public static string GetRegexPattern(string text) { if (null == text) throw new ArgumentNullException(); if (string.IsNullOrEmpty(text)) throw new ArgumentException(); var maker = new RegexPatternMaker(text); var queue = new Queue<char>(text); while (0 < queue.Count()) { var c = queue.Dequeue(); if (char.IsWhiteSpace(c)) { if (null == maker._state) { maker._state = maker._spaceState; } maker._state.Space(maker, c); } else if (IsSpecialChar(c)) { if (null == maker._state) { maker._state = maker._specialCharState; } maker._state.SpecialChar(maker, c); } else { if (null == maker._state) { maker._state = maker._abcState; } maker._state.Abc(maker, c); } } return maker._stringBuilder.ToString(); }
public static string 分割指示記号を取り除く(string text) { { text = Regex.Replace(text, @"(?<!\\)[()]", ""); text = Regex.Replace(text, @"\\([()])", "$1"); } var queue = new Queue<char>(text.ToCharArray()); var sb = new StringBuilder(); while (0 < queue.Count()) { var current = queue.Dequeue(); if (IsSpecialCharsA(current)) { sb.Append(current); } else if ('/' == current) { } else if (' ' == current) { sb.Append(current); } else if ('+' == current) { if (!IsSpecialCharsA(queue.Peek())) { sb.Append(' '); } } else { sb.Append(current); } } return sb.ToString(); }
public static IEnumerable<MondaiWord> Split2(string s) { if (string.IsNullOrWhiteSpace(s)) throw new ArgumentException(); s = 括弧内の単語をプラス記号で繋ぐ(s); var queue = new Queue<char>(s.ToCharArray()); var sb = new StringBuilder(); var left = false; var right = false; while (0 < queue.Count()) { var current = queue.Dequeue(); // 下部にもDequeue()あり // 特殊文字Bの場合 if (IsSpecialCharsB(current) && 0 == sb.Length && '+' != queue.Peek()) { sb.Append(current); yield return new MondaiWord(sb.ToString(), left, right); sb.Length = 0; left = false; right = false; } // 特殊文字Aの場合 else if (IsSpecialCharsA(current)) { if (0 != sb.Length) { yield return new MondaiWord(sb.ToString(), left, right); sb.Length = 0; left = false; right = false; } sb.Append(current); } else if ('/' == current) { right = true; if (0 == sb.Length) throw new ArgumentException(); yield return new MondaiWord(sb.ToString(), left, right); sb.Length = 0; left = true; right = false; } else if (' ' == current) { if (0 == sb.Length) throw new ArgumentException(); yield return new MondaiWord(sb.ToString(), left, right); sb.Length = 0; left = false; right = false; } else if ('+' == current) { // 空白と置換する'+', 置換しない'*'を用意するべき。というかそもそもダブルクォーテーションはSpecialCharsに入れるべきではない。 // 以下は応急処置 if (!IsSpecialCharsA(queue.Peek())) { if (!(0 < sb.Length && IsSpecialCharsB(sb[sb.Length - 1]))) { sb.Append(' '); } } else { sb.Append(queue.Dequeue()); } } else { sb.Append(current); } } if (0 != sb.Length) { yield return new MondaiWord(sb.ToString(), left, right); } }
public void UseHotspots(IEnumerable<WoWPoint> _hotspots) { _hotspots = _hotspots ?? new WoWPoint[0]; _hotSpots = new Queue<WoWPoint>(_hotspots); if (_hotSpots.Count() <= 0) { _hotSpots.Enqueue(HuntingGroundAnchor); } FindNearestHotspot(); }
private void алгоритмЕдмондсаКарпаToolStripMenuItem_Click(object sender, EventArgs e) { int n = G.get_n(); int m = G.get_m(); int[,] f = new int[n, n]; // поток int[,] c = new int[n, n]; // остаточная сеть Graph C = new Graph(); int sum = 0; //1) < добавим новый граф С для нахождения ниминального пути алгоритмом поиска в ширину for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (G.ar_sumiznist[i, j, 0] == 1) { c[i, j] = G.ar_sumiznist[i, j, 1]; C.ar_sumiznist[i, j, 0] = 1; C.ar_sumiznist[i, j, 1] = c[i, j]; C.add_m(); } f[i, j] = 0; } C.add_n(); } //> 1) while (true) { //2) < В остаточной сети находим кратчайший путь из источника в сток. Если такого пути нет, останавливаемся. bool[] visited = new bool[n]; int[] root = new int[n]; bool[] has_root = new bool[n]; bool find_way = false; for (int i = 0; i < n; ++i) { visited[i] = false; has_root[i] = false; } Queue<int> O = new Queue<int>(); O.Enqueue(choosen_vertex); visited[choosen_vertex] = true; while (O.Count() > 0 && !find_way) { int u = O.Dequeue(); for (int v = 0; v < n && !find_way; ++v) if (C.ar_sumiznist[u, v, 0] == 1) if (!visited[v]) { visited[v] = true; has_root[v] = true; root[v] = u; O.Enqueue(v); if (v == choosen_vertex_right) { find_way = true; break; } } } if (O.Count() == 0) { label2.Text = "Максимальний потік = " + sum.ToString(); // написать завершение алгоритма #region draw_answer Draw_Graph(sender, e); Gl.glColor3d(0.5, 0, 0.3); Gl.glPointSize(pSize); Gl.glBegin(Gl.GL_POINTS); Gl.glVertex2d(G.ar_graph_point_position[choosen_vertex_right, 0], G.ar_graph_point_position[choosen_vertex_right, 1]); Gl.glEnd(); // пропечатать вершины и метки дуг с пройденым потоком Gl.glColor3d(0, 0, 0); for (int i = 0; i < n; ++i) { Gl.glRasterPos2f(G.ar_graph_point_position[i, 0] - 3*devX, G.ar_graph_point_position[i, 1] - 3*devY); string text = (i+1).ToString(); // в цикле foreach перебираем значения из массива text, // который содержит значение строки для визуализации foreach (char char_for_draw in text) { // визуализируем символ c, с помощью функции glutBitmapCharacter, используя шрифт GLUT_BITMAP_9_BY_15. Glut.glutBitmapCharacter(Glut.GLUT_BITMAP_9_BY_15, char_for_draw); } } Gl.glColor3d(1, 0, 0); float x0, y0; for (int i = 0; i < n; ++i) { for (int j = i; j < n; ++j) if (G.ar_sumiznist[i, j, 0] == 1) // вычислить координаты центра ребра { x0 = (G.ar_graph_point_position[i, 0] + G.ar_graph_point_position[j, 0]) / 2; y0 = (G.ar_graph_point_position[i, 1] + G.ar_graph_point_position[j, 1]) / 2; Gl.glRasterPos2f(x0 + 5 * devX, y0 + 5 * devY); string text = (G.ar_sumiznist[i, j, 1]).ToString() + " / " + f[i, j]; // в цикле foreach перебираем значения из массива text, // который содержит значение строки для визуализации foreach (char char_for_draw in text) { // визуализируем символ c, с помощью функции glutBitmapCharacter, используя шрифт GLUT_BITMAP_9_BY_15. Glut.glutBitmapCharacter(Glut.GLUT_BITMAP_9_BY_15, char_for_draw); } } } #endregion return; /// } int[] way = new int[n]; int n_in_way = 0; way[n_in_way++] = choosen_vertex_right; for (int i = choosen_vertex_right; root[i] != choosen_vertex; ) { i = root[i]; way[n_in_way++] = i; } way[n_in_way++] = choosen_vertex; int[] wayr = new int[n_in_way]; for (int i = n_in_way; i > 0; --i) wayr[n_in_way - i] = way[i - 1]; // > 2) /* 3) < Пускаем через найденный путь максимально возможный поток: На найденном пути в остаточной сети ищем ребро с минимальной пропускной способностью c_\min. Для каждого ребра на найденном пути увеличиваем поток на c_\min, а в противоположном ему — уменьшаем на c_\min. Модифицируем остаточную сеть. Для всех рёбер на найденном пути, а также для противоположных им рёбер, вычисляем новую пропускную способность. Если она стала ненулевой, добавляем ребро к остаточной сети, а если обнулилась, стираем его. > 3) */ int c_min = EPS; for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (C.ar_sumiznist[i, j, 0] == 1) if (c_min > C.ar_sumiznist[i, j, 1]) c_min = C.ar_sumiznist[i, j, 1]; sum += c_min; for (int i = 0; i < n_in_way - 1; ++i) { f[wayr[i], wayr[i+1]] += c_min; f[wayr[i+1], wayr[i]] -= c_min; C.ar_sumiznist[wayr[i], wayr[i+1], 1] -= c_min; if (C.ar_sumiznist[wayr[i], wayr[i+1], 1] == 0) { C.ar_sumiznist[wayr[i], wayr[i+1], 0] = 0; C.sub_m(); } } } }
private void bfs(int v, ref int[] por, ref int n_por, ref bool[] vis) { Queue<int> Q = new Queue<int>(); por[n_por++] = v; vis[v] = true; Q.Enqueue(v); while (Q.Count() != 0) { int f = Q.Dequeue(); for (int i = 0; i < G.get_n(); ++i) { if (G.ar_sumiznist[f, i, 0] == 1) if (!vis[i]) { por[n_por++] = i; vis[i] = true; Q.Enqueue(i); } } } }
/// <summary> /// This is called to fill best path for solution. /// </summary> /// <param name="flagpass">A flag, 0 for DFS, 1 for BFS.</param> public void getPath(Object flagpass) { int flag = (int)flagpass; mapboat = new Dictionary<String, bool>(); List<Boat> listboatf = new List<Boat>(); foreach (Boat boat in boats) { listboatf.Add(new Boat(this,boat)); } List<BoatPath> boatpath = new List<BoatPath>(); mapboat.Add(ListBoatToString(listboatf), false); bestmove = -1; if (flag == 0) { bool cek = true; Stack<KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>> stackDFS = new Stack<KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>>(); stackDFS.Push(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>(new KeyValuePair<List<Boat>, List<BoatPath>>(listboatf, boatpath), new Sea(this, map))); while ((cek)&&(stackDFS.Count() > 0)) { KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea> pair = stackDFS.Pop(); List<Boat> listboat = pair.Key.Key; List<BoatPath> listpath = pair.Key.Value; Sea localmap = pair.Value; if ((int)(listboat.ElementAt(0).Position.X / widthPerTile) + (int)(listboat.ElementAt(0).Size.X / widthPerTile) == map.outPos.X) { bestmove = listpath.Count(); bestpath = listpath; cek = false; } if (cek) { for (int i = 0; i < listboat.Count(); ++i) { Boat tempboat = listboat.ElementAt(i); if ((tempboat.Arah == Boat.Orientation.Left) || (tempboat.Arah == Boat.Orientation.Right)) { int x = (int)(tempboat.Position.X / widthPerTile); int y = (int)(tempboat.Position.Y / heightPerTile); int sizex = (int)(tempboat.Size.X / widthPerTile); if ((x > 0) && (localmap.GetStatus(x - 1, y) == 0)) { listboat.ElementAt(i).Position = new Vector2((x - 1) * widthPerTile, y * heightPerTile); bool tempbool = false; if ((!(mapboat.TryGetValue(ListBoatToString(listboat), out tempbool))) || (tempbool)) { if (!tempbool) mapboat.Add(ListBoatToString(listboat), false); else mapboat[ListBoatToString(listboat)] = false; localmap.SetStatus(x - 1, y, 1); localmap.SetStatus(x + sizex - 1, y, 0); List<BoatPath> templistpath = listpath.ToList(); templistpath.Add(new BoatPath(i, new Vector2(x * widthPerTile, y * heightPerTile), new Vector2((x - 1) * widthPerTile, y * heightPerTile))); List<Boat> templistboat = new List<Boat>(); foreach (Boat boat in listboat) { templistboat.Add(new Boat(this, boat)); } stackDFS.Push(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>( new KeyValuePair<List<Boat>, List<BoatPath>>(templistboat, templistpath), new Sea(this,localmap))); } listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, y * heightPerTile); localmap.SetStatus(x - 1, y, 0); localmap.SetStatus(x + sizex - 1, y, 1); } if ((x + sizex < sizeX) && (localmap.GetStatus(x + sizex, y) == 0)) { listboat.ElementAt(i).Position = new Vector2((x + 1) * widthPerTile, y * heightPerTile); bool tempbool = false; if ((!(mapboat.TryGetValue(ListBoatToString(listboat), out tempbool))) || (tempbool)) { if (!tempbool) mapboat.Add(ListBoatToString(listboat), false); else mapboat[ListBoatToString(listboat)] = false; localmap.SetStatus(x + sizex, y, 1); localmap.SetStatus(x, y, 0); List<BoatPath> templistpath = listpath.ToList(); templistpath.Add(new BoatPath(i, new Vector2(x * widthPerTile, y * heightPerTile), new Vector2((x + 1) * widthPerTile, y * heightPerTile))); List<Boat> templistboat = new List<Boat>(); foreach (Boat boat in listboat) { templistboat.Add(new Boat(this, boat)); } stackDFS.Push(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>( new KeyValuePair<List<Boat>, List<BoatPath>>(templistboat, templistpath), new Sea(this, localmap))); } listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, y * heightPerTile); localmap.SetStatus(x + sizex, y, 0); localmap.SetStatus(x, y, 1); } } else if ((tempboat.Arah == Boat.Orientation.Top) || (tempboat.Arah == Boat.Orientation.Bottom)) { int x = (int)(tempboat.Position.X / widthPerTile); int y = (int)(tempboat.Position.Y / heightPerTile); int sizey = (int)(tempboat.Size.Y / heightPerTile); if ((y > 0) && (localmap.GetStatus(x, y - 1) == 0)) { listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, (y - 1) * heightPerTile); bool tempbool = false; if ((!(mapboat.TryGetValue(ListBoatToString(listboat), out tempbool))) || (tempbool)) { if (!tempbool) mapboat.Add(ListBoatToString(listboat), false); else mapboat[ListBoatToString(listboat)] = false; localmap.SetStatus(x, y - 1, 1); localmap.SetStatus(x, y + sizey - 1, 0); List<BoatPath> templistpath = listpath.ToList(); templistpath.Add(new BoatPath(i, new Vector2(x * widthPerTile, y * heightPerTile), new Vector2(x * widthPerTile, (y - 1) * heightPerTile))); List<Boat> templistboat = new List<Boat>(); foreach (Boat boat in listboat) { templistboat.Add(new Boat(this, boat)); } stackDFS.Push(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>( new KeyValuePair<List<Boat>, List<BoatPath>>(templistboat, templistpath), new Sea(this, localmap))); } listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, y * heightPerTile); localmap.SetStatus(x, y - 1, 0); localmap.SetStatus(x, y + sizey - 1, 1); } if ((y + sizey < sizeY) && (localmap.GetStatus(x, y + sizey) == 0)) { listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, (y + 1) * heightPerTile); bool tempbool = false; if ((!(mapboat.TryGetValue(ListBoatToString(listboat), out tempbool))) || (tempbool)) { if (!tempbool) mapboat.Add(ListBoatToString(listboat), false); else mapboat[ListBoatToString(listboat)] = false; localmap.SetStatus(x, y + sizey, 1); localmap.SetStatus(x, y, 0); List<BoatPath> templistpath = listpath.ToList(); templistpath.Add(new BoatPath(i, new Vector2(x * widthPerTile, y * heightPerTile), new Vector2(x * widthPerTile, (y + 1) * heightPerTile))); List<Boat> templistboat = new List<Boat>(); foreach (Boat boat in listboat) { templistboat.Add(new Boat(this, boat)); } stackDFS.Push(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>( new KeyValuePair<List<Boat>, List<BoatPath>>(templistboat, templistpath), new Sea(this, localmap))); } listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, y * heightPerTile); localmap.SetStatus(x, y + sizey, 0); localmap.SetStatus(x, y, 1); } } } } } } else if (flag == 1) { bool cek = true; Queue<KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>> queueBFS = new Queue<KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>>(); queueBFS.Enqueue(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>(new KeyValuePair<List<Boat>, List<BoatPath>>(listboatf, boatpath), new Sea(this, map))); while ((cek) && (queueBFS.Count() > 0)) { KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea> pair = queueBFS.Dequeue(); List<Boat> listboat = pair.Key.Key; List<BoatPath> listpath = pair.Key.Value; Sea localmap = pair.Value; if ((int)(listboat.ElementAt(0).Position.X / widthPerTile) + (int)(listboat.ElementAt(0).Size.X / widthPerTile) == map.outPos.X) { bestmove = listpath.Count(); bestpath = listpath; cek = false; } if (cek) { for (int i = 0; i < listboat.Count(); ++i) { Boat tempboat = listboat.ElementAt(i); if ((tempboat.Arah == Boat.Orientation.Left) || (tempboat.Arah == Boat.Orientation.Right)) { int x = (int)(tempboat.Position.X / widthPerTile); int y = (int)(tempboat.Position.Y / heightPerTile); int sizex = (int)(tempboat.Size.X / widthPerTile); if ((x > 0) && (localmap.GetStatus(x - 1, y) == 0)) { listboat.ElementAt(i).Position = new Vector2((x - 1) * widthPerTile, y * heightPerTile); bool tempbool = false; if ((!(mapboat.TryGetValue(ListBoatToString(listboat), out tempbool))) || (tempbool)) { if (!tempbool) mapboat.Add(ListBoatToString(listboat), false); else mapboat[ListBoatToString(listboat)] = false; localmap.SetStatus(x - 1, y, 1); localmap.SetStatus(x + sizex - 1, y, 0); List<BoatPath> templistpath = listpath.ToList(); templistpath.Add(new BoatPath(i, new Vector2(x * widthPerTile, y * heightPerTile), new Vector2((x - 1) * widthPerTile, y * heightPerTile))); List<Boat> templistboat = new List<Boat>(); foreach (Boat boat in listboat) { templistboat.Add(new Boat(this, boat)); } queueBFS.Enqueue(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>( new KeyValuePair<List<Boat>, List<BoatPath>>(templistboat, templistpath), new Sea(this, localmap))); } listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, y * heightPerTile); localmap.SetStatus(x - 1, y, 0); localmap.SetStatus(x + sizex - 1, y, 1); } if ((x + sizex < sizeX) && (localmap.GetStatus(x + sizex, y) == 0)) { listboat.ElementAt(i).Position = new Vector2((x + 1) * widthPerTile, y * heightPerTile); bool tempbool = false; if ((!(mapboat.TryGetValue(ListBoatToString(listboat), out tempbool))) || (tempbool)) { if (!tempbool) mapboat.Add(ListBoatToString(listboat), false); else mapboat[ListBoatToString(listboat)] = false; localmap.SetStatus(x + sizex, y, 1); localmap.SetStatus(x, y, 0); List<BoatPath> templistpath = listpath.ToList(); templistpath.Add(new BoatPath(i, new Vector2(x * widthPerTile, y * heightPerTile), new Vector2((x + 1) * widthPerTile, y * heightPerTile))); List<Boat> templistboat = new List<Boat>(); foreach (Boat boat in listboat) { templistboat.Add(new Boat(this, boat)); } queueBFS.Enqueue(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>( new KeyValuePair<List<Boat>, List<BoatPath>>(templistboat, templistpath), new Sea(this, localmap))); } listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, y * heightPerTile); localmap.SetStatus(x + sizex, y, 0); localmap.SetStatus(x, y, 1); } } else if ((tempboat.Arah == Boat.Orientation.Top) || (tempboat.Arah == Boat.Orientation.Bottom)) { int x = (int)(tempboat.Position.X / widthPerTile); int y = (int)(tempboat.Position.Y / heightPerTile); int sizey = (int)(tempboat.Size.Y / heightPerTile); if ((y > 0) && (localmap.GetStatus(x, y - 1) == 0)) { listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, (y - 1) * heightPerTile); bool tempbool = false; if ((!(mapboat.TryGetValue(ListBoatToString(listboat), out tempbool))) || (tempbool)) { if (!tempbool) mapboat.Add(ListBoatToString(listboat), false); else mapboat[ListBoatToString(listboat)] = false; localmap.SetStatus(x, y - 1, 1); localmap.SetStatus(x, y + sizey - 1, 0); List<BoatPath> templistpath = listpath.ToList(); templistpath.Add(new BoatPath(i, new Vector2(x * widthPerTile, y * heightPerTile), new Vector2(x * widthPerTile, (y - 1) * heightPerTile))); List<Boat> templistboat = new List<Boat>(); foreach (Boat boat in listboat) { templistboat.Add(new Boat(this, boat)); } queueBFS.Enqueue(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>( new KeyValuePair<List<Boat>, List<BoatPath>>(templistboat, templistpath), new Sea(this, localmap))); } listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, y * heightPerTile); localmap.SetStatus(x, y - 1, 0); localmap.SetStatus(x, y + sizey - 1, 1); } if ((y + sizey < sizeY) && (localmap.GetStatus(x, y + sizey) == 0)) { listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, (y + 1) * heightPerTile); bool tempbool = false; if ((!(mapboat.TryGetValue(ListBoatToString(listboat), out tempbool))) || (tempbool)) { if (!tempbool) mapboat.Add(ListBoatToString(listboat), false); else mapboat[ListBoatToString(listboat)] = false; localmap.SetStatus(x, y + sizey, 1); localmap.SetStatus(x, y, 0); List<BoatPath> templistpath = listpath.ToList(); templistpath.Add(new BoatPath(i, new Vector2(x * widthPerTile, y * heightPerTile), new Vector2(x * widthPerTile, (y + 1) * heightPerTile))); List<Boat> templistboat = new List<Boat>(); foreach (Boat boat in listboat) { templistboat.Add(new Boat(this, boat)); } queueBFS.Enqueue(new KeyValuePair<KeyValuePair<List<Boat>, List<BoatPath>>, Sea>( new KeyValuePair<List<Boat>, List<BoatPath>>(templistboat, templistpath), new Sea(this, localmap))); } listboat.ElementAt(i).Position = new Vector2(x * widthPerTile, y * heightPerTile); localmap.SetStatus(x, y + sizey, 0); localmap.SetStatus(x, y, 1); } } } } } } }
/** * Extracts a horizontal or vertical shape of the original Shape. * The area of the new, smaller flat shape will be smaller thatn the areaLimit. * sizeLimit specifies the width of the flat, extracted shape. */ public static Shape reduceShapeHVAreaLimit(Shape originalShape, Point? firstPoint, int sizeLimit, bool horizontal, int areaLimit) { int px, py, nx, ny; int[] neighx = { -1, 0, 1, -1, 1, -1, 0, 1 }, neighy = { -1, -1, 1, 0, 0, 1, 1, 1 }; Shape reducedShape = new Shape(); Queue<Point?> queue = new Queue<Point?>(); if (originalShape == null) { return null; } if (!originalShape.contains(firstPoint)) { return null; } queue.Enqueue(firstPoint); while (true) { Point? head = queue.Dequeue(); reducedShape.Add(head); int reducedArea = reducedShape.Area; Point? shapeCenter = reducedShape.getCenter(); px = head.Value.X; py = head.Value.Y; for (int i = 0; i < 8; i++) { nx = px + neighx[i]; ny = py + neighy[i]; Point? neighbour = new Point(nx, ny); if ((originalShape.contains(neighbour)) && (!reducedShape.contains(neighbour)) && (!queue.Contains(neighbour)) && (queue.Count() + reducedArea < areaLimit) && (((horizontal) && (Math.Abs(nx - shapeCenter.Value.X) < sizeLimit)) || ((!horizontal) && (Math.Abs(ny - shapeCenter.Value.Y) < sizeLimit))) ) { queue.Enqueue(neighbour); } } if ((reducedArea > areaLimit) || (queue.Count == 0)) { break; } } return reducedShape; }