Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
StatsCalculatorUI.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cstddef>
5#include <utility>
6
7namespace monopoly::statsui
8{
9 namespace
10 {
12 const CalculatorUIState& state) noexcept
13 {
14 return state.picker != CalculatorPicker::Player;
15 }
16
17 [[nodiscard]] bool publishResult(
18 CalculatorUIState& state,
19 const rules::GameState& gameState) noexcept
20 {
21 if (!state.activeFunction) return false;
22 auto result = calculate(
23 *state.activeFunction, gameState, state.selection);
24 if (!result)
25 {
26 state.result.reset();
27 state.error = result.error();
28 return false;
29 }
30 state.result = *result;
31 state.error.reset();
32 return true;
33 }
34 void beginFunction(
35 CalculatorUIState& state, std::uint8_t index) noexcept
36 {
37 state.activeFunction = static_cast<CalculatorFunction>(index);
38 state.hoveredFunction = index;
39 state.selection = {};
40 state.hoveredDeed.reset();
41 state.result.reset();
42 state.error.reset();
43 state.pressedNumber.reset();
45
46 switch (*state.activeFunction)
47 {
52 break;
59 break;
60 }
61 }
62 [[nodiscard]] bool chooseDeed(
63 CalculatorUIState& state, const rules::GameState& gameState,
64 int x, int y) noexcept
65 {
66 const auto deed = calculatorDeedHit(x, y);
67 if (!deed) return false;
68 state.selection.deed = *deed;
69 state.hoveredDeed.reset();
70
72 {
75 return true;
76 }
77
81 return true;
82 }
83
84 [[nodiscard]] bool choosePlayer(
85 CalculatorUIState& state, const rules::GameState& gameState,
86 int x, int y) noexcept
87 {
88 const auto player = calculatorTokenHit(gameState, x, y);
89 if (!player) return false;
90 state.selection.player = *player;
93 {
94 // Retail THIRD_STEP presses CalculatorButton[player].
95 state.pressedNumber = static_cast<std::uint8_t>(*player);
98 return true;
99 }
100
101 if (state.activeFunction == CalculatorFunction::MaximumExpense ||
102 state.activeFunction == CalculatorFunction::CurrentIncome ||
103 state.activeFunction == CalculatorFunction::MaximumIncome ||
105 {
106 // June 25 retail path hard-wires one turn and visually presses 1.
107 state.selection.turns = 1;
108 state.pressedNumber = 0;
111 return true;
112 }
113
116 return true;
117 }
118 }
119
120 std::optional<Rect> calculatorDeedRect(int square) noexcept
121 {
122 const int property = ibar::layout::propertyIndex(square);
123 if (property < 0) return std::nullopt;
124 const int left = 210 + 57 * (property % 7);
125 const int top = 240 + 45 * (property / 7);
126 return Rect{left, top, left + 36, top + 42};
127 }
128 std::optional<std::uint8_t> calculatorFunctionHit(
129 int x, int y) noexcept
130 {
131 for (std::uint8_t index = 0; index < 8; ++index)
132 if (calculatorFunctionRect(index).contains(x, y)) return index;
133 return std::nullopt;
134 }
135
136 std::optional<rules::PlayerNumber> calculatorTokenHit(
137 const rules::GameState& state, int x, int y) noexcept
138 {
139 const auto count = std::min<std::size_t>(
140 state.numberOfPlayers, rules::MaxPlayers);
141 for (std::size_t index = 0; index < count; ++index)
142 {
143 const auto player = static_cast<rules::PlayerNumber>(index);
144 if (calculatorTokenRect(player).contains(x, y)) return player;
145 }
146 return std::nullopt;
147 }
148
149 std::optional<int> calculatorDeedHit(int x, int y) noexcept
150 {
151 for (int square = 0; square < static_cast<int>(rules::SquareCount); ++square)
152 {
153 const auto rect = calculatorDeedRect(square);
154 if (rect && rect->contains(x, y)) return square;
155 }
156 return std::nullopt;
157 }
159 {
160 state = {};
161 }
162
165 {
166 const bool visible = view == display::Screen2D::Portfolio;
167 if (!visible && state.visible)
168 {
170 return;
171 }
172 state.visible = visible;
173 }
174
177 display::Screen2D view, const uimsg::Message& message) noexcept
178 {
180 if (!state.visible) return false;
181
182 const int x = static_cast<int>(message.numberA);
183 const int y = static_cast<int>(message.numberB);
184 if (message.type == uimsg::Type::MouseMoved)
185 {
186 if (state.picker == CalculatorPicker::Deed)
187 {
188 state.hoveredDeed = calculatorDeedHit(x, y);
189 return false;
190 }
191 state.hoveredDeed.reset();
192 if (state.step >= CalculatorStep::Second) return false;
193 const auto function = calculatorFunctionHit(x, y);
194 if (function)
195 {
196 state.hoveredFunction = *function;
198 }
199 else
200 {
201 state.hoveredFunction.reset();
202 state.activeFunction.reset();
203 state.result.reset();
204 state.error.reset();
206 state.pressedNumber.reset();
208 }
209 return false;
210 }
211
212 if (message.type != uimsg::Type::MouseLeftDown) return false;
213
215 calculatorNumberRect(10).contains(x, y))
216 {
218 state.visible = true;
219 return true;
220 }
221
222 switch (state.step)
223 {
225 return false;
226
228 {
229 const auto function = calculatorFunctionHit(x, y);
230 if (!function) return false;
232 return true;
233 }
235 if (!state.activeFunction) return false;
236 switch (*state.activeFunction)
237 {
241 return chooseDeed(state, gameState, x, y);
247 return choosePlayer(state, gameState, x, y);
248 }
249 return false;
250
252 if (state.activeFunction == CalculatorFunction::FutureValueToOther)
253 return choosePlayer(state, gameState, x, y);
254 return false;
255
257 return false;
258 }
259 return false;
260 }
261}
std::size_t count
std::atomic< float > left
int top
unsigned state
unsigned index
Rect rect
int propertyIndex(int square) noexcept
std::uint8_t PlayerNumber
Definition RuleTypes.hpp:12
constexpr std::size_t SquareCount
Definition RuleTypes.hpp:24
constexpr PlayerNumber MaxPlayers
Definition RuleTypes.hpp:14
bool processCalculatorInput(CalculatorUIState &state, const rules::GameState &gameState, display::Screen2D view, const uimsg::Message &message) noexcept
std::expected< CalculatorResult, std::string > calculate(CalculatorFunction function, const rules::GameState &state, const CalculatorSelection &selection) noexcept
std::optional< Rect > calculatorDeedRect(int square) noexcept
constexpr Rect calculatorTokenRect(rules::PlayerNumber player) noexcept
std::optional< std::uint8_t > calculatorFunctionHit(int x, int y) noexcept
void resetCalculatorUI(CalculatorUIState &state) noexcept
constexpr Rect calculatorFunctionRect(std::uint8_t index) noexcept
void syncCalculatorView(CalculatorUIState &state, display::Screen2D view) noexcept
constexpr Rect calculatorNumberRect(std::uint8_t index) noexcept
std::optional< rules::PlayerNumber > calculatorTokenHit(const rules::GameState &state, int x, int y) noexcept
std::optional< int > calculatorDeedHit(int x, int y) noexcept
constexpr bool contains(int x, int y) const noexcept
Definition StatsUI.hpp:38