12 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 9};
14 struct CityCurrencyTags
22 {0x0056,0x0060,0x0061}, {0x0065,0x006F,0x0070},
23 {0x0074,0x007E,0x007F}, {0x0083,0x008D,0x008E},
24 {0x0092,0x009C,0x009D}, {0x00A1,0x00AB,0x00AC},
25 {0x00B0,0x00BA,0x00BB}, {0x00C8,0x00C9,0x00CA},
26 {0x00CE,0x00D8,0x00D9}, {0x00EA,0x00F4,0x00F5},
27 {0x00F9,0x0103,0x0103}, {0x00DD,0x00E7,0x00E7}}};
29 {0x005B,0x0062,0x0063}, {0x006A,0x0071,0x0072},
30 {0x0079,0x0080,0x0081}, {0x0088,0x008F,0x0090},
31 {0x0097,0x009E,0x009F}, {0x00A6,0x00AD,0x00AE},
32 {0x00B5,0x00BC,0x00BD}, {0x00C3,0x00CB,0x00CC},
33 {0x00D3,0x00DA,0x00DB}, {0x00EF,0x00F6,0x00F7},
34 {0x00FE,0x0104,0x0104}, {0x00E2,0x00E8,0x00E8}}};
37 const std::array<CityCurrencyTags, 12>&
table,
int city,
38 int monetarySystem)
noexcept
41 const auto index =
static_cast<std::size_t
>(city);
43 if (monetarySystem == 12)
return table[
index].euro;
48 std::uint8_t
cardIndex,
int city,
int monetarySystem)
noexcept
50 static constexpr std::array<std::array<CardTag, 13>, 7>
SystemCards{{
51 {{0x0055,0x0064,0x0073,0x0082,0x0091,0x00A0,0x00AF,0x00BE,0x00CD,0x00DC,0x00E9,0x00F8,0x004E}},
52 {{0x0057,0x0066,0x0075,0x0084,0x0093,0x00A2,0x00B1,0x00BF,0x00CF,0x00DE,0x00EB,0x00FA,0x004F}},
53 {{0x0058,0x0067,0x0076,0x0085,0x0094,0x00A3,0x00B2,0x00C0,0x00D0,0x00DF,0x00EC,0x00FB,0x0050}},
54 {{0x0059,0x0068,0x0077,0x0086,0x0095,0x00A4,0x00B3,0x00C1,0x00D1,0x00E0,0x00ED,0x00FC,0x0051}},
55 {{0x005C,0x006B,0x007A,0x0089,0x0098,0x00A7,0x00B6,0x00C4,0x00D4,0x00E3,0x00F0,0x00FF,0x0052}},
56 {{0x005D,0x006C,0x007B,0x008A,0x0099,0x00A8,0x00B7,0x00C5,0x00D5,0x00E4,0x00F1,0x0100,0x0053}},
57 {{0x005F,0x006E,0x007D,0x008C,0x009B,0x00AA,0x00B9,0x00C7,0x00D7,0x00E6,0x00F3,0x0102,0x0054}}}};
59 if (monetarySystem >= 0 && monetarySystem < 13)
69 case 2:
return 0x0105;
70 case 6: {
static constexpr std::array<CardTag,12>
t{0x005A,0x0069,0x0078,0x0087,0x0096,0x00A5,0x00B4,0x00C2,0x00D2,0x00EE,0x00FD,0x00E1};
return t[
static_cast<std::size_t
>(city)]; }
71 case 8:
return 0x0106;
72 case 9:
return 0x0107;
73 case 11:
return 0x0108;
74 case 13: {
static constexpr std::array<CardTag,12>
t{0x005E,0x006D,0x007C,0x008B,0x009A,0x00A9,0x00B8,0x00C6,0x00D6,0x00F2,0x0101,0x00E5};
return t[
static_cast<std::size_t
>(city)]; }
75 case 15:
return 0x0109;
81 std::uint8_t
cardIndex,
int city,
int monetarySystem)
noexcept
91 0x0128, 0x0137, 0x0146, 0x0155, 0x0164, 0x0173,
92 0x0182, 0x0191, 0x01A0, 0x01AF, 0x01BE, 0x01CD, 0x010A};
100 const rules::GameState&
state,
104 player <
state.numberOfPlayers;
108 const rules::GameState&
state,
115 return state.squares[square].owner;
118 template <std::
size_t N>
120 const rules::GameState&
state,
123 const std::array<std::uint8_t, N>&
group)
noexcept
125 for (
const auto square :
group)
139 [[
nodiscard]] std::optional<TokenReaction> skip(
149 return square == 5 || square == 15 ||
150 square == 25 || square == 35;
154 return square == 12 || square == 28;
158 -1, 0,-1, 1,-1, 2, 3,-1, 4, 5,
159 -1, 6, 7, 8, 9,10,11,-1,12,13,
160 -1,14,-1,15,16,17,18,19,20,21,
161 -1,22,23,-1,24,25,-1,26,-1,27,-1,-1};
164 const LandingEconomics&
economics)
noexcept
187 const auto token =
state.players[player].token;
197 if (!
state.players[player].firstMoveMade)
204 const auto square =
state.players[player].currentSquare;
206 square > 30 && square < 40
222 static_cast<std::uint16_t
>(
total - 2u));
228 bool victory,
bool localHuman)
noexcept
242 std::uint8_t property,
250 if (property >= 1 && property <= 3)
252 std::array<std::uint8_t, 2>{1, 3});
253 if (property >= 6 && property <= 9)
255 std::array<std::uint8_t, 3>{6, 8, 9});
256 if (property >= 11 && property <= 14)
258 std::array<std::uint8_t, 3>{11, 13, 14});
259 if (property >= 16 && property <= 19)
261 std::array<std::uint8_t, 3>{16, 18, 19});
262 if (property >= 21 && property <= 24)
264 std::array<std::uint8_t, 3>{21, 23, 24});
265 if (property >= 26 && property <= 29)
267 std::array<std::uint8_t, 3>{26, 27, 29});
268 if (property >= 31 && property <= 34)
270 std::array<std::uint8_t, 3>{31, 32, 34});
271 if (property >= 37 && property <= 39)
273 std::array<std::uint8_t, 2>{37, 39});
280 std::uint8_t property)
noexcept
283 state.players[player].aiPlayerLevel == 0)
289 if (property >= 1 && property <= 9)
291 if (property >= 11 && property <= 19)
293 if (property >= 21 && property <= 29)
295 if (property >= 31 && property <= 39)
305 state.players[player].aiPlayerLevel == 0)
321 std::uint8_t property)
noexcept
330 if (
state.players[player].aiPlayerLevel != 0)
return std::nullopt;
342 bool localHuman)
noexcept
346 for (
const auto& square :
state.squares)
348 if (
ownedSquares > 25 || !localHuman)
return std::nullopt;
356 bool localHuman)
noexcept
361 for (std::size_t square = 0; square <
state.squares.size(); ++square)
374 std::uint8_t square, std::uint32_t
random100)
noexcept
378 const bool computer =
state.players[player].aiPlayerLevel != 0;
383 if (square == 7 || square == 22 || square == 36)
385 if (square == 2 || square == 17 || square == 33)
387 if (square == 20 && (
random100 % 100u) < 20u)
392 return computer &&
state.options.doubleSalaryOnGo ? std::nullopt
414 int city, std::uint8_t square)
noexcept
424 0x0968u + square +
static_cast<std::uint32_t
>(
normalizedCity) * 41u);
431 city =
static_cast<int>(language) -
451 int monetarySystem, std::uint8_t
cardIndex)
noexcept
453 if (
cardIndex >= 32)
return std::nullopt;
457 city =
static_cast<int>(language) -
462 if (tag == 0)
return std::nullopt;
477 const bool computer =
state.players[player].aiPlayerLevel != 0;
483 return wait(
state.options.freeParkingPot
517 if (square == 2 || square == 7 || square == 17 || square == 22 ||
518 square == 30 || square == 33 || square == 36 || square == 40 ||
526 if (square >= 31 && square <= 34)
528 if (square >= 37 && square <= 39)
532 const auto other =
static_cast<std::uint8_t
>(square == 12 ? 28 : 12);
533 return wait(
state.squares[
other].owner == player
540 for (
const auto railroad : std::array<std::uint8_t, 4>{5, 15, 25, 35})
554 if (
state.squares[square].mortgaged)
560 const auto houses =
state.squares[square].houses;
561 if (houses ==
state.options.housesPerHotel)