//get a new extinguisher object private void GetExtinguisher() { foreach (Tile t in lineOfSight) //up, down, left and right { if (sharedExtinguishers.Contains(t)) //if it is still in the shared extinguishers list (it has not been taken yet) { this.extinguisher = new Extinguisher(); this.sharedExtinguishers.Remove(t); //remove it from the shared list this.DIJKSTRA = new Dijkstra(currentLocation, grid); //create the dijsktra object this.NewExtinguisher(); //create a new extinguisher if (RedrawHandler != null) { RedrawHandler.Invoke(t); //Call the form's redraw method to redraw a wall } return; //spend one tick to get the extinguisher } } this.NewExtinguisher(); //set a new extinguisher RunForExtinguisher(); //avoid wasting time in one place when no extinguisher at the current place }
//IF PERSONALITY IS "HERO" public void RunForExtinguisher() { List <Tile> pathToFire; //store the path to the closest fire if (currentLocation.onFire) { this.Die(); //person dies return; } if (this.extinguisher != null) //if there is an extinguisher { if (this.extinguisher.Fuel <= 0) //if there is no fuel { this.RemoveExtinguisher(); return; //exit the recursion created by the other method } this.DIJKSTRA = new Dijkstra(currentLocation, grid); bool assigned = false; pathToFire = new List <Tile>(); foreach (Tile n in currentLocation.neighbours) { if (n.onFire && lineOfSight.Contains(n)) { assigned = true; pathToFire.Add(n); } } if (!assigned) { pathToFire = this.DIJKSTRA.CalculatePath(); } if (pathToFire.Count > 2) //if there is more than 1 move (final tile is on fire) { if (pathToFire[pathToFire.Count - 2] == currentLocation.up) //move up { MoveUp(); } else if (pathToFire[pathToFire.Count - 2] == currentLocation.down) //move down { MoveDown(); } else if (pathToFire[pathToFire.Count - 2] == currentLocation.left) //move left { MoveLeft(); } else if (pathToFire[pathToFire.Count - 2] == currentLocation.right) //move right { MoveRight(); } } else //if there are no moves, then person is at the end location { pathToFire[0].available = false; //the fire is currently being extinguished by a person, so no other person can have it set as a destination //do the extinguishy stuff if (this.extinguisher.Extinguish(pathToFire[0].GetFire())) //if there is no malfunction { if (pathToFire[0].GetFire().isExtinguished) //if the fire is extinguished { pathToFire[0].available = true; //make the tile available again } } else //there is a malfunction { this.RemoveExtinguisher(); pathToFire[0].available = true; //make the tile available for another person to extinguish return; //exit the recursion created by the other method } } } else { if (this.heroChanged) //if his destination is changed to the exit, always go there { this.RunForTheExit(); // start running for the exit return; //don't continue down } if (currentLocation == endLocation && !extinguisherBlocked) //AND extinguisher is not blocked because he is stuck in one place if there is no ext. on his position { this.GetExtinguisher(); } else { this.NewAlgorithm(); //create a new a* algorithm if (this.blindPath.Count == 0 && !extinguisherBlocked) //if the blind path is empty AND ext. is not blocked (otherwise causes stackOverflowException) { blindPath = this.A_STAR.GetFullPath(); //get a new path this.blindPath.RemoveAt(blindPath.Count - 1); //remove the start position this.RunForExtinguisher(); //call the method with a path return; } else { if (!extinguisherBlocked) //if path to extinguisher is not blocked { Tile nextLocation; nextLocation = this.blindPath[blindPath.Count - 1]; //get the next move //check the line of sight, because it removes the tiles on fire if (nextLocation.onFire || !lineOfSight.Contains(nextLocation)) //if the next location is on fire OR if it is not in the line of sight { //find a way to go around it if possible //get the first tile which is not on fire for (int i = blindPath.Count - 1; i >= 0; i--) //go through the list { if (!blindPath[i].onFire || i == 0) //find the first tile in the list that is not on fire { nextLocation = this.CheckAvailablePath(blindPath[i]); //the next move should be in regards to going around the fire break; } else { blindPath.RemoveAt(i); //remove the tile on fire } } } if (nextLocation == null) //if there is no way around the fire { if (this.NewExtinguisher()) //if there is an extinguisher (if not, the extinguisherBlocked is set to true) { this.blindPath.Clear(); //empty the blind path to set a new one } this.RunForExtinguisher(); //enter recursion to not stay in one place too long return; } else { //move to the appropriate location if (nextLocation == currentLocation.up) { MoveUp(); } else if (nextLocation == currentLocation.left) { MoveLeft(); } else if (nextLocation == currentLocation.down) { MoveDown(); } else if (nextLocation == currentLocation.right) { MoveRight(); } else { } //if next location is the current one, stay here if (blindPath.Contains(nextLocation)) //if the next location is part of the blind path after all this { for (int i = blindPath.Count - 1; i >= 0; i--) //loop through the list in reverse (from current to end) { if (blindPath[i] != nextLocation) //if there are tiles before the next move { blindPath.RemoveAt(i); //remove them (this will put the person back on track) } else { break; //once it reaches the nextLocation, break the loop } } //finally, remove the next location from the blind Path blindPath.Remove(nextLocation); } } } else //if all extinguishers are blocked { this.heroChanged = true; this.SetDestination(GetClosestFireEscape(currentLocation)); //set exit as new destination this.blindPath.Clear(); //clear the path to set a new one to the exit this.RunForExtinguisher(); //call the method again with the updated destination return; //exit recursion } } } } }