15 constexpr std::array<GroupRange, rules::board::MaxPropertyGroups>
17 {1, 4}, {6, 10}, {11, 15}, {16, 20}, {21, 25},
18 {26, 30}, {31, 35}, {37, 40}, {5, 36}, {12, 29}}};
20 constexpr std::array<double, rules::SquareCount>
22 1.14, 0.77, 1.0, 0.8, 0.88, 1.14, 0.86, 1.0, 0.89, 0.9,
23 1.0, 1.05, 1.07, 0.87, 0.95, 1.08, 1.06, 1.0, 1.11, 1.14,
24 1.10, 1.07, 1.0, 1.02, 1.19, 1.14, 1.01, 1.02, 1.04, 0.98,
25 0.97, 0.99, 0.97, 1.0, 0.91, 0.88, 1.0, 0.8, 0.8, 0.98,
29 SquareType square)
noexcept
31 return static_cast<std::size_t
>(square);
35 std::size_t
index)
noexcept
43 const auto index =
static_cast<std::size_t
>(
group);
54 for (std::size_t
index = 0;
68 for (std::size_t
index = range.begin;
index < range.endExclusive; ++
index)
80 while (properties != 0)
82 if ((properties & 1U) != 0)
91 SquareType square)
noexcept
95 if (range.begin == range.endExclusive)
97 for (std::size_t
index = range.begin;
index < range.endExclusive; ++
index)
113 for (std::size_t
index = range.begin;
index < range.endExclusive; ++
index)
117 result.count < result.squares.size())
119 result.squares[result.count++] =
candidate;
127 std::swap(result.squares[
index], result.squares[0]);
134 SquareType square)
noexcept
139 for (std::size_t
index = range.begin;
index < range.endExclusive; ++
index)
150 SquareType square)
noexcept
156 const auto owner =
state.squares[
indexOf(square)].owner;
160 for (std::size_t
index = range.begin;
index < range.endExclusive; ++
index)
179 if (
group == SquareGroup::Railroad ||
group == SquareGroup::Utility)
189 for (std::size_t
index = range.begin;
index < range.endExclusive; ++
index)
234 SquareType square)
noexcept
241 SquareType square)
noexcept
245 for (std::size_t
index = range.begin;
index < range.endExclusive; ++
index)
263 if (
group != SquareGroup::Railroad &&
group != SquareGroup::Utility)
268 for (std::size_t
index = range.begin;
index < range.endExclusive; ++
index)
292 state.options.mortgagedCountsInGroupRent))
295 return definition.
rent[0] * 2;
304 if (definition.
group == SquareGroup::Utility)
305 return count == 2 ? 70 : 28;
306 if (definition.
group == SquareGroup::Railroad)
307 return definition.
rent[
static_cast<std::size_t
>(
count)];
309 return definition.
rent[0];
315 for (std::size_t
index = 0;
321 if (
state.options.maximumHouses < used)
323 return static_cast<std::uint8_t
>(
state.options.maximumHouses - used);
329 for (std::size_t
index = 0;
335 return static_cast<std::uint8_t
>(
state.options.maximumHotels - used);
351 std::int64_t
total{};
352 for (std::size_t
index = 0;
382 std::int64_t moneyOwed)
noexcept
387 return state.players[player].cash +
396 std::span<const std::int64_t> moneyOwed)
noexcept
399 excludedPlayer >=
state.numberOfPlayers)
403 current <
state.numberOfPlayers; ++current)
405 if (current == excludedPlayer ||
406 state.players[current].currentSquare ==
407 static_cast<std::uint8_t
>(SquareType::OffBoard))
409 const auto debt = current < moneyOwed.size() ? moneyOwed[current] : 0;
420 std::int64_t
total =
state.players[player].cash;
422 for (std::size_t
index = 0;
437 SquareType square)
noexcept
439 return static_cast<std::int64_t
>(
state.options.housesPerHotel) *
449 const auto propertyIndex =
static_cast<std::int64_t
>(
indexOf(property));
450 const auto boardwalk =
static_cast<std::int64_t
>(
indexOf(SquareType::Boardwalk));
456 const auto current =
static_cast<std::int64_t
>(
state.players[player].currentSquare);
459 auto distance = propertyIndex - current;
486 SquareType square)
noexcept
495 cost +=
static_cast<std::int64_t
>(
504 return group == SquareGroup::Utility ||
group == SquareGroup::Railroad;
516 std::int64_t startSquare,
525 const auto end =
static_cast<std::int64_t
>(
indexOf(SquareType::InJail));
528 const auto square =
squareAt(
static_cast<std::size_t
>(
index));
543 std::int64_t startSquare,
558 if (
static_cast<std::int64_t
>(
indexOf(SquareType::IncomeTax)) >= startSquare)
561 if (
state.options.luxuryTaxAmount > 0)
564 static_cast<double>(
state.options.luxuryTaxAmount);
565 if (
quotient >
static_cast<double>(
state.options.flatTaxFee))
566 total +=
static_cast<double>(
state.options.flatTaxFee) / 7.0;
571 if (
static_cast<std::int64_t
>(
indexOf(SquareType::LuxuryTax)) >= startSquare)
572 total +=
static_cast<double>(
state.options.luxuryTaxAmount) / 7.0;
573 return static_cast<std::int64_t
>(
total);
580 auto current =
static_cast<std::int64_t
>(
state.players[player].currentSquare);
581 if (current ==
static_cast<std::int64_t
>(
indexOf(SquareType::InJail)))
582 current =
static_cast<std::int64_t
>(
indexOf(SquareType::JustVisiting));
583 if (current >
static_cast<std::int64_t
>(
indexOf(SquareType::Boardwalk)))
594 std::clamp(
state.options.housesPerHotel, 0,
596 for (std::size_t
index = 0;
638 for (std::size_t
index = 0;
655 result.square = square;
667 player <
state.numberOfPlayers; ++player)
694 std::span<const rules::PlayerNumber>
players,
698 for (
const auto player :
players)
705 std::span<rules::PlayerNumber>
players,
706 std::size_t playerCount,
707 std::span<const rules::PlayerNumber> remove)
noexcept
709 playerCount = std::min(playerCount,
players.size());
713 for (std::size_t current = 0; current < playerCount; ++current)
727 std::span<const rules::board::SquareType> squares)
noexcept
729 for (
const auto square : squares)
731 if (square != SquareType::Go)
754 for (std::size_t
index = 0;
760 if (
static_cast<std::size_t
>(
group) <=
761 static_cast<std::size_t
>(SquareGroup::ParkPlace))
790 const int housesPerHotel =
state.options.housesPerHotel;
796 if (houses == housesPerHotel)
849 for (std::size_t
index = 0;
890 for (std::size_t
index = 0;
898 const double cost =
static_cast<double>(
940 state, player, SquareType::Boardwalk);
943 state, player, SquareType::StCharlesPlace);
965 state, player, SquareType::IllinoisAvenue);
970 state, player, 0,
true, 1.0);
976 const auto current =
static_cast<std::size_t
>(
landSquare);
1009 if (owner == player)
std::array< rules::PlayerNumber, rules::MaxPlayers > players
double averageRentReceived(const rules::GameState &state, rules::PlayerNumber player, std::int64_t startSquare, bool dontCountDevelopedMonopolies, double cashCowMultiplier, rules::board::PropertySet propertiesOwned) noexcept
MonopolyStage monopolyStage(const rules::GameState &state, rules::PlayerNumber player) noexcept
std::int64_t potentialIncome(const rules::GameState &state, rules::PlayerNumber player) noexcept
bool someoneCloseToMonopoly(const rules::GameState &state, rules::PlayerNumber player, const MonopolyLots &monopoly, std::int64_t minDistance, std::int64_t maxDistance) noexcept
int housesOnMonopoly(const rules::GameState &state, SquareType square) noexcept
MonopolyLots monopolyLots(SquareType square) noexcept
std::uint8_t freeHouses(const rules::GameState &state) noexcept
int propertyCount(rules::board::PropertySet properties) noexcept
std::int64_t minimumCalculatedExpenses(const rules::GameState &state, rules::PlayerNumber player) noexcept
double landingFrequency(SquareType square) noexcept
bool playerOwnsMonopoly(const rules::GameState &state, rules::PlayerNumber player, bool countBaltic) noexcept
std::size_t removePlayersFromList(std::span< rules::PlayerNumber > players, std::size_t playerCount, std::span< const rules::PlayerNumber > remove) noexcept
rules::board::PropertySet monopolySet(SquareType square) noexcept
bool isCashCow(SquareType square) noexcept
bool testForMonopoly(rules::board::PropertySet properties, SquareType square) noexcept
bool ownsMonopoly(const rules::GameState &state, rules::PlayerNumber player, SquareType square, bool mortgageCounts) noexcept
constexpr int SadReactionRent
SquareType findLowestRentProperty(const rules::GameState &state, rules::PlayerNumber player, rules::board::PropertySet properties) noexcept
constexpr int CriticalUnownedSquares
std::int64_t rentIfSteppedOn(const rules::GameState &state, SquareType square, rules::board::PropertySet propertiesOwned) noexcept
int numberRailroadsUtilitiesOwned(const rules::GameState &state, rules::PlayerNumber player, SquareGroup group, bool mortgageCounts, rules::board::PropertySet propertiesOwned) noexcept
void testSellHouses(rules::GameState &state, const MonopolyLots &monopoly, SquareType testSquare) noexcept
rules::board::PropertySet xorProperties(rules::board::PropertySet properties, std::span< const rules::board::SquareType > squares) noexcept
std::int64_t mostLiquidAssets(const rules::GameState &state, rules::PlayerNumber excludedPlayer, bool countMonopolies, std::span< const std::int64_t > moneyOwed) noexcept
std::int64_t totalWorth(const rules::GameState &state, rules::PlayerNumber player) noexcept
int monopoliesBetweenPlayers(const rules::GameState &state, std::span< const rules::PlayerNumber > players, rules::board::SquareType extraProperty) noexcept
int monopoliesInSet(rules::board::PropertySet properties) noexcept
int propertiesLeftToBuy(const rules::GameState &state) noexcept
std::int64_t liquidAssets(const rules::GameState &state, rules::PlayerNumber player, bool countHouses, bool countMonopolies, std::int64_t moneyOwed) noexcept
bool isMonopoly(const rules::GameState &state, SquareType square) noexcept
bool housingShortage(const rules::GameState &state, std::uint8_t criticalLevel) noexcept
constexpr std::array< rules::board::SquareType, 8 > ExpensiveMonopolySquares
std::int64_t liquidAssetsForProperties(const rules::GameState &state, rules::board::PropertySet properties, bool countHouses, bool countMonopolies) noexcept
rules::PlayerNumber firstOwnerInMonopoly(const rules::GameState &state, SquareType square) noexcept
bool playerCloseToProperty(const rules::GameState &state, rules::PlayerNumber ignorePlayer, SquareType property, std::int64_t minDistance, std::int64_t maxDistance) noexcept
HighestRentResult highestRentSquare(const rules::GameState &state, rules::PlayerNumber player) noexcept
MonopolyCollection monopoliesOwned(const rules::GameState &state, rules::PlayerNumber player, bool mortgageCounts) noexcept
bool anyMonopoly(const rules::GameState &state) noexcept
std::int64_t averageRentPaid(const rules::GameState &state, rules::PlayerNumber player, std::int64_t startSquare, bool considerDevelopedMonopolies, double cashCowMultiplier) noexcept
rules::PlayerNumber bestCurrentRent(const rules::GameState &state) noexcept
std::uint8_t freeHotels(const rules::GameState &state) noexcept
std::int64_t costUnmortgageMonopoly(const rules::GameState &state, SquareType square) noexcept
std::int64_t housesCanBuyOnMonopoly(const rules::GameState &state, SquareType square) noexcept
GroupRange groupRange(SquareGroup group) noexcept
SquareType findHighestRentMortgaged(const rules::GameState &state, rules::PlayerNumber player, rules::board::PropertySet properties, std::int64_t topUnmortgageCost) noexcept
rules::board::PropertySet propertiesOwnedByPlayer(const rules::GameState &state, rules::PlayerNumber player) noexcept
TokenReaction squareMoveReaction(const rules::GameState &state, rules::PlayerNumber player, SquareType landSquare, rules::CardType card) noexcept
bool ownsPropertyFromMonopoly(const rules::GameState &state, rules::PlayerNumber player, SquareType square) noexcept
constexpr int HappyReactionRent
rules::PlayerNumber mostExpensivePotentialIncome(const rules::GameState &state) noexcept
constexpr int AngryReactionRent
const SquareDefinition & definition(SquareType square)
constexpr std::size_t RentStepCount
constexpr std::size_t MaxPropertyGroups
std::uint32_t PropertySet
PropertySet propertyBit(SquareType square)
constexpr PlayerNumber BankPlayer
std::uint8_t PlayerNumber
@ ChancePay25EachHouse100EachHotel
@ CommunityGoDirectlyToJail
@ ChanceGoToIllinoisAvenue
@ ChanceGoToStCharlesPlace
@ CommunityGet200FromBank
@ CommunityPay40EachHouse115EachHotel
@ ChanceGoBackThreeSpaces
@ CommunityGet100FromBank1
@ CommunityGet100FromBank3
@ CommunityGet100FromBank2
constexpr PlayerNumber MaxPlayers
constexpr PlayerNumber NobodyPlayer
std::array< rules::board::SquareType, 8 > representatives
std::int64_t housePurchaseCost
std::int64_t mortgageCost
std::int64_t purchaseCost
std::array< std::int64_t, RentStepCount > rent