public void CreateEnterence() //Interpreter로 부터 받을 변수가 있다면 추가 { //1층에서만 현관을 찾는다. foreach (Space.RoomRelationShip rel in this.Relations[Space.RelationLevel.First]) { if (rel.Origin is Space.Entrance) { Space.RoomRelationShip Ent = rel; bool placed = false; //어느 Side부터 탐색할지를 랜덤하게 결정하는 과정 List <Data.SideCardinalDirection> search = new List <Data.SideCardinalDirection>(); foreach (Data.SideCardinalDirection elem in Enum.GetValues(typeof(Data.SideCardinalDirection))) { search.Add(elem); } int n = search.Count; while (n > 1) { n--; int k = rng.Next(n + 1); Data.SideCardinalDirection value = search[k]; search[k] = search[n]; search[n] = value; } foreach (Data.SideCardinalDirection relsideDirection in search) { foreach (Data.Side relSide in rel.Origin.Sides[relsideDirection]) { if (relSide.Type == Data.SideType.Wall && relSide.GetLength() > Data.Config.DoorLength && this.IsOutterSide(rel.Origin.id, relSide, rel.Level)) { relSide.Type = Data.SideType.Door; placed = true; break; } } if (placed) { break; } } break; } } }
public void OccupySide(Data.SideCardinalDirection part, double start, double end) { //특정한 Side를 Occupy할 때, /* * 1) 새로운 Side 상태의 기록을 남긴다. * 2) 이전 Side의 상태도 기록한다. * * 일단, 변화를 순차적으로 추적하기 위해, * Stack 자료구조를 활용해서 이전 자료를 저장하는 과정이 필요하다. * Stack에는 List<Side>와 part를 같이 저장해야 복구할 Side가 무엇인지 알 수 있다. */ List <Data.Side> target = this.Sides[part]; }
public static bool IsContact(Room r1, Room r2, double minOverlapLen) { foreach (Data.SideCardinalDirection i in Enum.GetValues(typeof(Data.SideCardinalDirection))) { Data.SideCardinalDirection j = Data.SideCardinalDirection.West; switch (i) { case (Data.SideCardinalDirection.West): j = Data.SideCardinalDirection.East; break; case (Data.SideCardinalDirection.North): j = Data.SideCardinalDirection.South; break; case (Data.SideCardinalDirection.East): j = Data.SideCardinalDirection.West; break; case (Data.SideCardinalDirection.South): j = Data.SideCardinalDirection.North; break; } foreach (Data.Side a in r1.Sides[i]) { foreach (Data.Side b in r2.Sides[j]) { if (a.IsContact(b)) { Data.Side contacted = a.GetContact(b); if (contacted.GetLength() >= minOverlapLen) { return(true); } } } } } return(false); }
public static void OccupySides(Room r1, Room r2, ConnectionType type) { foreach (Data.SideCardinalDirection i in Enum.GetValues(typeof(Data.SideCardinalDirection))) { Data.SideCardinalDirection j = Data.SideCardinalDirection.West; switch (i) { case (Data.SideCardinalDirection.West): j = Data.SideCardinalDirection.East; break; case (Data.SideCardinalDirection.North): j = Data.SideCardinalDirection.South; break; case (Data.SideCardinalDirection.East): j = Data.SideCardinalDirection.West; break; case (Data.SideCardinalDirection.South): j = Data.SideCardinalDirection.North; break; } Data.Side[] r1Sides = r1.Sides[i].ToArray(); Data.Side[] r2Sides = r2.Sides[j].ToArray(); foreach (Data.Side a in r1Sides) { foreach (Data.Side b in r2Sides) { if (a.IsContact(b)) { r1.Sides[i].Remove(a); r2.Sides[j].Remove(b); //접촉하는 부분을 추출 Data.Side contacted = a.GetContact(b); //두 공간의 관계에 따라, 점령될 SideType을 결정 Data.SideType sType = Data.SideType.Wall; if (type == ConnectionType.Open) { sType = Data.SideType.Open; } else if (type == ConnectionType.Door) { sType = Data.SideType.Door; } //Side 점령 foreach (Data.Side newA in a.OccupyPart(contacted, sType)) { r1.Sides[i].Add(newA); } //r1.Sides[(int)i] = a.OccupyPart(contacted, sType); foreach (Data.Side newB in b.OccupyPart(contacted, sType)) { r2.Sides[j].Add(newB); } //r2.Sides[(int)j] = b.OccupyPart(contacted, sType); } } } } }
public void CreateWindows() //Interpreter로 부터 받을 변수가 있다면 추가 { foreach (KeyValuePair <Space.RelationLevel, List <Space.RoomRelationShip> > entry in this.Relations) { foreach (Space.RoomRelationShip rel in entry.Value) { //현재는 침실만 창문을 달고 있다. if (rel.Origin is Space.Bed || rel.Origin is Space.Living) { int winnum = 0; //Window가 가능한 Side를 찾는 과정 foreach (Data.SideCardinalDirection relsideDirection in Enum.GetValues(typeof(Data.SideCardinalDirection))) { foreach (Data.Side relSide in rel.Origin.Sides[relsideDirection]) { if (relSide.Type == Data.SideType.Wall && relSide.GetLength() > Data.Config.WindowLength && this.IsOutterSide(rel.Origin.id, relSide, rel.Level)) { relSide.Type = Data.SideType.Window; //한 사이드 방향에 하나의 창문만 winnum++; break; } } if (winnum >= 2) { break; } } } //화장실과 주방에는 창문 하나 else if (rel.Origin is Space.Kitchen || rel.Origin is Space.Rest) { bool placed = false; //어느 Side부터 탐색할지를 랜덤하게 결정하는 과정 List <Data.SideCardinalDirection> search = new List <Data.SideCardinalDirection>(); foreach (Data.SideCardinalDirection elem in Enum.GetValues(typeof(Data.SideCardinalDirection))) { search.Add(elem); } int n = search.Count; while (n > 1) { n--; int k = rng.Next(n + 1); Data.SideCardinalDirection value = search[k]; search[k] = search[n]; search[n] = value; } //Window가 가능한 Side를 찾는 과정 foreach (Data.SideCardinalDirection relsideDirection in search) { foreach (Data.Side relSide in rel.Origin.Sides[relsideDirection]) { if (relSide.Type == Data.SideType.Wall && relSide.GetLength() > Data.Config.WindowLength && this.IsOutterSide(rel.Origin.id, relSide, rel.Level)) { relSide.Type = Data.SideType.Window; placed = true; break; } } if (placed) { break; } } } } } }