|
|
using System;
|
|
|
using static isometricparkfna.TileMap;
|
|
|
|
|
|
namespace isometricparkfna
|
|
|
{
|
|
|
public class Simulation
|
|
|
{
|
|
|
public const int START_YEAR = 2020;
|
|
|
public const int START_MONTH = 1;
|
|
|
public const int START_DAY = 1;
|
|
|
|
|
|
|
|
|
private const float SPONTANEOUS_NEW_TREE_CHANCE = 0.9995f;
|
|
|
private const float NEIGHBOR_NEW_TREE_CHANCE = 0.995f;
|
|
|
private const float NEIGHBOR_CROWDS_TREE_CHANCE = 0.995f;
|
|
|
|
|
|
public int Tick
|
|
|
{
|
|
|
get;
|
|
|
|
|
|
private set;
|
|
|
}
|
|
|
|
|
|
public float Elapsed
|
|
|
{
|
|
|
get;
|
|
|
|
|
|
private set;
|
|
|
}
|
|
|
|
|
|
public DateTime DateTime
|
|
|
{
|
|
|
get;
|
|
|
|
|
|
private set;
|
|
|
}
|
|
|
|
|
|
public decimal money;
|
|
|
|
|
|
public float millisecondsPerAdvance { get; private set; }
|
|
|
public String Season { get
|
|
|
{
|
|
|
if (MathUtils.Between(this.DateTime.Month, 3, 5))
|
|
|
{
|
|
|
return "Spring";
|
|
|
}
|
|
|
else if (MathUtils.Between(this.DateTime.Month, 6, 8))
|
|
|
{
|
|
|
return "Summer";
|
|
|
}
|
|
|
else if (MathUtils.Between(this.DateTime.Month, 9, 11))
|
|
|
{
|
|
|
return "Fall";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return "Winter";
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public TileMap map;
|
|
|
|
|
|
public int ticksPerAdvance;
|
|
|
private float lastAdvance;
|
|
|
public bool paused;
|
|
|
|
|
|
private Random random;
|
|
|
|
|
|
public Simulation(int width, int height, float millisecondsPerAdvance)
|
|
|
{
|
|
|
this.random = new Random();
|
|
|
|
|
|
this.DateTime = new DateTime(START_YEAR, START_MONTH, START_DAY);
|
|
|
|
|
|
this.map = new TileMap(width, height);
|
|
|
this.money = 1000;
|
|
|
this.millisecondsPerAdvance = millisecondsPerAdvance;
|
|
|
|
|
|
this.paused = true;
|
|
|
}
|
|
|
|
|
|
private void advanceSimulation()
|
|
|
{
|
|
|
|
|
|
this.DateTime = this.DateTime.AddMonths(1);
|
|
|
|
|
|
foreach (Cell cell in this.map.iterate_cells())
|
|
|
{
|
|
|
if (random.NextDouble() > SPONTANEOUS_NEW_TREE_CHANCE)
|
|
|
{
|
|
|
cell.hasTree = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
foreach (Cell cell in this.map.iterate_cells_with_neighbors(4))
|
|
|
{
|
|
|
if (random.NextDouble() > NEIGHBOR_NEW_TREE_CHANCE)
|
|
|
{
|
|
|
cell.hasTree = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
foreach (Cell cell in this.map.iterate_cells_with_neighbors(7))
|
|
|
{
|
|
|
if (random.NextDouble() > NEIGHBOR_CROWDS_TREE_CHANCE)
|
|
|
{
|
|
|
cell.hasTree = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
public void update(TimeSpan deltaTime)
|
|
|
{
|
|
|
//this.Tick++;
|
|
|
|
|
|
if (!this.paused)
|
|
|
{
|
|
|
this.Elapsed += deltaTime.Milliseconds;
|
|
|
|
|
|
int advancesToSimulate = (int)((this.Elapsed - this.lastAdvance) / this.millisecondsPerAdvance);
|
|
|
|
|
|
for (int i = 0; i < advancesToSimulate; i++)
|
|
|
{
|
|
|
this.advanceSimulation();
|
|
|
|
|
|
//Partial frames haven't been simulated so they're not counted as part of
|
|
|
//lastAdvance
|
|
|
//Example:
|
|
|
//We start at t=100 and simulate every 10 t. If we miss enough updates that
|
|
|
//it's t=125, we have 2.5 steps to simulate. However, we only want to simulate
|
|
|
//whole steps for simplicity's sake, so that means we'll simulate 2. But that means we've only simulated
|
|
|
//through t=120, so that's what we want to track in lastAdvance.
|
|
|
this.lastAdvance += advancesToSimulate * this.millisecondsPerAdvance;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
if ((this.Tick % this.millisecondsPerAdvance) == 0)
|
|
|
{
|
|
|
this.DateTime = this.DateTime.AddMonths(1);
|
|
|
}*/
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|