// a private common initilization function private void InitClass(string ID, cSuperCell SuperCell, double K, double XLoc, double YLoc) { // check the parameters to make sure that they are valid. Throw exceptions if // they are not. // ID must not be 0 length. if (ID.Length == 0) { throw new ArgumentException("ID must not be an empty string.", "ID"); } // SuperCell must be a valid reference if (SuperCell == null) { ThrowSuperCellException(); } // K must be greater than or equal to 0 if (K < 0) { ThrowKException(); } // set the ID value and K mvarID = ID; mvarK = K; // add this cell to the supercell SuperCell.Add(this); // set the x,y location mvarXLoc = XLoc; mvarYLoc = YLoc; // create the neighbours array mvarNeighbours = new cCell[6]; // create the list of animals mvarAnimals = new cAnimalList(null); }
// ************************ Methods ********************************************** /// <summary> /// Add a cell to the cell list. The cell will be keyed by its ID. If another /// cell in the list already has this ID, an ArgumentException exception will be /// raised. If item is null, an ArgumentNullException exception is raised. /// </summary> /// <param name="item">The cell to add to the list.</param> public virtual void Add(cCell item) { if (item == null) { throw new ArgumentNullException("item", "Cannot add a null item to the list"); } Values.Add(item.ID, item); }
/// <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> /// Add a cell to this supercell. The supercell property of the cell is set /// to this supercell. /// </summary> /// <param name="item"> /// The cell to add to this supercell. An ArgumentNullException exception is /// raised if item is null. /// </param> public override void Add(cCell item) { // throw an exception if item is null if (item == null) { throw new ArgumentNullException("item", "Item cannot be null."); } // assign the passed cell to this supercell item.SetSuperCell(this); // call the base add method base.Add(item); }
/// <summary> /// Set the neighbouring cell of this cell at the passed index position. /// Setting a neighbour to 'null' sets the neighbour to the boundary. /// </summary> /// <param name="index">The desired position of the neighbour.</param> /// <param name="item">The neighbouring cell.</param> public void SetNeighbour(enumNeighbourPosition index, cCell item) { mvarNeighbours[(int)index] = item; }
// ************************** 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); }