Exemple #1
0
 public int getScore()
       /*Returns the number of pebbles a player has captured in
        * their assigned collection pit. */
     {
   return collectionPit.getCount();
 }
  // Merge two pits
  public boolean mergePits() {
    Pit firstPit = this.pits.pitDataList.get(0);
    int secondPitId = firstPit.pitIdOverflowingInto; // The pit ID that the first pit overflows into

    // Handle pits merging with other pits
    if (secondPitId > -1) {
      int mergedPitID = this.pits.maxPitId++;
      Pit secondPit = this.pits.pitDataList.get(this.pits.getIndexOf(secondPitId));

      // re-ID the two merging pits with their new mergedPitID
      for (int i = 0; i < firstPit.allPointsList.size(); i++) {
        this.pits.pitIdMatrix[firstPit.allPointsList.get(i).y][firstPit.allPointsList.get(i).x] =
            mergedPitID;
        this.pits.pitsBitmap.setPixel(
            this.dem[0].length - 1 - firstPit.allPointsList.get(i).x,
            firstPit.allPointsList.get(i).y,
            secondPit.color);
      }
      for (int i = 0; i < secondPit.allPointsList.size(); i++) {
        this.pits.pitIdMatrix[secondPit.allPointsList.get(i).y][secondPit.allPointsList.get(i).x] =
            mergedPitID;
      }

      // Fill the first pit and resolve flow direction. This must be completed before the new pit
      // entry is created or else retention volumes will be incorrectly calculated (the first pit
      // must be filled).
      resolveFilledArea();

      // Update all pits that will overflow into either of the merging pits as now overflowing into
      // the new mergedPitID
      for (int i = 0; i < this.pits.pitDataList.size(); i++) {
        if ((this.pits.pitDataList.get(i).pitIdOverflowingInto == firstPit.pitId)
            || (this.pits.pitDataList.get(i).pitIdOverflowingInto == secondPitId)) {
          this.pits.pitDataList.get(i).pitIdOverflowingInto = mergedPitID;
        }
      }
      // Rather than create the new merged pit entry, overwrite the second pit with the new merged
      // pit data
      firstPit.pitId = mergedPitID;
      firstPit.color = secondPit.color;
      firstPit.allPointsList.addAll(
          0,
          secondPit
              .allPointsList); // put the second pit's indices at the beginning of the list (so that
                               // the pit bottom is always the 0th item)
      firstPit.pitBorderIndicesList.addAll(0, secondPit.pitBorderIndicesList);
      firstPit.spilloverElevation = Float.NaN;

      // traverse in reverse order.  some of the border indices will be found to be not on the
      // border and removed from the list (necessitating the onBorder variable)
      for (int i = firstPit.pitBorderIndicesList.size() - 1; i > -1; i--) {
        Point currentPoint = firstPit.pitBorderIndicesList.get(i);
        int r = currentPoint.y;
        int c = currentPoint.x;
        boolean onBorder = false;
        for (int x = -1; x < 2; x++) {
          for (int y = -1; y < 2; y++) {
            if (x == 0 && y == 0) {
              continue;
            }

            if (this.pits.pitIdMatrix[r + y][c + x] != this.pits.pitIdMatrix[r][c]) {
              double currentElevation = this.dem[r][c];
              double neighborElevation = this.dem[r + y][c + x];
              onBorder = true;
              if (Float.isNaN(firstPit.spilloverElevation)
                  || (currentElevation <= firstPit.spilloverElevation
                      && neighborElevation <= firstPit.spilloverElevation)) {
                firstPit.spilloverElevation = (float) Math.max(neighborElevation, currentElevation);
                firstPit.pitOutletPoint = currentPoint;
                firstPit.outletSpilloverFlowDirection = new Point(c + x, r + y);
                firstPit.pitIdOverflowingInto = this.pits.pitIdMatrix[r + y][c + x];
              }
            }
          }
        }
        if (onBorder == false) {
          firstPit.pitBorderIndicesList.remove(currentPoint);
        }
      }

      // Volume/elevation-dependent variables and calculations
      firstPit.filledVolume = secondPit.filledVolume + firstPit.retentionVolume;
      firstPit.retentionVolume = firstPit.filledVolume;
      for (int i = 0; i < firstPit.allPointsList.size(); i++) {
        int r = firstPit.allPointsList.get(i).y;
        int c = firstPit.allPointsList.get(i).x;
        if (this.dem[r][c] < firstPit.spilloverElevation) {
          firstPit.retentionVolume +=
              ((firstPit.spilloverElevation - this.dem[r][c]) * cellSizeX * cellSizeY);
        }
      }

      // Sum the drainage taking place in the pit
      firstPit.pitDrainageRate = 0;
      //				for (int listIdx = 0; listIdx < firstPit.allPointsList.size(); listIdx++) {
      //					Point currentPoint = firstPit.allPointsList.get(listIdx);
      //					int r = currentPoint.y;
      //					int c = currentPoint.x;
      //					firstPit.pitDrainageRate = firstPit.pitDrainageRate; // + drainage[r][c]
      //				}
      firstPit.netAccumulationRate =
          (RainfallSimConfig.rainfallIntensity
                  * firstPit.allPointsList.size()
                  * cellSizeX
                  * cellSizeY)
              - firstPit.pitDrainageRate;
      firstPit.spilloverTime = firstPit.retentionVolume / firstPit.netAccumulationRate;

      // Removed the second pit
      this.pits.pitDataList.remove(secondPit);

      // Handle pits that begin to run off the DEM
    } else if (secondPitId <= -1) {
      int mergedPitId = this.pits.minPitId--;
      Pit secondPit = this.pits.pitDataList.get(this.pits.getIndexOf(secondPitId));

      // re-ID the two merging pits with their new mergedPitID
      for (int i = 0; i < firstPit.allPointsList.size(); i++) {
        this.pits.pitIdMatrix[firstPit.allPointsList.get(i).y][firstPit.allPointsList.get(i).x] =
            mergedPitId;
        this.pits.pitsBitmap.setPixel(
            this.dem[0].length - 1 - firstPit.allPointsList.get(i).x,
            firstPit.allPointsList.get(i).y,
            secondPit.color);
      }
      for (int i = 0; i < secondPit.allPointsList.size(); i++) {
        this.pits.pitIdMatrix[secondPit.allPointsList.get(i).y][secondPit.allPointsList.get(i).x] =
            mergedPitId;
      }

      // Fill the first pit and resolve flow direction. This must be completed before the new pit
      // entry is created or else retention volumes will be incorrectly calculated (the first pit
      // must be filled).
      resolveFilledArea();

      // Update all pits that will overflow into either of the merging pits as now overflowing into
      // the new mergedPitID
      for (int i = 0; i < this.pits.pitDataList.size(); i++) {
        if ((this.pits.pitDataList.get(i).pitIdOverflowingInto == firstPit.pitId)
            || (this.pits.pitDataList.get(i).pitIdOverflowingInto == secondPitId)) {
          this.pits.pitDataList.get(i).pitIdOverflowingInto = mergedPitId;
        }
      }

      // Rather than create the new merged pit entry, overwrite the first pit with the new merged
      // pit data
      firstPit.pitId = mergedPitId;
      firstPit.color = secondPit.color;
      firstPit.allPointsList.addAll(0, secondPit.allPointsList);
      firstPit.pitBorderIndicesList.addAll(0, secondPit.pitBorderIndicesList);
      firstPit.spilloverElevation = Float.NaN;

      // traverse in reverse order.  some of the border indices will be found to be not on the
      // border and removed from the list (hence, the onBorder variable)
      for (int i = firstPit.pitBorderIndicesList.size() - 1; i > -1; i--) {
        Point currentPoint = firstPit.pitBorderIndicesList.get(i);
        int r = currentPoint.y;
        int c = currentPoint.x;
        boolean onBorder = false;
        for (int x = -1; x < 2; x++) {
          for (int y = -1; y < 2; y++) {
            if (x == 0 && y == 0) {
              continue;
            }
            if (currentPoint.y + y >= this.pits.pitIdMatrix.length - 1
                || currentPoint.y + y <= 0
                || currentPoint.x + x >= this.pits.pitIdMatrix[0].length - 1
                || currentPoint.x + x <= 0) {
              continue;
            }
            if (this.pits.pitIdMatrix[r + y][c + x] != this.pits.pitIdMatrix[r][c]
                || (r == this.pits.pitIdMatrix.length - 1
                    || r == 0
                    || c == this.pits.pitIdMatrix[0].length - 1
                    || c == 0)) {
              double currentElevation = this.dem[r][c];
              double neighborElevation = this.dem[r + y][c + x];
              onBorder = true;
              if (Float.isNaN(firstPit.spilloverElevation)
                  || (currentElevation <= firstPit.spilloverElevation
                      && neighborElevation <= firstPit.spilloverElevation)) {
                firstPit.spilloverElevation = (float) Math.max(neighborElevation, currentElevation);
                firstPit.pitOutletPoint = currentPoint;
                firstPit.outletSpilloverFlowDirection = new Point(c + x, r + y);
                firstPit.pitIdOverflowingInto = this.pits.pitIdMatrix[r + y][c + x];
              }
            }
          }
        }
        if (onBorder == false) {
          firstPit.pitBorderIndicesList.remove(currentPoint);
        }
      }

      firstPit.filledVolume = secondPit.filledVolume + firstPit.retentionVolume;
      firstPit.retentionVolume = firstPit.filledVolume;
      for (int i = 0; i < firstPit.allPointsList.size(); i++) {
        int r = firstPit.allPointsList.get(i).y;
        int c = firstPit.allPointsList.get(i).x;
        if (this.dem[r][c] < firstPit.spilloverElevation) {
          firstPit.retentionVolume +=
              ((firstPit.spilloverElevation - this.dem[r][c]) * cellSizeX * cellSizeY);
        }
      }

      // Sum the drainage taking place in the pit
      firstPit.pitDrainageRate = 0.0;
      //				for (int listIdx = 0; listIdx < firstPit.allPointsList.size(); listIdx++) {
      //					Point currentPoint = firstPit.allPointsList.get(listIdx);
      //					int r = currentPoint.y;
      //					int c = currentPoint.x;
      //					firstPit.pitDrainageRate = firstPit.pitDrainageRate; // + drainage[r][c]
      //				}
      firstPit.netAccumulationRate =
          (RainfallSimConfig.rainfallIntensity
                  * firstPit.allPointsList.size()
                  * cellSizeX
                  * cellSizeY)
              - firstPit.pitDrainageRate;
      //			firstPit.spilloverTime = firstPit.retentionVolume/firstPit.netAccumulationRate;
      firstPit.spilloverTime = Double.POSITIVE_INFINITY;

      // Removed the second pit
      this.pits.pitDataList.remove(secondPit);

      //			////////////////////////////////////////
      //			int color = this.pits.pitsBitmap.getPixel(this.dem[0].length - 1 -
      // firstPit.outletSpilloverFlowDirection.x, firstPit.outletSpilloverFlowDirection.y);
      //			for (int i = 0; i < firstPit.allPointsList.size(); i++) {
      //				this.pits.pitIdMatrix[firstPit.allPointsList.get(i).y][firstPit.allPointsList.get(i).x]
      // = secondPitId;
      //				this.pits.pitsBitmap.setPixel(this.dem[0].length - 1 - firstPit.allPointsList.get(i).x,
      // firstPit.allPointsList.get(i).y, color);
      //			}
      //			resolveFilledArea();
      //
      //			// Update all pits that will overflow into the filled pit as now overflowing into the
      // second pit's ID
      //			for (int i = 0; i < this.pits.pitDataList.size(); i++){
      //				if (this.pits.pitDataList.get(i).pitIdOverflowingInto == firstPit.pitId) {
      //					this.pits.pitDataList.get(i).pitIdOverflowingInto = secondPitId;
      //				}
      //			}
      //			this.pits.pitDataList.remove(0);
    }
    return true;
  }