Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
RuleResync.cpp
Go to the documentation of this file.
1#include "RuleResync.hpp"
2
3#include "BoardRules.hpp"
4#include "Messaging.hpp"
5
6#include <cstddef>
7#include <cstdint>
8#include <vector>
9
11{
12 namespace
13 {
14 void putU8(
15 std::vector<std::uint8_t>& data,
16 std::uint8_t value)
17 {
18 data.push_back(value);
19 }
20
21
22 void putU32(
23 std::vector<std::uint8_t>& data,
24 std::uint32_t value)
25 {
26 for (int shift = 0;
27 shift < 32;
28 shift += 8)
29 {
30 putU8(
31 data,
32 static_cast<std::uint8_t>(
33 value >> shift
34 )
35 );
36 }
37 }
38
39
40 void putI64(
41 std::vector<std::uint8_t>& data,
42 std::int64_t value)
43 {
44 const std::uint64_t raw =
45 static_cast<std::uint64_t>(
46 value
47 );
48
49 for (int shift = 0;
50 shift < 64;
51 shift += 8)
52 {
53 putU8(
54 data,
55 static_cast<std::uint8_t>(
56 raw >> shift
57 )
58 );
59 }
60 }
61
62
63 std::vector<std::uint8_t>
65 const GameState& state,
66 Cause cause)
67 {
68 // Version moderne et explicitement packed du
69 // RULE_ClientResyncInfoRecord.
70
71 std::vector<std::uint8_t> data;
72
73 putU8(data, 1); // format version
74
75
76 // Cash.
77 for (PlayerNumber player = 0;
78 player < MaxPlayers;
79 ++player)
80 {
81 putI64(
82 data,
83 state.players[player].cash
84 );
85 }
86
87
88 // Property sets.
89 std::uint32_t mortgaged = 0;
90
91 std::uint32_t
93
94
95 for (std::size_t squareNo = 0;
96 squareNo <= 39;
97 ++squareNo)
98 {
99 const SquareState& square =
101
102
103 if (
104 square.owner >=
106 {
107 continue;
108 }
109
110
111 const std::uint32_t bit =
113 static_cast<
115 >(squareNo)
116 );
117
118
119 owned[
120 square.owner
121 ] |= bit;
122
123
124 if (square.mortgaged)
125 {
126 mortgaged |= bit;
127 }
128 }
129
130
131 for (const auto properties :
132 owned)
133 {
134 putU32(
135 data,
136 properties
137 );
138 }
139
140
141 putU32(
142 data,
143 mortgaged
144 );
145
146
147 // Player squares.
148 for (PlayerNumber player = 0;
149 player < MaxPlayers;
150 ++player)
151 {
152 putU8(
153 data,
154 state.players[player]
155 .currentSquare
156 );
157 }
158
159
160 // Jail card owners.
161 for (const CardDeck& deck :
162 state.cards)
163 {
164 putU8(
165 data,
166 deck.jailOwner
167 );
168 }
169
170
171 // Buildings.
172 for (const SquareState& square :
174 {
175 putU8(
176 data,
177 square.houses
178 );
179 }
180
181
182 putU8(
183 data,
184 static_cast<std::uint8_t>(
185 cause
186 )
187 );
188
189
190 const GamePhase currentPhase =
192 ? state.phaseStack[0].phase
194
195
196 putU8(
197 data,
198 static_cast<std::uint8_t>(
200 )
201 );
202
203
204 std::uint32_t firstMoves = 0;
205
206
207 for (PlayerNumber player = 0;
208 player <
210 ++player)
211 {
212 if (
213 state.players[player]
214 .firstMoveMade)
215 {
216 firstMoves |=
217 1u << player;
218 }
219 }
220
221
222 putU32(
223 data,
225 );
226
227
228 putU8(
229 data,
231 );
232
233
234 return data;
235 }
236 }
237
238
239 void sendClientState(const GameState& state, PlayerNumber toPlayer, Cause cause)
240 {
242
246
247 stateMessage.fromPlayer =
249
250 stateMessage.toPlayer =
251 toPlayer;
252
253 stateMessage.binaryDataA =
255 state,
256 cause
257 );
258
259
262 );
263 }
264
265
267 const GameState& state,
268 PlayerNumber toPlayer,
269 Cause cause,
271 {
272 // SendResyncMessages() original.
273
274 if (
275 toPlayer >=
277 {
278 toPlayer =
280 }
281
282
283 // ----------------------------------------------------
284 // Nombre de joueurs.
285 // ----------------------------------------------------
286
290 toPlayer,
292 0,
293 0,
294 0
295 );
296
297
298 // ----------------------------------------------------
299 // Configuration.
300 // ----------------------------------------------------
301
302 actions::Message configuration{};
303
304 configuration.action =
307
308 configuration.fromPlayer =
310
311 configuration.toPlayer =
312 toPlayer;
313
314 configuration.numberA =
316
317 configuration.numberB = 0;
318
319 // Star Wars Monopoly protocol version :
320 // 1 = futures support.
321 configuration.numberC = 1;
322
323
326 configuration.binaryDataA
327 );
328
329
331 configuration
332 );
333
334
335 // ----------------------------------------------------
336 // Players + AI state.
337 // ----------------------------------------------------
338
339 for (PlayerNumber player = 0;
340 player <
342 ++player)
343 {
344 const PlayerState& info =
345 state.players[player];
346
347
351 toPlayer,
352 player,
353 info.token,
354 info.colour,
355 info.aiPlayerLevel,
356 info.name
357 );
358
359
360 if (
361 !aiStates[player].empty())
362 {
363 actions::Message ai{};
364
365 ai.action =
368
369 ai.fromPlayer =
371
372 ai.toPlayer =
373 toPlayer;
374
375 ai.numberA =
376 player;
377
378 ai.binaryDataA =
379 aiStates[player];
380
381
383 }
384 }
385
386
387 // ----------------------------------------------------
388 // Compact game state.
389 // ----------------------------------------------------
390
391 sendClientState(state, toPlayer, cause);
392
393
394 // ----------------------------------------------------
395 // Futures / immunités actifs.
396 // ----------------------------------------------------
397
398 for (const CountHitRecord& hit :
400 {
401 if (
402 hit.toPlayer ==
403 NobodyPlayer ||
404 hit.tradedItem)
405 {
406 continue;
407 }
408
409
410 actions::Message update{};
411
412 update.action =
413 hit.hitType ==
419
420 update.fromPlayer =
422
423 update.toPlayer =
424 toPlayer;
425
426 update.numberA =
427 hit.toPlayer;
428
429 update.numberB =
430 hit.hitCount;
431
432 // SQ_OFF_BOARD :
433 // update global, pas consommation d'un hit.
434 update.numberC = 41;
435
436 update.numberD =
437 hit.fromPlayer;
438
439 update.numberE =
440 hit.properties;
441
442
444 update
445 );
446 }
447
448
449 // Réémettre le prompt de la phase courante.
454 );
455 }
456}
std::vector< std::uint8_t > data
unsigned index
std::uint16_t value
Definition Timers.cpp:16
bool sendAction(const actions::Message &message)
bool encodeOptions(const GameOptions &options, std::vector< std::uint8_t > &result)
std::array< std::vector< std::uint8_t >, MaxPlayers > AIStateArray
PropertySet propertyBit(SquareType square)
void sendClientState(const GameState &state, PlayerNumber toPlayer, Cause cause)
void sendAll(const GameState &state, PlayerNumber toPlayer, Cause cause, const archive::AIStateArray &aiStates)
constexpr PlayerNumber BankPlayer
Definition RuleTypes.hpp:15
std::uint8_t PlayerNumber
Definition RuleTypes.hpp:12
const GameState & state()
constexpr PlayerNumber MaxPlayers
Definition RuleTypes.hpp:14
constexpr PlayerNumber NobodyPlayer
Definition RuleTypes.hpp:16
constexpr PlayerNumber AllPlayers
Definition RuleTypes.hpp:17
std::array< CardDeck, static_cast< std::size_t >(DeckType::Count) > cards
std::array< CountHitRecord, MaxCountHitSets > countHits
std::array< SquareState, SquareCount > squares
std::array< PendingPhase, MaxPendingPhases > phaseStack
std::uint8_t numberOfPendingPhases
std::array< PlayerState, MaxPlayers > players