Description:
Merge in Milestone 1-Money (so far).
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r86:bce262cae9d2 -

@@ -0,0 +1,130
1 using System;
2 using Microsoft.Xna.Framework;
3 using Microsoft.Xna.Framework.Graphics;
4 using Microsoft.Xna.Framework.Input;
5
6 namespace isometricparkfna.UI
7 {
8 public class BudgetWindow
9 {
10 private Budget budget;
11 private Budget previous_budget;
12 private SpriteFont font;
13 public int x;
14 public int y;
15
16
17 private Vector2 mouseEnd;
18 private Vector2 mouseStart;
19 private MouseState mousePrev;
20
21 private static int bar_height = 25;
22 private static int height = 500;
23 private static int width = 700;
24
25 public BudgetWindow(Budget budget, SpriteFont font, int start_x, int start_y)
26 {
27
28 this.budget = budget;
29 this.font = font;
30 this.x = start_x;
31 this.y = start_y;
32 }
33
34 public bool update(MouseState mouseCur, Budget budget, Budget previous_budget)
35 {
36 this.budget = budget;
37 this.previous_budget = previous_budget;
38
39 if ((mouseCur.LeftButton == ButtonState.Pressed)
40 && MathUtils.Between(mouseCur.X, width+x-20, width+x)
41 && MathUtils.Between(mouseCur.Y, y+bar_height, y+bar_height+20)
42 ) {
43
44 return false;
45
46 }
47 else if ((mouseCur.LeftButton == ButtonState.Pressed)
48 && MathUtils.Between(mouseCur.X, x, width+x)
49 && MathUtils.Between(mouseCur.Y, y, 500 + y))
50 {
51 if (mousePrev.LeftButton == ButtonState.Released)
52 {
53 this.mouseStart = new Vector2(mouseCur.X, mouseCur.Y);
54
55 }
56 else
57 {
58 this.mouseEnd = new Vector2(mouseCur.X, mouseCur.Y);
59 this.x = MathUtils.Clamp(this.x + (int)(this.mouseEnd.X - this.mouseStart.X), 0, width);
60 this.y = MathUtils.Clamp(this.y + (int)(this.mouseEnd.Y - this.mouseStart.Y), 0, 400);
61 }
62 }
63
64 this.mouseStart = new Vector2(mouseCur.X, mouseCur.Y);
65
66 this.mousePrev = mouseCur;
67
68 return true;
69 }
70
71 public void draw(SpriteBatch batch)
72 {
73
74
75
76 FilledRectangle.drawFilledRectangle(batch, new Rectangle(x - 20, y+bar_height, 20, height), Color.White);
77 Line.drawLine(batch, new Vector2(x, y + bar_height), new Vector2(x, y + bar_height + height), Color.Gray);
78 FilledRectangle.drawFilledRectangle(batch, new Rectangle(x + width, y+bar_height, 20, height), Color.White);
79 Line.drawLine(batch, new Vector2(x + width, y + bar_height), new Vector2(x + width, y + bar_height + height), Color.Gray);
80
81 for (int i = 1; i <= (height / bar_height); i++)
82 {
83 Rectangle position = new Rectangle(this.x, bar_height * i + this.y,
84 width, bar_height);
85
86 if ((i % 2) == 0)
87 {
88 FilledRectangle.drawFilledRectangle(batch, position, Color.LightGreen, 0.99f);
89 }
90 else
91 {
92 FilledRectangle.drawFilledRectangle(batch, position, Color.White, 0.99f);
93 }
94 }
95
96 FilledRectangle.drawFilledRectangle(batch, new Rectangle(x + width - 20, y+bar_height, 20, 20), Color.LightGray);
97 Vector2 dimensions = font.MeasureString("X");
98 batch.DrawString(font, "X", new Vector2(x+width -20 + (dimensions.X/2), y+bar_height), Color.Black);
99
100 batch.DrawString(font, String.Format("BUDGET REPORT FOR {0:MMMMM yyyy}", this.budget.DateTime), new Vector2(x, bar_height * 1 + y), Color.Black);
101
102 batch.DrawString(font, String.Format("Starting Funds.........${0:}", this.budget.money), new Vector2(x, bar_height * 2 + y), Color.Black);
103
104 batch.DrawString(font, String.Format("REVENUE", this.budget.upkeep), new Vector2(x, bar_height * 4 + y), Color.Black);
105 batch.DrawString(font, String.Format("Subsidy................${0:}....${1:}", this.budget.subsidy, this.previous_budget.subsidy), new Vector2(x, bar_height * 5 + y), Color.Black);
106
107 batch.DrawString(font, String.Format("EXPENSES", this.budget.upkeep), new Vector2(x, bar_height * 9 + y), Color.Black);
108 batch.DrawString(font, String.Format("Upkeep.................${0:}....${1:}", this.budget.upkeep, this.previous_budget.upkeep), new Vector2(x, bar_height * 10 + y), Color.Black);
109 batch.DrawString(font, String.Format("Tree Planting..........${0:}....${1:}", this.budget.tree_planting, this.previous_budget.tree_planting), new Vector2(x, bar_height * 11 + y), Color.Black);
110 batch.DrawString(font, String.Format("Tree Clearing..........${0:}....${1:}", this.budget.tree_clearing, this.previous_budget.tree_clearing), new Vector2(x, bar_height * 12 + y), Color.Black);
111
112 Color cashflow_color = Color.Black;
113 if (this.budget.cashflow < 0) {
114 cashflow_color = Color.Red;
115 }
116 Color final_color = Color.Black;
117 if (this.budget.final_money < 0) {
118 final_color = Color.Red;
119 }
120
121 batch.DrawString(font, String.Format("Cashflow.............${0:}....${1:}", this.budget.cashflow, this.previous_budget.cashflow), new Vector2(x, bar_height * 14 + y), cashflow_color);
122 batch.DrawString(font, String.Format("Ending Funds.........${0:}....${1:}", this.budget.final_money, this.previous_budget.final_money), new Vector2(x, bar_height * 15 + y), final_color);
123
124
125 FilledRectangle.drawFilledRectangle(batch, new Rectangle(50, 50, 50, 50), new Color (0, 0,0, 0), 0.99f);
126
127
128 }
129 }
130 }
@@ -0,0 +1,63
1 using ImGuiNET;
2
3 using Num = System.Numerics;
4
5 namespace isometricparkfna.UI
6 {
7
8 public static class ForestWindow
9 {
10 public static void Render(ref bool show, ImFontPtr font, Simulation sim)
11 {
12 if (show)
13 {
14 ImGui.PushFont(font);
15
16 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.None;
17 ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 0.0f);
18 ImGui.PushStyleVar(ImGuiStyleVar.WindowRounding, 0.0f);
19 ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 1.0f);
20 ImGui.PushStyleColor(ImGuiCol.WindowBg, new Num.Vector4(0.75f, 0.75f, 0.75f, 1f));
21
22 var title_bar = new Num.Vector4(0.65f, 0.65f, 0.65f, 1f);
23 ImGui.PushStyleColor(ImGuiCol.TitleBg, title_bar);
24 ImGui.PushStyleColor(ImGuiCol.TitleBgActive, title_bar);
25 ImGui.PushStyleColor(ImGuiCol.TitleBgCollapsed, title_bar);
26
27 ImGui.PushStyleColor(ImGuiCol.Border, new Num.Vector4(0f, 0f, 0f, 1f));
28 ImGui.PushStyleColor(ImGuiCol.BorderShadow, new Num.Vector4(0f, 0f, 0f, 0.5f));
29
30
31
32 ImGui.PushStyleColor(ImGuiCol.Button, new Num.Vector4(0.75f, 0.75f, 0.75f, 1f));
33 ImGui.PushStyleColor(ImGuiCol.Text, new Num.Vector4(0f, 0f, 0f, 1f));
34 ImGui.Begin("Forest Policy", ref show, ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoSavedSettings);
35
36
37 int new_tree_planting = sim.tree_planting;
38 ImGui.SliderInt("Tree Planting ", ref new_tree_planting, 0, Simulation.MAX_TREES_TO_PLANT, string.Format("%d (${0})", new_tree_planting*Simulation.TREE_PLANT_COST));
39 sim.tree_planting = new_tree_planting;
40
41 int new_tree_clearing = sim.tree_clearing;
42 ImGui.SliderInt("Tree Clearing", ref new_tree_clearing, 0, Simulation.MAX_TREES_TO_CLEAR, string.Format("%d (${0})", new_tree_clearing*Simulation.TREE_CLEAR_COST));
43 sim.tree_clearing = new_tree_clearing;
44
45 ImGui.Text(string.Format("Crowded Trees: {0}", sim.crowded_trees ));
46 ImGui.Text(string.Format("Percent Healthy Trees: {0:F2}", sim.healthy_percent));
47 ImGui.Text(string.Format("Average Age of Trees: {0:F2}", sim.average_tree_age));
48 ImGui.Text(string.Format("Max Age of Trees: {0:F2}", sim.max_tree_age));
49
50 if (ImGui.Button("Okay"))
51 {
52 show = false;
53 }
54
55 ImGui.End();
56 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.Left;
57 ImGui.PopStyleVar(3);
58 ImGui.PopStyleColor(8);
59 ImGui.PopFont();
60 }
61 }
62 }
63 } No newline at end of file
@@ -2,7 +2,7
2 Gameplay:
2 Gameplay:
3 Money:
3 Money:
4 - Add basic subsidy @milestone(1: Basic Money) @done(2021-01-27)
4 - Add basic subsidy @milestone(1: Basic Money) @done(2021-01-27)
5 - Balance sheet
5 - Basic Balance sheet
6 - Basic balance sheet @milestone(1: Basic Money)
6 - Basic balance sheet @milestone(1: Basic Money)
7 - Basic display @done(2021-01-27)
7 - Basic display @done(2021-01-27)
8 - Movement @done(2021-01-27)
8 - Movement @done(2021-01-27)
@@ -16,7 +16,7
16 - Outline reserved areas @milestone(3: Contracts)
16 - Outline reserved areas @milestone(3: Contracts)
17 -
17 -
18 Trees:
18 Trees:
19 - Add basic maintenance cost @milestone(1: Basic Money)
19 - Add basic maintenance cost @milestone(1: Basic Money) @done(2021-01-27)
20 - Add basic age simulation
20 - Add basic age simulation
21 - Biodiversity @maybe
21 - Biodiversity @maybe
22 - Research agreements @maybe
22 - Research agreements @maybe
@@ -67,8 +67,8
67 Other features:
67 Other features:
68 Accessibility:
68 Accessibility:
69 - Verify contrast
69 - Verify contrast
70 - Increase display size
70 - Option to Increase display size
71 - Turn off bad outcomes
71 - Option to Turn off bad outcomes or disasters?
72 Other QoL things:
72 Other QoL things:
73 - Adjust display size
73 - Adjust display size
74 - Toggle trees translucency
74 - Toggle trees translucency
@@ -31,6 +31,23
31 }
31 }
32 }
32 }
33
33
34 public int tree_capacity
35 {
36 get
37 {
38 return MapWidth * MapHeight;
39 }
40 }
41
42 public int remaining_tree_capacity
43 {
44 get
45 {
46 return this.tree_capacity - this.tree_count;
47 }
48 }
49
50
34 public CellMap()
51 public CellMap()
35 {
52 {
36 //TileMap(MapWidth, MapHeight);
53 //TileMap(MapWidth, MapHeight);
@@ -56,7 +73,7
56
73
57 }
74 }
58
75
59 public System.Collections.IEnumerable tree_cells()
76 public System.Collections.Generic.IEnumerable<Cell> tree_cells()
60 {
77 {
61 foreach (List<Cell> row in cells)
78 foreach (List<Cell> row in cells)
62 {
79 {
@@ -70,7 +87,7
70 }
87 }
71 }
88 }
72
89
73 public System.Collections.IEnumerable tree_cells(int zone)
90 public System.Collections.Generic.IEnumerable<Cell> tree_cells(int zone)
74 {
91 {
75 foreach (List<Cell> row in cells)
92 foreach (List<Cell> row in cells)
76 {
93 {
@@ -84,7 +101,7
84 }
101 }
85 }
102 }
86
103
87 public System.Collections.IEnumerable iterate_cells()
104 public System.Collections.Generic.IEnumerable<Cell> iterate_cells()
88 {
105 {
89 foreach (List<Cell> row in cells)
106 foreach (List<Cell> row in cells)
90 {
107 {
@@ -100,7 +117,7
100 return MathUtils.Between(x, 0, MapWidth - 1) && MathUtils.Between(y, 0, MapHeight - 1);
117 return MathUtils.Between(x, 0, MapWidth - 1) && MathUtils.Between(y, 0, MapHeight - 1);
101 }
118 }
102
119
103 private System.Collections.IEnumerable iterate_neighbors(int x, int y)
120 private System.Collections.Generic.IEnumerable<Cell> iterate_neighbors(int x, int y)
104 {
121 {
105 //iterates over neighbors (clockwise starting at noon/midnight)
122 //iterates over neighbors (clockwise starting at noon/midnight)
106 if (inBounds(x, y + 1))
123 if (inBounds(x, y + 1))
@@ -142,13 +159,15
142 int count = 0;
159 int count = 0;
143 foreach (Cell neighbor in this.iterate_neighbors(x, y))
160 foreach (Cell neighbor in this.iterate_neighbors(x, y))
144 {
161 {
145 count++;
162 if (neighbor.hasTree) {
163 count++;
164 }
146 }
165 }
147
166
148 return count;
167 return count;
149 }
168 }
150
169
151 public System.Collections.IEnumerable iterate_cells_with_neighbors(int neighbors)
170 public System.Collections.Generic.IEnumerable<Cell> iterate_cells_with_neighbors(int neighbors)
152 {
171 {
153 for (int i = 0; i < MapHeight; i++)
172 for (int i = 0; i < MapHeight; i++)
154 {
173 {
@@ -165,9 +184,41
165
184
166 }
185 }
167
186
187 public enum CellStatus{
188 Clear,
189 LivingTree,
190 DeadTree
191 }
192
168 public class Cell
193 public class Cell
169 {
194 {
170 public Boolean hasTree = false;
195 // public Boolean _hasTree = false;
196 public CellStatus status {
197 get;
198 private set;
199 }
200
201 public Boolean hasTree {
202 get {
203 return this.status == CellStatus.LivingTree;
204 }
205 }
206
207 public DateTime planted;
208
209 public void addTree(DateTime datetime) {
210 this.status = CellStatus.LivingTree;
211
212 this.planted = datetime;
213 }
214
215 public void removeTree() {
216 this.status = CellStatus.Clear;
217 }
218
219 public void markTreeDead() {
220 this.status = CellStatus.DeadTree;
221 }
171 }
222 }
172 }
223 }
173 } No newline at end of file
224 }
@@ -1,4 +1,4
1 using System.Collections.Generic;
1 using System.Collections.Generic;
2 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework;
3 using Microsoft.Xna.Framework.Audio;
3 using Microsoft.Xna.Framework.Audio;
4 using Microsoft.Xna.Framework.Input;
4 using Microsoft.Xna.Framework.Input;
@@ -14,6 +14,7
14 using System.Diagnostics;
14 using System.Diagnostics;
15 using static isometricparkfna.CellMap;
15 using static isometricparkfna.CellMap;
16 using isometricparkfna.Utils;
16 using isometricparkfna.Utils;
17 using isometricparkfna.UI;
17
18
18
19
19
20
@@ -71,10 +72,13
71 private Queue<Node<DialogOption>> remainingDialog;
72 private Queue<Node<DialogOption>> remainingDialog;
72
73
73
74
74 private bool showGrid = true;
75 private bool showGrid;
75 private Grammar grammar;
76 private Grammar grammar;
76 private string output;
77 private string output;
77 private GraphicsDeviceManager gdm;
78 private GraphicsDeviceManager gdm;
79 private bool showBudget;
80 private BudgetWindow budgetWindow;
81 private bool showForest;
78
82
79 private static void Main(string[] args)
83 private static void Main(string[] args)
80 {
84 {
@@ -115,13 +119,20
115 {
119 {
116 if (this.random_generator.NextDouble() > 0.75)
120 if (this.random_generator.NextDouble() > 0.75)
117 {
121 {
118 cell.hasTree = true;
122 int random_year = (int)MathHelper.Clamp((float)MathUtils.NextNormal(random_generator, 2010.0f, 40.0f), 1800, Simulation.START_YEAR);
123 int random_month = random_generator.Next(1, 12);
124 DateTime random_date = new DateTime(random_year, random_month, 1);
125
126 cell.addTree(random_date);
119 }
127 }
120 }
128 }
121 }
129 }
122
130
123 showInitial = true;
131 showInitial = true;
124 messageIndex = 0;
132 messageIndex = 0;
133 showBudget = false;
134 showForest = true;
135 showGrid = true;
125
136
126 this.Window.Title = "Isometric Park";
137 this.Window.Title = "Isometric Park";
127
138
@@ -129,8 +140,6
129
140
130 currentNode = DialogTrees.introTree;
141 currentNode = DialogTrees.introTree;
131
142
132
133
134 }
143 }
135
144
136 protected override void Initialize()
145 protected override void Initialize()
@@ -188,6 +197,9
188 //font = fontBakeResult.CreateSpriteFont(GraphicsDevice);
197 //font = fontBakeResult.CreateSpriteFont(GraphicsDevice);
189 monoFont = bakedMono.CreateSpriteFont(GraphicsDevice);
198 monoFont = bakedMono.CreateSpriteFont(GraphicsDevice);
190
199
200 this.budgetWindow = new BudgetWindow(new Budget { }, this.monoFont, 0, 0);
201
202
191 }
203 }
192
204
193 protected override void UnloadContent()
205 protected override void UnloadContent()
@@ -323,6 +335,16
323 this.showGrid = !this.showGrid;
335 this.showGrid = !this.showGrid;
324
336
325 }
337 }
338 if (keyboardCur.IsKeyDown(Keys.B) && keyboardPrev.IsKeyUp(Keys.B))
339 {
340 this.showBudget = !this.showBudget;
341
342 }
343 if (keyboardCur.IsKeyDown(Keys.F) && keyboardPrev.IsKeyUp(Keys.F))
344 {
345 this.showForest = !this.showForest;
346
347 }
326 if (keyboardCur.IsKeyDown(Keys.C) && keyboardPrev.IsKeyUp(Keys.C))
348 if (keyboardCur.IsKeyDown(Keys.C) && keyboardPrev.IsKeyUp(Keys.C))
327 {
349 {
328 this.camera.Jump(Vector2.Zero);
350 this.camera.Jump(Vector2.Zero);
@@ -387,8 +409,15
387
409
388 #endregion input
410 #endregion input
389
411
412
413
390 this.simulation.update(gameTime.ElapsedGameTime);
414 this.simulation.update(gameTime.ElapsedGameTime);
391
415
416 if (this.showBudget)
417 {
418 this.showBudget = this.budgetWindow.update(mouseCur, this.simulation.latestBudget, this.simulation.previousBudget);
419 }
420
392
421
393 if (!this.showInitial && this.remainingDialog.Count > 0)
422 if (!this.showInitial && this.remainingDialog.Count > 0)
394 {
423 {
@@ -673,15 +702,21
673
702
674 if (this.simulation.map.cells[i][j].hasTree)
703 if (this.simulation.map.cells[i][j].hasTree)
675 { //until we actually simulate:
704 { //until we actually simulate:
676 if ((i + j) % 8 == 0)
705 drawTileAt(i, j, 142, 2);
677 {
706 // if ((i + j) % 8 == 0)
707 // {
708 // drawTileAt(i, j, 141, 2);
709 // }
710 // else
711 // {
712 // drawTileAt(i, j, 142, 2);
713 // }
714 }
715 else if (this.simulation.map.cells[i][j].status == CellStatus.DeadTree) {
678 drawTileAt(i, j, 141, 2);
716 drawTileAt(i, j, 141, 2);
679 }
717 // System.Console.WriteLine(String.Format("Drew Dead Tree at {0},{1}", i, j));
680 else
718
681 {
719 }
682 drawTileAt(i, j, 142, 2);
683 }
684 }
685 }
720 }
686 }
721 }
687 #endregion draw_trees
722 #endregion draw_trees
@@ -716,17 +751,30
716 this.Window.Title = String.Format("Isometric Park [{0:}]", header_middle);
751 this.Window.Title = String.Format("Isometric Park [{0:}]", header_middle);
717 Vector2 dimensions = monoFont.MeasureString(header_middle);
752 Vector2 dimensions = monoFont.MeasureString(header_middle);
718
753
719 float middle_start = (FNAGame.width / 2) - (dimensions.X / 2);
754 float middle_start = (int)((FNAGame.width / 2) - (dimensions.X / 2));
720
755
721 FilledRectangle.drawFilledRectangle(batch, new Rectangle(0, 0, width, (int)dimensions.Y), Color.White, 0.51f);
756 FilledRectangle.drawFilledRectangle(batch, new Rectangle(0, 0, width, (int)dimensions.Y), Color.White, 0.51f);
722
757
723
758
724 batch.DrawString(monoFont, header_left, new Vector2(1, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
759 batch.DrawString(monoFont, header_left, new Vector2(1, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
725 batch.DrawString(monoFont, header_middle, new Vector2(middle_start, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
760 batch.DrawString(monoFont, header_middle, new Vector2(middle_start, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
726 #endregion draw_header
761 #endregion draw_header
727
762
728
763
729 batch.End();
764 #region budget
765
766 if (this.showBudget)
767 {
768 budgetWindow.draw(batch);
769
770 }
771
772 #endregion budget
773
774 batch.End();
775
776
777
730
778
731 #region debug_window
779 #region debug_window
732 //Calcs for debug window:
780 //Calcs for debug window:
@@ -763,11 +811,11
763 additionalInfo.Add("mouse delta", delta.ToString());
811 additionalInfo.Add("mouse delta", delta.ToString());
764
812
765 additionalInfo.Add("Tracery Test", this.output);
813 additionalInfo.Add("Tracery Test", this.output);
766 debugWindow.Layout(debugInfo, additionalInfo, ref show_another_window);
814
815 debugWindow.Layout(debugInfo, additionalInfo, ref show_another_window);
767
816
768
817
769 debugWindow.ImGuiLayout();
818 //debugWindow.ImGuiLayout();
770
771 //String[] messages = { "Message1", "Message2" };
819 //String[] messages = { "Message1", "Message2" };
772
820
773 //DialogOption[] dialog = { new DialogOption{ response="Welcome to your new park, director! You can use the mouse or arrow keys to move around, and the plus and minus keys to zoom in and out.", choice="Okay" },
821 //DialogOption[] dialog = { new DialogOption{ response="Welcome to your new park, director! You can use the mouse or arrow keys to move around, and the plus and minus keys to zoom in and out.", choice="Okay" },
@@ -781,6 +829,11
781 ref this.simulation.paused, debugWindow.monoFont, this.currentNode);
829 ref this.simulation.paused, debugWindow.monoFont, this.currentNode);
782 }
830 }
783
831
832 if (this.showForest)
833 {
834 ForestWindow.Render(ref this.showForest, debugWindow.monoFont, this.simulation);
835 }
836
784
837
785 _imGuiRenderer.AfterLayout();
838 _imGuiRenderer.AfterLayout();
786
839
@@ -1,19 +1,58
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using static isometricparkfna.CellMap;
3 using static isometricparkfna.CellMap;
4 using System.Linq;
3
5
4 namespace isometricparkfna
6 namespace isometricparkfna
5 {
7 {
8 public struct Budget
9 {
10 public DateTime DateTime;
11
12 //assets
13 public decimal money;
14
15
16 //revenue
17 public decimal subsidy;
18
19 //expenses
20 public decimal upkeep;
21 public decimal tree_planting;
22 public decimal tree_clearing;
23
24
25 public decimal final_money;
26 public decimal cashflow;
27
28
29 //misc
30 public int trees;
31
32 }
33
6 public class Simulation
34 public class Simulation
7 {
35 {
8 public const int START_YEAR = 2020;
36 public const int START_YEAR = 2020;
9 public const int START_MONTH = 1;
37 public const int START_MONTH = 1;
10 public const int START_DAY = 1;
38 public const int START_DAY = 1;
11
39
40 public DateTime START_DATETIME{
41 get {
42 return new DateTime(START_YEAR, START_MONTH, START_DAY);
43 }}
44
12
45
13 private const float SPONTANEOUS_NEW_TREE_CHANCE = 0.9995f;
46 private const float SPONTANEOUS_NEW_TREE_CHANCE = 0.9995f;
14 private const float NEIGHBOR_NEW_TREE_CHANCE = 0.995f;
47 private const float NEIGHBOR_NEW_TREE_CHANCE = 0.995f;
15 private const float NEIGHBOR_CROWDS_TREE_CHANCE = 0.995f;
48 private const float NEIGHBOR_CROWDS_TREE_CHANCE = 0.995f;
16
49
50 public const int TREE_PLANT_COST = 750;
51 public const int TREE_CLEAR_COST = 500;
52
53 public const int MAX_TREES_TO_PLANT = 25;
54 public const int MAX_TREES_TO_CLEAR = 25;
55
17 public int Tick
56 public int Tick
18 {
57 {
19 get;
58 get;
@@ -37,6 +76,39
37
76
38 public decimal money;
77 public decimal money;
39
78
79 private List<Budget> budgets;
80
81
82 public Budget latestBudget
83 {
84 get
85 {
86 if (this.budgets.Count >= 1) {
87 return this.budgets[this.budgets.Count - 1];
88
89 }
90 else
91 {
92 return new Budget { };
93 }
94 }
95 }
96
97 public Budget previousBudget
98 {
99 get
100 {
101 if (this.budgets.Count >= 2) {
102 return this.budgets[this.budgets.Count - 2];
103
104 }
105 else
106 {
107 return new Budget { };
108 }
109 }
110 }
111
40 public float millisecondsPerAdvance { get; private set; }
112 public float millisecondsPerAdvance { get; private set; }
41 public String Season { get
113 public String Season { get
42 {
114 {
@@ -65,7 +137,62
65 private float lastAdvance;
137 private float lastAdvance;
66 public bool paused;
138 public bool paused;
67
139
68 private Random random;
140 private Random random;
141
142 //forest policy params
143 private int _tree_planting;
144 public int tree_planting
145 {
146 get {
147 return _tree_planting;
148 }
149 set {
150 _tree_planting = MathUtils.Clamp(value, 0, MAX_TREES_TO_PLANT);
151 }
152 }
153 private int _tree_clearing = 0;
154 public int tree_clearing
155 {
156 get {
157 return _tree_clearing;
158 }
159 set {
160 _tree_clearing = MathUtils.Clamp(value, 0, MAX_TREES_TO_CLEAR);
161 }
162 }
163
164 public int crowded_trees
165 {
166 get {
167 return this.map.iterate_cells_with_neighbors(7).Where(c => c.hasTree).Count();
168
169 }
170 }
171
172 public float healthy_percent
173 {
174 get {
175 return (float)(this.map.tree_count - this.map.iterate_cells_with_neighbors(7).Where(c => c.hasTree).Count()) / this.map.tree_count * 100;
176 }
177 }
178
179 public double average_tree_age
180 {
181 get
182 {
183 return this.map.iterate_cells().Where(c => c.hasTree).Select(c => (this.DateTime - c.planted).Days / 365.0).Average();
184 }
185 }
186
187 public double max_tree_age
188 {
189 get
190 {
191 return this.map.iterate_cells().Where(c => c.hasTree).Select(c => (this.DateTime - c.planted).Days / 365.0).Max();
192 }
193 }
194
195
69
196
70 public Simulation(int width, int height, float millisecondsPerAdvance)
197 public Simulation(int width, int height, float millisecondsPerAdvance)
71 {
198 {
@@ -74,10 +201,12
74 this.DateTime = new DateTime(START_YEAR, START_MONTH, START_DAY);
201 this.DateTime = new DateTime(START_YEAR, START_MONTH, START_DAY);
75
202
76 this.map = new CellMap(width, height);
203 this.map = new CellMap(width, height);
77 this.money = 1000;
204 this.money = 100000;
78 this.millisecondsPerAdvance = millisecondsPerAdvance;
205 this.millisecondsPerAdvance = millisecondsPerAdvance;
79
206
80 this.paused = true;
207 this.paused = true;
208
209 this.budgets = new List<Budget>();
81 }
210 }
82
211
83 private void advanceSimulation()
212 private void advanceSimulation()
@@ -85,30 +214,91
85
214
86 this.DateTime = this.DateTime.AddMonths(1);
215 this.DateTime = this.DateTime.AddMonths(1);
87
216
217
88 foreach (Cell cell in this.map.iterate_cells())
218 foreach (Cell cell in this.map.iterate_cells())
89 {
219 {
90 if (random.NextDouble() > SPONTANEOUS_NEW_TREE_CHANCE)
220 if (random.NextDouble() > SPONTANEOUS_NEW_TREE_CHANCE)
91 {
221 {
92 cell.hasTree = true;
222 cell.addTree(this.DateTime);
93 }
223 }
94 }
224 }
95
225
226 int new_planted = 0;
96 foreach (Cell cell in this.map.iterate_cells_with_neighbors(4))
227 foreach (Cell cell in this.map.iterate_cells_with_neighbors(4))
97 {
228 {
98 if (random.NextDouble() > NEIGHBOR_NEW_TREE_CHANCE)
229 if (random.NextDouble() > NEIGHBOR_NEW_TREE_CHANCE)
99 {
230 {
100 cell.hasTree = true;
231 cell.addTree(this.DateTime);
232 new_planted += 1;
101 }
233 }
102 }
234 }
235 System.Console.WriteLine(String.Format("New {0}", new_planted));
103
236
237 int crowded_out = 0;
104 foreach (Cell cell in this.map.iterate_cells_with_neighbors(7))
238 foreach (Cell cell in this.map.iterate_cells_with_neighbors(7))
105 {
239 {
106 if (random.NextDouble() > NEIGHBOR_CROWDS_TREE_CHANCE)
240 if (random.NextDouble() > NEIGHBOR_CROWDS_TREE_CHANCE)
107 {
241 {
108 cell.hasTree = false;
242 cell.markTreeDead();
243 crowded_out += 1;
244 }
245 }
246 System.Console.Write(String.Format("Crowded {0}", crowded_out));
247
248 int trees_to_plant = this.tree_planting;
249
250 while (trees_to_plant > 0 && this.map.remaining_tree_capacity > 0) {
251 int y = random.Next(0, this.map.MapHeight);
252 int x = random.Next(0, this.map.MapWidth);
253 Cell chosen_cell = this.map.cells[x][y];
254
255 if (!chosen_cell.hasTree) {
256 chosen_cell.addTree(this.DateTime);
257 trees_to_plant -= 1;
258 }
259 }
260
261
262 int trees_to_clear = this.tree_clearing;
263 System.Console.Write(String.Format("Found {0}; ", this.map.iterate_cells_with_neighbors(7).Where(c => c.hasTree).Count()));
264 foreach (Cell cell in this.map.iterate_cells_with_neighbors(7).Where(c => c.hasTree))
265 {
266 if (trees_to_clear > 0) {
267 cell.removeTree();
268 trees_to_clear -= 1;
109 }
269 }
110 }
270 }
271
272 Budget newBudget = new Budget
273 {
274 DateTime = this.DateTime,
275 money = this.money,
276 trees = this.map.tree_count,
277 subsidy = 1000,
278 upkeep = this.map.tree_count * 1,
279 tree_planting = this.tree_planting * Simulation.TREE_PLANT_COST,
280 tree_clearing = this.tree_clearing * Simulation.TREE_CLEAR_COST
281 };
282
283
284 newBudget = this.applyBudget(newBudget); ;
285 this.budgets.Add(newBudget);
111 }
286 }
287
288 public Budget applyBudget(Budget budget)
289 {
290
291 this.money = budget.money
292 - (budget.upkeep + budget.tree_planting + budget.tree_clearing)
293 + (budget.subsidy);
294
295
296 budget.final_money = this.money;
297 budget.cashflow = budget.final_money - budget.money;
298
299 return budget;
300 }
301
112 public void update(TimeSpan deltaTime)
302 public void update(TimeSpan deltaTime)
113 {
303 {
114 //this.Tick++;
304 //this.Tick++;
@@ -7,7 +7,7
7 using Microsoft.Xna.Framework;
7 using Microsoft.Xna.Framework;
8 using Microsoft.Xna.Framework.Graphics;
8 using Microsoft.Xna.Framework.Graphics;
9
9
10 namespace isometricparkfna
10 namespace isometricparkfna.UI
11 {
11 {
12
12
13 public struct DebugInfo
13 public struct DebugInfo
@@ -6,7 +6,7
6 using Num = System.Numerics;
6 using Num = System.Numerics;
7
7
8
8
9 namespace isometricparkfna
9 namespace isometricparkfna.UI
10 {
10 {
11
11
12
12
@@ -110,6 +110,7
110 {
110 {
111 ImGui.PushFont(font);
111 ImGui.PushFont(font);
112
112
113 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.None;
113 ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 0.0f);
114 ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 0.0f);
114 ImGui.PushStyleVar(ImGuiStyleVar.WindowRounding, 0.0f);
115 ImGui.PushStyleVar(ImGuiStyleVar.WindowRounding, 0.0f);
115 ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 1.0f);
116 ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 1.0f);
@@ -163,6 +164,7
163
164
164 }
165 }
165 ImGui.End();
166 ImGui.End();
167 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.Left;
166 ImGui.PopStyleVar(3);
168 ImGui.PopStyleVar(3);
167 ImGui.PopStyleColor(8);
169 ImGui.PopStyleColor(8);
168 ImGui.PopFont();
170 ImGui.PopFont();
@@ -19,6 +19,22
19
19
20 }
20 }
21
21
22 public static int Clamp(int val, int min, int max)
23 {
24 if(val > max)
25 {
26 return max;
27 }
28 else if (val < min)
29 {
30 return min;
31 }
32 else
33 {
34 return val;
35 }
36 }
37
22 protected float Decrement(float value, float delta)
38 protected float Decrement(float value, float delta)
23 {
39 {
24 float magnitude = Math.Abs(value);
40 float magnitude = Math.Abs(value);
@@ -43,5 +59,42
43 }
59 }
44 }
60 }
45
61
62
63 public static System.Collections.Generic.IEnumerable<Double> NextNormalEnumerator(Random random, float mean, float variation)
64 {
65
66 while (true) {
67 double u1 = random.NextDouble();
68 double u2 = random.NextDouble();
69
70 double z1 = Math.Sqrt(-2 * Math.Log(u1)) * Math.Cos(2 * Math.PI * u2);
71 double z2 = Math.Sqrt(-2 * Math.Log(u1)) * Math.Sin(2 * Math.PI * u2);
72
73 yield return (variation * z1) + mean;
74 yield return (variation * z2) + mean;
75 }
76 }
77
78 public static Double NextNormal(Random random, float mean, float variation)
79 {
80 //Uses Box-Muller to scale the default uniform distribution
81 double u1 = random.NextDouble();
82 double u2 = random.NextDouble();
83
84 double z1 = Math.Sqrt(-2 * Math.Log(u1)) * Math.Cos(2 * Math.PI * u2);
85 double z2 = Math.Sqrt(-2 * Math.Log(u1)) * Math.Sin(2 * Math.PI * u2);
86
87 if(random.NextDouble() > 0.5d) {
88 return (variation * z1) + mean;
89 }
90 else {
91 return (variation * z2) + mean;
92 }
93
94
95
96 }
97
46 }
98 }
99
47 }
100 }
@@ -41,12 +41,14
41 <Compile Include="Camera.cs" />
41 <Compile Include="Camera.cs" />
42 <Compile Include="DrawVertDeclaration.cs" />
42 <Compile Include="DrawVertDeclaration.cs" />
43 <Compile Include="ImGuiRenderer.cs" />
43 <Compile Include="ImGuiRenderer.cs" />
44 <Compile Include="DebugWindow.cs" />
45 <Compile Include="FilledRectangle.cs" />
44 <Compile Include="FilledRectangle.cs" />
46 <Compile Include="Simulation.cs" />
45 <Compile Include="Simulation.cs" />
47 <Compile Include="Utils\MathUtils.cs" />
46 <Compile Include="Utils\MathUtils.cs" />
48 <Compile Include="Utils\Node.cs" />
47 <Compile Include="Utils\Node.cs" />
49 <Compile Include="Dialog.cs" />
48 <Compile Include="UI\BudgetWindow.cs" />
49 <Compile Include="UI\DebugWindow.cs" />
50 <Compile Include="UI\Dialog.cs" />
51 <Compile Include="UI\ForestWindow.cs" />
50 </ItemGroup>
52 </ItemGroup>
51 <ItemGroup>
53 <ItemGroup>
52 <ProjectReference Include="..\FNA\FNA.csproj">
54 <ProjectReference Include="..\FNA\FNA.csproj">
You need to be logged in to leave comments. Login now