/// <summary> /// Simple constructor /// </summary> /// <param name="c">Capacity of this field</param> public EvacuationElement(int c) { Processed = false; Capacity = c; Neighbours = new EvacuationElement[4]; NeighboursPassages = new IWallElement[4]; }
/// <summary> /// Counstrructor - initializes delay, passage and determine next step (exit from stairs) /// </summary> /// <param name="se">Stairs entry</param> /// <param name="em">Whole evacuation map</param> public StairsEvacuationElement(StairsEntry se, EvacuationMap em) : base(se.ConnectedStairs.Capacity) { _startingDelay = se.ConnectedStairs.Delay; _groups = new List<KeyValuePair<int, int>>(); _entry = se; _secondEntry = se.ConnectedStairs.GetEntry(1 - se.ID); _exitEvacuationElement = em.Get(_entry.Position) ?? em.Get(_entry.Position.GetAdjacentPosition()); _secondExitEvacuationElement = em.Get(_secondEntry.Position) ?? em.Get(_secondEntry.Position.GetAdjacentPosition()); DetermineNextStep(); }
/// <summary> /// Process one element of evacuation route /// </summary> /// <param name="group">Evacuation element to process</param> /// <param name="tick">Process given element with this tick</param> private void Process(EvacuationElement group, int tick) { int peopleCount; EvacuationElement nextStep = group.NextStep; if (group.Processed == true) return; group.StartProcessing(); if (nextStep == null) { //group finally evacuated, yeah peopleCount = Math.Min(group.Passage.Efficiency, group.PeopleQuantity); if (peopleCount > 0) { _escapedGroups.Add(new EscapedGroup(peopleCount, tick)); group.RemovePeople(peopleCount); } return; } //there is more steps to do in evacuation route if(nextStep.PeopleQuantity != 0) Process(nextStep, tick); peopleCount = nextStep.PeopleQuantityLeft; if (peopleCount == 0) { //there is no room for anybody return; } peopleCount = Math.Min(Math.Min(peopleCount, group.Passage.Efficiency), group.PeopleQuantity); if (peopleCount != 0) { if (!nextStep.Processed) { //new field for processing _evacuationGroups.Add(nextStep); } nextStep.Processed = true; //prevent from multiple moves //move people nextStep.AddPeople(peopleCount); group.RemovePeople(peopleCount); } }
/// <summary> /// Method initializes evacuation map from given building map /// </summary> /// <param name="bm">Building map</param> public void InitializeFromBuildingMap(BuildingMap bm) { _map = new SortedDictionary<int, IDictionary<int, IDictionary<int, EvacuationElement>>>(); //setup shape and neighbourhood passages foreach(var e in bm.Floors) { Floor f = e.Value; int level = e.Key; IDictionary<int, IDictionary<int, EvacuationElement>> floorMap = new SortedDictionary<int, IDictionary<int, EvacuationElement>>(); foreach (var row in f.Tiles) { IDictionary<int, EvacuationElement> tempRow = new SortedDictionary<int, EvacuationElement>(); foreach (var tile in row.Value) { EvacuationElement ee = new EvacuationElement(tile.Value.Capacity); //setup passages for (int i = 0; i < 4; ++i) { ee.NeighboursPassages[i] = tile.Value.Side[i]; } tempRow.Add(tile.Key, ee); } floorMap.Add(row.Key, tempRow); } _map.Add(level, floorMap); } //setup neighbourhood foreach (var floor in _map) { foreach (var row in floor.Value) { foreach (var tile in row.Value) { tile.Value.Neighbours[(int)Direction.DOWN] = Get(floor.Key, row.Key + 1, tile.Key); tile.Value.Neighbours[(int)Direction.UP] = Get(floor.Key, row.Key - 1, tile.Key); tile.Value.Neighbours[(int)Direction.LEFT] = Get(floor.Key, row.Key, tile.Key - 1); tile.Value.Neighbours[(int)Direction.RIGHT] = Get(floor.Key, row.Key, tile.Key + 1); //creating special evacuation element for stairs for (int i = 0; i < 4; ++i) { if (tile.Value.NeighboursPassages[i].Type == WallElementType.STAIR_ENTRY) { tile.Value.Neighbours[i] = new StairsEvacuationElement((StairsEntry)tile.Value.NeighboursPassages[i], this); } } } } } }