Description:
Merge in Milestone 1-Money (so far).
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
@@ -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 | 2 | Gameplay: |
|
3 | 3 | Money: |
|
4 | 4 | - Add basic subsidy @milestone(1: Basic Money) @done(2021-01-27) |
|
5 | - Balance sheet | |
|
5 | - Basic Balance sheet | |
|
6 | 6 | - Basic balance sheet @milestone(1: Basic Money) |
|
7 | 7 | - Basic display @done(2021-01-27) |
|
8 | 8 | - Movement @done(2021-01-27) |
@@ -16,7 +16,7 | |||
|
16 | 16 | - Outline reserved areas @milestone(3: Contracts) |
|
17 | 17 | - |
|
18 | 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 | 20 | - Add basic age simulation |
|
21 | 21 | - Biodiversity @maybe |
|
22 | 22 | - Research agreements @maybe |
@@ -67,8 +67,8 | |||
|
67 | 67 | Other features: |
|
68 | 68 | Accessibility: |
|
69 | 69 | - Verify contrast |
|
70 | - Increase display size | |
|
71 | - Turn off bad outcomes | |
|
70 | - Option to Increase display size | |
|
71 | - Option to Turn off bad outcomes or disasters? | |
|
72 | 72 | Other QoL things: |
|
73 | 73 | - Adjust display size |
|
74 | 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 | 51 | public CellMap() |
|
35 | 52 | { |
|
36 | 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 | 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 | 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 | 106 | foreach (List<Cell> row in cells) |
|
90 | 107 | { |
@@ -100,7 +117,7 | |||
|
100 | 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 | 122 | //iterates over neighbors (clockwise starting at noon/midnight) |
|
106 | 123 | if (inBounds(x, y + 1)) |
@@ -142,13 +159,15 | |||
|
142 | 159 | int count = 0; |
|
143 | 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 | 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 | 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 | 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 | 224 | } No newline at end of file |
@@ -1,4 +1,4 | |||
|
1 | using System.Collections.Generic; | |
|
1 | using System.Collections.Generic; | |
|
2 | 2 | using Microsoft.Xna.Framework; |
|
3 | 3 | using Microsoft.Xna.Framework.Audio; |
|
4 | 4 | using Microsoft.Xna.Framework.Input; |
@@ -14,6 +14,7 | |||
|
14 | 14 | using System.Diagnostics; |
|
15 | 15 | using static isometricparkfna.CellMap; |
|
16 | 16 | using isometricparkfna.Utils; |
|
17 | using isometricparkfna.UI; | |
|
17 | 18 | |
|
18 | 19 | |
|
19 | 20 | |
@@ -71,10 +72,13 | |||
|
71 | 72 | private Queue<Node<DialogOption>> remainingDialog; |
|
72 | 73 | |
|
73 | 74 | |
|
74 |
private bool showGrid |
|
|
75 | private bool showGrid; | |
|
75 | 76 | private Grammar grammar; |
|
76 | 77 | private string output; |
|
77 | 78 | private GraphicsDeviceManager gdm; |
|
79 | private bool showBudget; | |
|
80 | private BudgetWindow budgetWindow; | |
|
81 | private bool showForest; | |
|
78 | 82 | |
|
79 | 83 | private static void Main(string[] args) |
|
80 | 84 | { |
@@ -115,13 +119,20 | |||
|
115 | 119 | { |
|
116 | 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 | 131 | showInitial = true; |
|
124 | 132 | messageIndex = 0; |
|
133 | showBudget = false; | |
|
134 | showForest = true; | |
|
135 | showGrid = true; | |
|
125 | 136 | |
|
126 | 137 | this.Window.Title = "Isometric Park"; |
|
127 | 138 | |
@@ -129,8 +140,6 | |||
|
129 | 140 | |
|
130 | 141 | currentNode = DialogTrees.introTree; |
|
131 | 142 | |
|
132 | ||
|
133 | ||
|
134 | 143 | } |
|
135 | 144 | |
|
136 | 145 | protected override void Initialize() |
@@ -188,6 +197,9 | |||
|
188 | 197 | //font = fontBakeResult.CreateSpriteFont(GraphicsDevice); |
|
189 | 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 | 205 | protected override void UnloadContent() |
@@ -323,6 +335,16 | |||
|
323 | 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 | 348 | if (keyboardCur.IsKeyDown(Keys.C) && keyboardPrev.IsKeyUp(Keys.C)) |
|
327 | 349 | { |
|
328 | 350 | this.camera.Jump(Vector2.Zero); |
@@ -387,8 +409,15 | |||
|
387 | 409 | |
|
388 | 410 | #endregion input |
|
389 | 411 | |
|
412 | ||
|
413 | ||
|
390 | 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 | 422 | if (!this.showInitial && this.remainingDialog.Count > 0) |
|
394 | 423 | { |
@@ -673,15 +702,21 | |||
|
673 | 702 | |
|
674 | 703 | if (this.simulation.map.cells[i][j].hasTree) |
|
675 | 704 | { //until we actually simulate: |
|
676 | if ((i + j) % 8 == 0) | |
|
677 |
|
|
|
705 | drawTileAt(i, j, 142, 2); | |
|
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 | 716 | drawTileAt(i, j, 141, 2); |
|
679 | } | |
|
680 | else | |
|
681 | { | |
|
682 | drawTileAt(i, j, 142, 2); | |
|
683 | } | |
|
684 | } | |
|
717 | // System.Console.WriteLine(String.Format("Drew Dead Tree at {0},{1}", i, j)); | |
|
718 | ||
|
719 | } | |
|
685 | 720 | } |
|
686 | 721 | } |
|
687 | 722 | #endregion draw_trees |
@@ -716,17 +751,30 | |||
|
716 | 751 | this.Window.Title = String.Format("Isometric Park [{0:}]", header_middle); |
|
717 | 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 | 756 | FilledRectangle.drawFilledRectangle(batch, new Rectangle(0, 0, width, (int)dimensions.Y), Color.White, 0.51f); |
|
722 | 757 | |
|
723 | 758 | |
|
724 | 759 | batch.DrawString(monoFont, header_left, new Vector2(1, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f); |
|
725 | 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 | 779 | #region debug_window |
|
732 | 780 | //Calcs for debug window: |
@@ -763,11 +811,11 | |||
|
763 | 811 | additionalInfo.Add("mouse delta", delta.ToString()); |
|
764 | 812 | |
|
765 | 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(); | |
|
770 | ||
|
818 | //debugWindow.ImGuiLayout(); | |
|
771 | 819 | //String[] messages = { "Message1", "Message2" }; |
|
772 | 820 | |
|
773 | 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 | 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 | 838 | _imGuiRenderer.AfterLayout(); |
|
786 | 839 |
@@ -1,19 +1,58 | |||
|
1 | using System; | |
|
1 | using System; | |
|
2 | using System.Collections.Generic; | |
|
2 | 3 | using static isometricparkfna.CellMap; |
|
4 | using System.Linq; | |
|
3 | 5 | |
|
4 | 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 | 34 | public class Simulation |
|
7 | 35 | { |
|
8 | 36 | public const int START_YEAR = 2020; |
|
9 | 37 | public const int START_MONTH = 1; |
|
10 | 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 | 46 | private const float SPONTANEOUS_NEW_TREE_CHANCE = 0.9995f; |
|
14 | 47 | private const float NEIGHBOR_NEW_TREE_CHANCE = 0.995f; |
|
15 | 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 | 56 | public int Tick |
|
18 | 57 | { |
|
19 | 58 | get; |
@@ -37,6 +76,39 | |||
|
37 | 76 | |
|
38 | 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 | 112 | public float millisecondsPerAdvance { get; private set; } |
|
41 | 113 | public String Season { get |
|
42 | 114 | { |
@@ -65,7 +137,62 | |||
|
65 | 137 | private float lastAdvance; |
|
66 | 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 | 197 | public Simulation(int width, int height, float millisecondsPerAdvance) |
|
71 | 198 | { |
@@ -74,10 +201,12 | |||
|
74 | 201 | this.DateTime = new DateTime(START_YEAR, START_MONTH, START_DAY); |
|
75 | 202 | |
|
76 | 203 | this.map = new CellMap(width, height); |
|
77 | this.money = 1000; | |
|
204 | this.money = 100000; | |
|
78 | 205 | this.millisecondsPerAdvance = millisecondsPerAdvance; |
|
79 | 206 | |
|
80 | 207 | this.paused = true; |
|
208 | ||
|
209 | this.budgets = new List<Budget>(); | |
|
81 | 210 | } |
|
82 | 211 | |
|
83 | 212 | private void advanceSimulation() |
@@ -85,30 +214,91 | |||
|
85 | 214 | |
|
86 | 215 | this.DateTime = this.DateTime.AddMonths(1); |
|
87 | 216 | |
|
217 | ||
|
88 | 218 | foreach (Cell cell in this.map.iterate_cells()) |
|
89 | 219 | { |
|
90 | 220 | if (random.NextDouble() > SPONTANEOUS_NEW_TREE_CHANCE) |
|
91 | 221 | { |
|
92 |
cell. |
|
|
222 | cell.addTree(this.DateTime); | |
|
93 | 223 | } |
|
94 | 224 | } |
|
95 | 225 | |
|
226 | int new_planted = 0; | |
|
96 | 227 | foreach (Cell cell in this.map.iterate_cells_with_neighbors(4)) |
|
97 | 228 | { |
|
98 | 229 | if (random.NextDouble() > NEIGHBOR_NEW_TREE_CHANCE) |
|
99 | 230 | { |
|
100 |
cell. |
|
|
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 | 238 | foreach (Cell cell in this.map.iterate_cells_with_neighbors(7)) |
|
105 | 239 | { |
|
106 | 240 | if (random.NextDouble() > NEIGHBOR_CROWDS_TREE_CHANCE) |
|
107 | 241 | { |
|
108 |
cell. |
|
|
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 | 302 | public void update(TimeSpan deltaTime) |
|
113 | 303 | { |
|
114 | 304 | //this.Tick++; |
@@ -7,7 +7,7 | |||
|
7 | 7 | using Microsoft.Xna.Framework; |
|
8 | 8 | using Microsoft.Xna.Framework.Graphics; |
|
9 | 9 | |
|
10 | namespace isometricparkfna | |
|
10 | namespace isometricparkfna.UI | |
|
11 | 11 | { |
|
12 | 12 | |
|
13 | 13 | public struct DebugInfo |
@@ -6,7 +6,7 | |||
|
6 | 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 | 111 | ImGui.PushFont(font); |
|
112 | 112 | |
|
113 | ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.None; | |
|
113 | 114 | ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 0.0f); |
|
114 | 115 | ImGui.PushStyleVar(ImGuiStyleVar.WindowRounding, 0.0f); |
|
115 | 116 | ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 1.0f); |
@@ -163,6 +164,7 | |||
|
163 | 164 | |
|
164 | 165 | } |
|
165 | 166 | ImGui.End(); |
|
167 | ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.Left; | |
|
166 | 168 | ImGui.PopStyleVar(3); |
|
167 | 169 | ImGui.PopStyleColor(8); |
|
168 | 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 | 38 | protected float Decrement(float value, float delta) |
|
23 | 39 | { |
|
24 | 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 | 41 | <Compile Include="Camera.cs" /> |
|
42 | 42 | <Compile Include="DrawVertDeclaration.cs" /> |
|
43 | 43 | <Compile Include="ImGuiRenderer.cs" /> |
|
44 | <Compile Include="DebugWindow.cs" /> | |
|
45 | 44 | <Compile Include="FilledRectangle.cs" /> |
|
46 | 45 | <Compile Include="Simulation.cs" /> |
|
47 | 46 | <Compile Include="Utils\MathUtils.cs" /> |
|
48 | 47 | <Compile Include="Utils\Node.cs" /> |
|
49 |
<Compile Include=" |
|
|
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 | 52 | </ItemGroup> |
|
51 | 53 | <ItemGroup> |
|
52 | 54 | <ProjectReference Include="..\FNA\FNA.csproj"> |
You need to be logged in to leave comments.
Login now