/// <summary> /// Bestimmt, was für eine Art Feld dieses anhand des Raum-Layouts sein soll (Wand, Ecke, Boden, etc) /// </summary> /// <param name="fields">Alle Felder des Dungeons</param> public void SetFieldTypeAndAnimation(Field[,] fields) { if (Area == null) { return; } Field[] neighbors = GetNeighbors(fields); // Array der 8 Nachbarfelder, angefangen bei dem linken auf der selben Y Höhe und im Uhrzeigersinn fortlaufend Rectangle[] maxRects = FindValidMaxRectangles(neighbors); // sucht die Rechtecke, die aus besetzten Nachbarsfeldern gemacht werden können, mit maximaler Flächer if (maxRects.Length == 0) { throw new FieldAloneException(); } if (maxRects.Length > 1) { if (maxRects[0].Area < 6) { throw new FieldAloneException(); } for (int i = 1; i < neighbors.Length; i += 2) // Betrachten aller diagonalen Ecken bei zwei Rechtecken mit Größe 6 { if (neighbors[i].Area == null) { this.Type = (FieldType)(9 + (((i - 1) / 2 + 2) % 4)); // bestimmt innere Ecken } } } else { Rectangle rect = maxRects[0]; if (rect.Area == 4) // Feld ist eine Ecke { for (int i = 0; i < neighbors.Length; i += 2) { if (neighbors[i].Area == null && neighbors[(i + 2) % neighbors.Length].Area == null) { Type = (FieldType)(5 + i / 2); } } } else if (rect.Area == 6) // Feld ist eine Wand { for (int i = 0; i < neighbors.Length; i += 2) { if (neighbors[i].Area == null) { Type = (FieldType)(1 + i / 2); } } } else if (rect.Area == 9) // Feld ist Boden { Type = FieldType.Floor; } } SetAnimation(); }
/// <summary> /// Überprüft, ob in einem angegebenen Rechteck alle Felder innerhalb der Grenzen und von einem Raum/Korridor besetzt sind /// </summary> private bool AllFieldsInRectangleDefined(Field[,] fields, Rectangle rect) { for (int x = (int)rect.Pos.X; x < rect.Pos.X + rect.Size.X; x++) { for (int y = (int)rect.Pos.Y; y < rect.Pos.Y + rect.Size.Y; y++) { if (fields[x, y].Area == null) { return(false); } } } return(true); }
/// <summary> /// Erstellt alle gültigen Rechtecke aus den umliegenden Feldern, deren Fläche maximal ist /// </summary> /// <param name="origFields">Array der 8 umliegenden Felder</param> private Rectangle[] FindValidMaxRectangles(Field[] origFields) { Field[,] fields = new Field[3, 3]; // Array der umliegenden Nachbarn und diesem Feld fields[1, 1] = this; foreach (Field f in origFields) { fields[f.X - X + 1, f.Y - Y + 1] = f; } List <Rectangle> rects = new List <Rectangle>(); for (int x = 0; x < fields.GetLength(0); x++) { for (int y = 0; y < fields.GetLength(1); y++) { if (fields[x, y].Area == null) { continue; } int width = 1; int height = 1; for (int i = 1; x + i < fields.GetLength(0) && AllFieldsInRectangleDefined(fields, new Rectangle(new Vector(x, y), new Vector(width + 1, height))); i++) // falls bei einer um eins größeren Breite ein Rechteck gebildet werden kann { width++; } for (int i = 1; y + i < fields.GetLength(1) && AllFieldsInRectangleDefined(fields, new Rectangle(new Vector(x, y), new Vector(width, height + 1))); i++) { height++; } Rectangle rectHorizontal = new Rectangle(new Vector(x, y), new Vector(width, height)); width = 1; height = 1; for (int i = 1; y + i < fields.GetLength(1) && AllFieldsInRectangleDefined(fields, new Rectangle(new Vector(x, y), new Vector(width, height + 1))); i++) { height++; } for (int i = 1; x + i < fields.GetLength(0) && AllFieldsInRectangleDefined(fields, new Rectangle(new Vector(x, y), new Vector(width + 1, height))); i++) { width++; } Rectangle rectVertical = new Rectangle(new Vector(x, y), new Vector(width, height)); if (rectHorizontal.Size != rectVertical.Size) // in genau einem Fall gehen von einem Feld zwei maximal große Rechtecke aus { rects.Add(rectVertical); } rects.Add(rectHorizontal); } } rects.RemoveAll(x => x.Area < 4); // entfernt alle nicht validen Rechtecke mit irgendeiner Kantenlänge < 2 if (rects.Count == 0) { return(rects.ToArray()); } List <Rectangle> maxRects = new List <Rectangle>(); maxRects.Add(rects[0]); for (int i = 1; i < rects.Count; i++) // Bestimmung der Rechtecke mit maximaler Fläche { if (rects[i].Area > maxRects[0].Area) { maxRects.Clear(); maxRects.Add(rects[i]); } else if (rects[i].Area == maxRects[0].Area) { maxRects.Add(rects[i]); } } return(maxRects.ToArray()); }