protected override void GenerateCellState(Random random, int x, int y, out long state, out float stateValue, out object cellData) { ForestFireCellData ffCellData = new ForestFireCellData(null); cellData = ffCellData; state = STATE_EMPTY; stateValue = 0; if (random.NextDouble() < INIT_WATER_CHANCE) { stateValue = 0; state = STATE_WATER; } else if (random.NextDouble() < INIT_TREE_CHANCE) { state = STATE_TREE; ffCellData.Grow(random); stateValue = 0; } }
protected override void CalculateNewState(int x, int y, long currentState, float currentStateValue, object currentCellData, float deltaTime, Random random, out long state, out float stateValue, out object cellData) { ForestFireCellData ffCellData = (ForestFireCellData)currentCellData; state = currentState; stateValue = currentStateValue; cellData = ffCellData; if (currentState == STATE_TREE) { totalUtility += ffCellData.TreeData.Utility; } switch (currentState) { case STATE_EMPTY: { int nb_tree = Neighbours(x, y, STATE_TREE); if (random.NextDouble() < TREE_SEEDLING_CHANCE * nb_tree || random.NextDouble() < TREE_REGROW_CHANCE) { //if (random.NextDouble() < ffCellData.SproutChance(random) * TREE_REGROW_FACTOR) { ffCellData.Grow(random); state = STATE_TREE; stateValue = 0; } break; } case STATE_ASH: { int nb_tree = Neighbours(x, y, STATE_TREE); float decomposition = ASH_DECOMPOSITION_BASE_FACTOR + nb_tree * ASH_DECOMPOSITION_TREE_FACTOR; if (currentStateValue <= decomposition) { state = STATE_EMPTY; stateValue = 0; } else { stateValue = Math.Max(0, currentStateValue - decomposition); } break; } case STATE_TREE: { int nb_fire = Neighbours(x, y, STATE_FIRE); float nbv_fire = NeighbourStateValue(x, y, STATE_FIRE, (v, a) => v + a); int nb_water = Neighbours(x, y, STATE_WATER); if ((nb_fire > nb_water && random.NextDouble() < 1 * nbv_fire) || random.NextDouble() < FIRE_CHANCE) { stateValue = currentStateValue; state = STATE_FIRE; ffCellData.Burn(); } else { //foreach (object cD in NeighbourCellData(x, y)) { // ForestFireCellData ffCD = (ForestFireCellData)cD; // if (ffCD.TreeData == null) // continue; // if (random.NextDouble() >= SAPLING_SPREAD_CHANCE) // continue; // SaplingData newSapling = ffCD.TreeData.Mutate(random, SAPLING_MUTATION_CHANCE, SAPLING_MUTATION_STD_DEV); // ffCellData.Add(newSapling); //} if (currentStateValue < 1) { int nb_ash = Neighbours(x, y, STATE_ASH); float growth = GROWTH_FACTOR_BASE + nb_ash * ASH_GROWTH_FACTOR; //float growth = ffCellData.TreeData.GrowModifier * GROWTH_FACTOR_BASE + nb_ash * ASH_GROWTH_FACTOR; stateValue = Math.Min(1, currentStateValue + growth); } } } break; case STATE_FIRE: { int nb_water = Neighbours(x, y, STATE_WATER); float diminishing = FIRE_DIMINISHING_BASE_FACTOR + nb_water * FIRE_DIMINISHING_WATER_FACTOR; if (currentStateValue <= diminishing) { state = STATE_ASH; stateValue = 1; } else { stateValue = Math.Max(0, currentStateValue - diminishing); } break; } } }