Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
RulePrediction.cpp
Go to the documentation of this file.
1#include "RulePrediction.hpp"
2
3#include "Actions.hpp"
4#include "BoardRules.hpp"
5#include "Messaging.hpp"
6#include "PhaseStack.hpp"
7#include "RuleRandom.hpp"
8
9#include <cstddef>
10#include <cstdint>
11
13{
14 namespace
15 {
16 constexpr std::uint8_t GoSquare = 0;
17 constexpr std::uint8_t JustVisitingSquare = 10;
18 constexpr std::uint8_t ElectricCompany = 12;
19 constexpr std::uint8_t PennsylvaniaRailroad = 15;
20 constexpr std::uint8_t IllinoisAvenue = 24;
21 constexpr std::uint8_t BAndORailroad = 25;
22 constexpr std::uint8_t WaterWorks = 28;
23 constexpr std::uint8_t ShortLineRailroad = 35;
24 constexpr std::uint8_t ReadingRailroad = 5;
25 constexpr std::uint8_t StCharlesPlace = 11;
26 constexpr std::uint8_t BoardwalkSquare = 39;
27 constexpr std::uint8_t InJailSquare = 40;
28 constexpr std::uint8_t OffBoardSquare = 41;
29
30
31 bool predictionPhase(
32 GamePhase phase)
33 {
34 switch (phase)
35 {
40 case GamePhase::
42 case GamePhase::
44 case GamePhase::
46 return true;
47
48 default:
49 return false;
50 }
51 }
52
53
55 const GameState& state)
56 {
57 if (
61 ))
62 {
63 return NobodyPlayer;
64 }
65
66
67 PlayerNumber player =
69
70
71 if (
72 player >=
74 {
75 return NobodyPlayer;
76 }
77
78
79 // Premier lancer :
80 // 0 == 0.
81 //
82 // Double :
83 // même joueur.
84 if (
85 state.dice[0] ==
86 state.dice[1])
87 {
88 return player;
89 }
90
91
92 while (true)
93 {
94 ++player;
95
96
97 if (
98 player >=
100 {
101 player = 0;
102 }
103
104
105 if (
106 player ==
108 {
109 break;
110 }
111
112
113 if (
114 state.players[player]
115 .currentSquare <
116 OffBoardSquare)
117 {
118 break;
119 }
120 }
121
122
123 return player;
124 }
125
126
127 std::uint8_t randomDie()
128 {
129 return
130 static_cast<std::uint8_t>(
131 (
133 6u
134 ) + 1u
135 );
136 }
137
138
139 void ensureNextDice(
141 {
142 if (state.nextDice[0] != 0)
143 {
144 return;
145 }
146
147
148 state.nextDice[0] =
149 randomDie();
150
151
152 // Exactement les trois appels de séparation
153 // du code original.
157
158
159 state.nextDice[1] =
160 randomDie();
161 }
162
163
164 std::uint8_t previewCard(
165 const GameState& state,
166 std::uint8_t squareNo)
167 {
168 if (squareNo >= SquareCount)
169 {
170 return 0;
171 }
172
173
174 const auto group =
176 static_cast<board::SquareType>(
178 )
179 ).group;
180
181
182 if (
183 group ==
185 {
186 return
187 state.cards[
188 static_cast<std::size_t>(
190 )
191 ].cardPile[0];
192 }
193
194
195 if (
196 group ==
198 {
199 return
200 state.cards[
201 static_cast<std::size_t>(
203 )
204 ].cardPile[0];
205 }
206
207
208 return 0;
209 }
210 }
211
212
215 {
216 // ====================================================
217 // PredictNextMove() original.
218 // ====================================================
219
220 if (
222 {
223 return;
224 }
225
226
227 PlayerNumber player =
229
230
231 if (
232 player >=
234 {
235 return;
236 }
237
238
239 std::uint8_t squareNo =
240 state.players[player]
241 .currentSquare;
242
243
244 if (squareNo >= OffBoardSquare)
245 {
246 return;
247 }
248
249
250 PlayerNumber movingPlayer =
251 player;
252
253
254 std::uint8_t movingFromSquare =
255 squareNo;
256
257
258 std::uint8_t movingToSquare =
259 OffBoardSquare;
260
261
264
265
267
268
269 const std::uint8_t totalRolled =
270 static_cast<std::uint8_t>(
271 state.nextDice[0] +
272 state.nextDice[1]
273 );
274
275
276 const bool doublesRolled =
277 state.nextDice[0] ==
278 state.nextDice[1];
279
280
281 const GamePhase phase =
283
284
285 // ----------------------------------------------------
286 // Carte en cours de lecture.
287 // ----------------------------------------------------
288
289 if (
290 phase ==
292 {
293 const auto group =
295 static_cast<board::SquareType>(
297 )
298 ).group;
299
300
301 const DeckType deck =
302 group ==
303 board::SquareGroup::
304 CommunityChest
307
308
309 const CardType card =
310 static_cast<CardType>(
311 state.cards[
312 static_cast<std::size_t>(
313 deck
314 )
315 ].cardPile[0]
316 );
317
318
319 switch (card)
320 {
321 case CardType::
323
324 case CardType::
326
330
333
334 break;
335
336
337 case CardType::
339
340 case CardType::
342
346
348 GoSquare;
349
350 break;
351
352
353 case CardType::
355
359
361 ReadingRailroad;
362
363 break;
364
365
366 case CardType::
368
372
373
374 if (
375 squareNo >=
376 ElectricCompany &&
377 squareNo <
378 WaterWorks)
379 {
381 WaterWorks;
382 }
383 else
384 {
386 ElectricCompany;
387 }
388
389 break;
390
391
392 case CardType::
394
398
401
402 break;
403
404
405 case CardType::
407
411
413 StCharlesPlace;
414
415 break;
416
417
418 case CardType::
420
421 case CardType::
423
427
428
429 if (
430 squareNo >=
431 ShortLineRailroad ||
432 squareNo <
433 ReadingRailroad)
434 {
436 ReadingRailroad;
437 }
438 else if (
439 squareNo <
440 PennsylvaniaRailroad)
441 {
443 PennsylvaniaRailroad;
444 }
445 else if (
446 squareNo <
447 BAndORailroad)
448 {
450 BAndORailroad;
451 }
452 else
453 {
455 ShortLineRailroad;
456 }
457
458 break;
459
460
461 case CardType::
463
467
469 IllinoisAvenue;
470
471 break;
472
473
474 case CardType::
476 {
480
481
482 int destination =
483 static_cast<int>(
485 ) - 3;
486
487
488 if (destination < 0)
489 {
490 destination +=
491 BoardwalkSquare + 1;
492 }
493
494
496 static_cast<std::uint8_t>(
498 );
499
500 break;
501 }
502
503
504 default:
505 {
506 player =
508 state
509 );
510
511
512 if (
513 player < MaxPlayers)
514 {
515 movingPlayer =
516 player;
517
518
520 state.players[player]
521 .currentSquare;
522
523
524 if (
526 OffBoardSquare)
527 {
531
532
534 static_cast<std::uint8_t>(
537 );
538
539
540 if (
543 {
546 1;
547 }
548 }
549 }
550
551 break;
552 }
553 }
554 }
555
556 // ----------------------------------------------------
557 // Un lancer de mouvement/prison est attendu.
558 // ----------------------------------------------------
559
560 else if (
561 phase ==
563 phase ==
565 phase ==
566 GamePhase::
568 {
569 if (
572 {
576
577
580 }
581 else
582 {
583 if (
584 squareNo ==
586 {
587 squareNo =
589 }
590
591
595
596
598 static_cast<std::uint8_t>(
599 squareNo +
601 );
602
603
604 if (
607 {
609 BoardwalkSquare + 1;
610 }
611 }
612 }
613
614 // ----------------------------------------------------
615 // La décision en cours terminera potentiellement
616 // le tour : prédire le prochain joueur.
617 // ----------------------------------------------------
618
619 else if (
620 phase ==
621 GamePhase::
623 phase ==
625 phase ==
628 {
629 player =
631 state
632 );
633
634
635 if (player < MaxPlayers)
636 {
637 movingPlayer =
638 player;
639
640
642 state.players[player]
643 .currentSquare;
644
645
646 if (
648 OffBoardSquare)
649 {
653
654
656 static_cast<std::uint8_t>(
659 );
660
661
662 if (
665 {
667 BoardwalkSquare + 1;
668 }
669 }
670 }
671 }
672
673
674 if (
675 movingAction ==
677 {
678 return;
679 }
680
681
682 const std::uint8_t card =
684 state,
686 );
687
688
690
693
694 notification.fromPlayer =
696
697 notification.toPlayer =
699
700 notification.numberA =
701 static_cast<std::int64_t>(
703 );
704
705 notification.numberB =
707
708 notification.numberC =
710
711 notification.numberD =
712 movingPlayer;
713
714 notification.numberE =
715 card;
716
717
720 );
721 }
722}
std::uint16_t group
unsigned index
bool sendAction(const actions::Message &message)
const SquareDefinition & definition(SquareType square)
const PendingPhase & current(const GameState &state)
void sendNextMove(GameState &state)
std::mt19937 & generator()
constexpr PlayerNumber BankPlayer
Definition RuleTypes.hpp:15
std::uint8_t PlayerNumber
Definition RuleTypes.hpp:12
constexpr std::size_t SquareCount
Definition RuleTypes.hpp:24
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< std::uint8_t, 2 > dice
std::array< CardDeck, static_cast< std::size_t >(DeckType::Count) > cards
std::uint8_t numberOfDoublesRolled
std::array< std::uint8_t, 2 > nextDice
std::uint8_t numberOfPendingPhases
std::array< PlayerState, MaxPlayers > players