//pick the first point of which to allocate to a starting region //if starting point doesnt have any free neighbours then it retries, if freepoints >1 private bool allocatePointToRegion(Tile.Region region, HashSet <Pair> noneNeighbours) { int randIndex = UnityEngine.Random.Range(0, freePoints.Count); //pick a random free point to assign to region int xPos = freePoints[randIndex].first; int yPos = freePoints[randIndex].second; List <Pair> nlist = findNeighbours(xPos, yPos); foreach (Pair p in nlist) { if (isNoneRegion(p)) //add to hashset of noneneighbours only if the tile is none { noneNeighbours.Add(p); } } if (noneNeighbours.Count >= 1 || freePoints.Count < 1) // set random neighbour to city { int rand = Random.Range(0, noneNeighbours.Count); Pair p = noneNeighbours.ElementAt(rand); // slow O(n) but should be ok considering relatively small dimensions tileBoard[p.first, p.second].region = region; noneNeighbours.Remove(p); //also slow O(n) //Debug.Log(noneNeighbours.Count + " neighbours count for " + region); freePoints.RemoveAt(randIndex); //remove this point as it is no longer free tileBoard[xPos, yPos].region = region; return(true); } else { //try again.. shouldnt cause infinite loop? Debug.Log("attempting to find a better starting point..."); allocatePointToRegion(region, noneNeighbours); } return(false); }
//given a region and amount (counter) allocate tiles to that region private void AllocateTiles(Tile.Region region, int counter) { //pick random free tile from the list of tiles and allocate it to city HashSet <Pair> noneNeighbours = new HashSet <Pair>(); //avoid dupllicate points here. no way to select specific index/ random elem from hashset however :( Debug.Log("allocating" + counter + " " + region + " tiles..."); //Debug.Log("allocate tiles: counter : " + counter + " , freePoints count: " + freePoints.Count); allocatePointToRegion(region, noneNeighbours); counter--; while (counter > 0 && freePoints.Count > 0) { allocateNeighbourToRegion(region, noneNeighbours); counter--; } }
private HashSet <Pair> allocateNeighbourToRegion(Tile.Region region, HashSet <Pair> noneNeighbours) { //pick random point in neighbours list, set it to region int rand = Random.Range(0, noneNeighbours.Count); Pair p = noneNeighbours.ElementAt(rand); tileBoard[p.first, p.second].region = region; //remove this point from neighbours and freepoints as it is no longer free noneNeighbours.Remove(p); //////////freePoints.RemoveAt(rand); issue removing from free points properly //find neighbours of this point and add them to the neighbours list List <Pair> nlist = findNeighbours(p.first, p.second); foreach (Pair pair in nlist) { if (isNoneRegion(pair)) //add to hashset of noneneighbours only if the tile is none { noneNeighbours.Add(pair); } } return(noneNeighbours); //doesnt need to return as parameter object is mutable and changes within this method }