Commit Description:
Finish moving UI.
Commit Description:
Finish moving UI.
File last commit:
Show/Diff file:
Action:
isometric-park-fna/Simulation.cs
240 lines | 5.9 KiB | text/x-csharp | CSharpLexer
using System;
using System.Collections.Generic;
using static isometricparkfna.TileMap;
namespace isometricparkfna
{
public struct Budget
{
public DateTime DateTime;
//assets
public decimal money;
//revenue
public decimal subsidy;
//expenses
public decimal upkeep;
public decimal final_money;
//misc
public int trees;
}
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;
private List<Budget> budgets;
public Budget latestBudget
{
get
{
if (this.budgets.Count >= 1) {
return this.budgets[this.budgets.Count - 1];
}
else
{
return new Budget { };
}
}
}
public Budget previousBudget
{
get
{
if (this.budgets.Count >= 2) {
return this.budgets[this.budgets.Count - 2];
}
else
{
return new Budget { };
}
}
}
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 = 100000;
this.millisecondsPerAdvance = millisecondsPerAdvance;
this.paused = true;
this.budgets = new List<Budget>();
}
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;
}
}
//this.money -= (this.map.tree_count * 1);
//this.money += 1000;
Budget newBudget = new Budget
{
DateTime = this.DateTime,
money = this.money,
trees = this.map.tree_count,
subsidy = 1000,
upkeep = this.map.tree_count * 1
};
newBudget = this.applyBudget(newBudget); ;
this.budgets.Add(newBudget);
}
public Budget applyBudget(Budget budget)
{
this.money = budget.money
- (budget.upkeep)
+ (budget.subsidy);
budget.final_money = this.money;
return budget;
}
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);
}*/
}
}
}
}