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; }