/** * Initializes drought days for each food type to zero. Also checks to see if food deplete rates * and times are valid for each food type. Valid random food deplete rates and times will be * generated using the environments random number generator for each invalid entry. */ private void setupDraughtDeplete() { draughtdays = new int[getTypeCount()]; for (int i = 0; i < getTypeCount(); ++i) { draughtdays[i] = 0; if (foodData[i].depleteRate < 0.0f || foodData[i].depleteRate > 1.0f) foodData[i].depleteRate = simulation.getRandom().nextFloat(); if (foodData[i].depleteTime <= 0) foodData[i].depleteTime = simulation.getRandom().nextInt(100) + 1; } }
private void depleteFood(ComplexFoodParams food, int type) { // the algorithm for randomly selecting the food cells to delete // is as follows: // We iterate through all of the cells and the location of each // one containing food type i is added to // a random position in our vector. We then calculate exactly // how many food items we need to destroy, say N, // and we destroy the food at the positions occupying the last N // spots in our vector List<Location> locations = new ArrayList<Location>(); for (int x = 0; x < simulation.getTopology().width; ++x) { for (int y = 0; y < simulation.getTopology().height; ++y) { Location currentPos = new Location(x, y); if (env.hasFood(currentPos) && env.getFoodType(currentPos) == type) locations.add(currentPos); } } Collections.shuffle(locations, simulation.getRandom()); int foodToDeplete = (int) (locations.size() * food.depleteRate); for (int j = 0; j < foodToDeplete; ++j) { Location loc = locations.get(j); env.removeFood(loc); } draughtdays[type] = food.draughtPeriod; }
private void dropFood(int type) { float foodDrop = foodData[type].dropRate; while (simulation.getRandom().nextFloat() < foodDrop) { --foodDrop; Location l; int j = 0; do { ++j; l = simulation.getTopology().getRandomLocation(); } while (j < DROP_ATTEMPTS_MAX && env.hasAnythingAt(l)); if (j < DROP_ATTEMPTS_MAX) { env.addFood(l, type); } } }
private void growFood() { // create a new ArrayEnvironment and a new food type array // loop through all positions AbioticMutator abiotic = env.getPlugin(AbioticMutator.class); for (int y = 0; y < simulation.getTopology().height; ++y) { for (int x = 0; x < simulation.getTopology().width; ++x) { Location currentPos = new Location(x, y); if (!env.hasAnythingAt(currentPos)) { // we should grow food here // the following code block tests all adjacent squares // to this one and counts how many have food // as well how many of each food type exist double foodCount = 0; int[] mostFood = new int[getTypeCount()]; for (Direction dir : simulation.getTopology().ALL_4_WAY) { Location checkPos = simulation.getTopology().getAdjacent(currentPos, dir); if (checkPos != null && env.hasFood(checkPos)) { foodCount++; mostFood[env.getFoodType(checkPos)]++; } } // and if we have found any adjacent food, theres a // chance we want to grow food here if (foodCount > 0) { int max = 0; int growingType; // find the food that exists in the largest quantity for (int i = 1; i < mostFood.length; ++i) if (mostFood[i] > mostFood[max]) max = i; // give the max food an extra chance to be chosen if (sameFoodProb >= simulation.getRandom().nextFloat()) { growingType = max; } else { growingType = simulation.getRandom().nextInt(getTypeCount()); } // finally, we grow food according to a certain // amount of random chance ComplexFoodParams thisType = foodData[growingType]; float growRate = thisType.growRate; for (int i = 0; i < thisType.abioticParams.factorParams.length; i++) { AbioticPreferenceParam factorParams = thisType.abioticParams.factorParams[i].preference; float factorValue = abiotic.getValue(i, currentPos); float discomfort = 1 + factorParams.score(factorValue); growRate *= discomfort; } if (foodCount * growRate > 100 * simulation.getRandom().nextFloat()) { env.addFood(currentPos, growingType); } } } } } }