Exemplo n.º 1
0
        /// <summary>
        ///		Read cell data from the data source and fill the passed cell list.  This
        ///		method will raise an exception if 1) a supercell ID in the database is not
        ///		found in the Background assigned to this class (ArgumentException exception) or
        ///		2) a cell is assigned a reference to a neighbour that does not exist
        ///		(ArgumentException exception).
        /// </summary>
        /// <param name="Cells">
        ///		The cell list to fill.  The cells are added to any that are already in the
        ///		list.  An ArgumentNullException exception is raised if Cells is null.
        /// </param>
        /// <param name="SuperCells">
        ///		A list of Supercells that these cells will belong to.  An ArgumentNullException
        ///		is raised if SuperCells is null.  An ArgumentException is raised if SuperCells
        ///		is an empty list.
        /// </param>
        public void GetCellData(cCellList Cells, cSuperCellList Supercells)
        {
            // make sure Cells is not null
            if (Cells == null)
            {
                throw new ArgumentNullException("Cells", "Cells must not be null.");
            }
            // make sure Supercells is not null
            if (Supercells == null)
            {
                ThrowSupercellsException();
            }
            // the supercell list must contain at least one super cell
            if (Supercells.Count == 0)
            {
                throw new ArgumentException("Supercell list must contain at least one supercell.",
                                            "Supercells");
            }
            // retrieve the name of this list of cells
            Cells.Name = this.GetName();
            // create a cell data object
            cCellData CellData = new cCellData();

            // loop, loading cell data one at a time
            this.Reset();
            while (this.GetNextCellRecord(CellData))
            {
                // create the new cell
                cCell Cell = new cCell(CellData.ID, Supercells[CellData.SuperCellID],
                                       CellData.K, CellData.XLoc, CellData.YLoc);
                Cells.Add(Cell);
            }
            // loop again, this time assigning neighbours.  If an invalid refence exception
            // is thrown, then the neighbour ID is invalid.
            this.Reset();
            while (this.GetNextCellRecord(CellData))
            {
                // loop through the six neighbour positions
                for (int i = 0; i < 6; i++)
                {
                    // note: if the neighbour value in the datasource is "b", this indicates
                    // that the neighbour is on the bouandary
                    if (CellData.Neighbours[i] == "b")
                    {
                        Cells[CellData.ID].SetNeighbour((enumNeighbourPosition)i, null);
                    }
                    else
                    {
                        Cells[CellData.ID].SetNeighbour((enumNeighbourPosition)i,
                                                        Cells[CellData.Neighbours[i]]);
                    }
                }
            }
        }
        // ************************** Methods *******************************************
        /// <summary>
        ///		Calculate a path through a series of cells with a bias in the specified
        ///		direction.  Note, the returned path may not be as long as expected for two
        ///		possible reasons; 1) The path encounters the boundary of the region under
        ///		study or 2) The path attempts to cross a supercell boundary and cannot
        ///		overcome the resistances involved to do so.
        /// </summary>
        /// <param name="StartCellID">
        ///		The ID of the cell at the start of the path.  If if a cell with the passed ID
        ///		is not in the list, an ArgumentException exception is raised.
        ///	</param>
        /// <param name="PathLength">
        ///		The number of cells the path should pass through.
        /// </param>
        /// <param name="DirectionBias">The directional bias of the path.</param>
        /// <returns>
        ///		A cCellList containing the cells within the path in order to the end of
        ///		the path.  The starting cell IS NOT included in this list.
        ///	</returns>
        public cCellList CalculatePath(string StartCellID, int PathLength,
                                       enumNeighbourPosition DirectionBias)
        {
            cCellList             Path        = new cCellList(null);
            cCell                 CurrentCell = this[StartCellID];
            cCell                 NextCell;
            int                   RanNum;
            enumNeighbourPosition Direction;

            // if requested path is zero length or less, then do nothing
            if (PathLength > 0)
            {
                // loop for desired path length
                for (int i = 0; i < PathLength; i++)
                {
                    // get a Random number from the random number generator
                    //mvarBackground.RandomNum.MinValue = 0;
                    //mvarBackground.RandomNum.MaxValue = 100;
                    RanNum = mvarBackground.RandomNum.IntValue(1, 100);
                    // get a direction for the next cell based on the value of the
                    // random number
                    if (RanNum <= 20)
                    {
                        Direction = DirectionBias - 1;
                        if (Direction < 0)
                        {
                            Direction += 6;
                        }
                    }
                    else if (RanNum <= 80)
                    {
                        Direction = DirectionBias;
                    }
                    else
                    {
                        Direction = DirectionBias + 1;
                        if ((int)Direction > 5)
                        {
                            Direction -= 6;
                        }
                    }
                    // now try to get the neighbour.  If this is a boundary cell, we can go
                    // no further and will stop calculating the path.
                    // is this neighbour on the boundary.  If it is, break out of the loop
                    // immediately.
                    if (CurrentCell.IsBoundary(Direction))
                    {
                        break;
                    }
                    // get the neighbouring cell
                    NextCell = CurrentCell.GetNeighbour(Direction);
                    // is the next cell in the same super group as the current cell.
                    // If not see if we can overcome both the exiting and entering
                    // resistances.
                    if (NextCell.SuperCell != CurrentCell.SuperCell)
                    {
                        // the two cells do not share the same supercell.  We must check
                        // resistances
                        // check out resistance of current cell.  If we do not overcome it,
                        // stop here.
                        if (CurrentCell.SuperCell.OutResistance > 0)
                        {
                            //mvarBackground.RandomNum.MinValue = 0;
                            //mvarBackground.RandomNum.MaxValue = 100;
                            if (Background.RandomNum.IntValue(1, 100) <= CurrentCell.SuperCell.OutResistance)
                            {
                                break;
                            }
                        }
                        // check in resistance of next cell.  If we do not overcome it,
                        // stop here
                        if (NextCell.SuperCell.InResistance > 0)
                        {
                            //mvarBackground.RandomNum.MinValue = 0;
                            //mvarBackground.RandomNum.MaxValue = 100;
                            if (Background.RandomNum.IntValue(1, 100) <= NextCell.SuperCell.InResistance)
                            {
                                break;
                            }
                        }
                    }
                    // add the neigbour to our list
                    try {
                        Path.Add(NextCell);
                    }
                    catch {
                        return(Path);
                    }
                    // now make next cell the current cell
                    CurrentCell = NextCell;
                }
            }
            // return the calculted path
            return(Path);
        }