Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
IBarRuleState.cpp
Go to the documentation of this file.
1#include "IBarRuleState.hpp"
2
3#include <optional>
4
5namespace monopoly::ibar
6{
7 namespace
8 {
9 [[nodiscard]] std::optional<rules::PlayerNumber> messagePlayer(
10 std::int64_t raw) noexcept
11 {
13 return std::nullopt;
14 return static_cast<rules::PlayerNumber>(raw);
15 }
16
17 void setMode(
18 RuleProjection& projection,
19 RuleMode mode,
20 std::int64_t rawPlayer) noexcept
21 {
22 const auto player = messagePlayer(rawPlayer);
23 if (!player)
24 return;
25 projection.mode = mode;
26 projection.player = *player;
27 }
28
30 actions::Type action) noexcept
31 {
32 switch (action)
33 {
43 return true;
44 default:
45 return false;
46 }
47 }
48 }
49
51 const actions::Message& message,
53 {
54 if (message.action != actions::Type::NotifyHousingShortage ||
56 {
57 return;
58 }
59
60 mode = message.numberC < 0
63 player = resolvedPlayer;
64 }
65
67 const actions::Message& message,
69 {
72 {
73 return;
74 }
75
76 mode = RuleMode::Trading;
77 player = resolvedPlayer;
78 }
79
80 void RuleProjection::process(const actions::Message& message) noexcept
81 {
82 if (message.action == actions::Type::NotifyActionCompleted)
83 {
84 if (message.numberB != 0 &&
85 message.numberA >= 0 &&
86 message.numberA <= static_cast<std::int64_t>(actions::Type::ClearTradedImmunitiesOrFutures) &&
87 acceptedActionClearsMode(static_cast<actions::Type>(message.numberA)))
88 {
89 mode = RuleMode::Nothing;
90 }
91 return;
92 }
93
94 switch (message.action)
95 {
97 setMode(*this, RuleMode::DoneTurn, message.numberA);
98 return;
100 setMode(*this, RuleMode::Nothing, message.numberA);
101 return;
103 setMode(*this, RuleMode::StartTurn, message.numberA);
104 return;
106 // UDIBar.cpp clears the rules mode but deliberately keeps the
107 // currently displayed IBar player.
108 mode = RuleMode::Nothing;
109 return;
111 {
112 const auto incomingPlayer = messagePlayer(message.numberA);
113 if (incomingPlayer)
114 {
116 player = *incomingPlayer;
117 raiseCashNeeded = message.numberC;
118 raiseCashCanBankrupt = message.numberE != 0;
119 }
120 return;
121 }
123 setMode(*this, RuleMode::BuyAuction, message.numberA);
124 return;
126 {
127 const bool canRoll = message.numberB != 0;
128 const bool hasCard = message.numberD != 0;
132 setMode(*this, jailMode, message.numberA);
133 return;
134 }
136 setMode(*this, RuleMode::ViewingCard, message.numberA);
137 return;
139 setMode(*this, RuleMode::Nothing, message.numberA);
140 return;
142 freeUnmortgageSet = static_cast<std::uint32_t>(message.numberB);
143 if (freeUnmortgageSet != 0)
144 setMode(*this, RuleMode::FreeUnmortgage, message.numberA);
145 return;
147 setMode(*this, RuleMode::TaxDecision, message.numberA);
148 return;
150 placeBuildingSet = static_cast<std::uint32_t>(message.numberC);
151 setMode(*this,
152 message.numberB < 0 ? RuleMode::PlaceHouse : RuleMode::PlaceHotel,
153 message.numberA);
154 return;
156 setMode(*this, RuleMode::HotelDecomposition, message.numberA);
157 return;
159 {
160 const auto bssmPlayer = messagePlayer(message.numberA);
161 if (!bssmPlayer)
162 return;
164 {
165 mode = RuleMode::Nothing;
166 return;
167 }
169 player = *bssmPlayer;
170 return;
171 }
173 {
174 const auto proposer = messagePlayer(message.numberA);
176 {
177 if (!tradeInProgress)
178 {
179 mode = RuleMode::Nothing;
180 player = *proposer;
181 }
182 tradeAPlayer = *proposer;
183 tradeBPlayer = rules::MaxPlayers;
184 tradeInProgress = true;
185 }
186 return;
187 }
189 {
190 const auto editor = messagePlayer(message.numberA);
192 tradeAPlayer = *editor;
193 return;
194 }
196 {
197 const auto from = messagePlayer(message.numberA);
198 const auto to = messagePlayer(message.numberB);
199 if (!from || !to || *from >= rules::MaxPlayers || *to >= rules::MaxPlayers)
200 return;
201 if (*from == tradeAPlayer)
202 tradeBPlayer = *to;
203 else if (*to == tradeAPlayer)
204 tradeBPlayer = *from;
205
206 // UDTrade.cpp rebuilds TradeB from every item, then clears the
207 // RULE bar to Nothing while keeping that reconstructed B player.
208 if (tradeBPlayer < rules::MaxPlayers)
209 {
210 mode = RuleMode::Nothing;
211 player = tradeBPlayer;
212 }
213 return;
214 }
216 if (message.numberA != -1)
217 {
218 tradeInProgress = false;
219 tradeAPlayer = rules::MaxPlayers;
220 tradeBPlayer = rules::MaxPlayers;
221 }
222 else
223 {
224 // Counter-offer: UDTrade may swap A/B for a local TradeB.
225 // The next TradeStarted/TradeEditor notification rebuilds the
226 // pair; do not guess local ownership in this pure projection.
227 tradeInProgress = false;
228 }
229 return;
231 setMode(*this, RuleMode::GameOver, message.numberA);
232 return;
234 if (message.numberA == 0)
235 reset();
236 return;
237 default:
238 return;
239 }
240 }
241}
unsigned index
std::uint8_t PlayerNumber
Definition RuleTypes.hpp:12
constexpr PlayerNumber MaxPlayers
Definition RuleTypes.hpp:14
constexpr PlayerNumber NobodyPlayer
Definition RuleTypes.hpp:16
void processHousingShortage(const actions::Message &message, rules::PlayerNumber resolvedPlayer) noexcept
void processTradeAcceptance(const actions::Message &message, rules::PlayerNumber resolvedPlayer) noexcept
void process(const actions::Message &message) noexcept