コード例 #1
0
        //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
        }
コード例 #2
0
        //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
                        }
                    }
                }
            }
        }