mega-commit, some from now, some from months ago. added a lot of logging tonight so we can watch a game in real-time. also included slowdown for the same purpose
This commit is contained in:
88
buy_decision_algos.py
Normal file
88
buy_decision_algos.py
Normal file
@@ -0,0 +1,88 @@
|
||||
"""
|
||||
from
|
||||
[here](https://blog.ed.ted.com/2017/12/01/heres-how-to-win-at-monopoly-according-to-math-experts/):
|
||||
'For every property (apart from the brown set — which, let’s be honest, is basically pointless),
|
||||
it’s the third house that is really worth investing in quickly. After that, build more if you have
|
||||
the money, but it’s probably worth waiting a few turns if cash is a bit tight. Since there are a
|
||||
limited number of houses in the game, building three houses on properties early and then waiting
|
||||
to upgrade further has the added advantage of potentially blocking the building projects of other
|
||||
players. Sneaky, huh?'
|
||||
'utilities are completely pointless.'
|
||||
"""
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from monopoly import Property, Player
|
||||
|
||||
|
||||
class BuyDecision(ABC):
|
||||
@abstractmethod
|
||||
def __call__(self, property_: "Property", player: "Player"):
|
||||
pass
|
||||
|
||||
|
||||
class BuyEverything(BuyDecision):
|
||||
def __call__(self, _, __):
|
||||
return True
|
||||
|
||||
|
||||
class BuyIfHaveThreeTimesPrice(BuyDecision):
|
||||
def __call__(self, property_: "Property", player: "Player"):
|
||||
return player.money >= property_.cost * 3
|
||||
|
||||
|
||||
class BuyIfDontHaveTwoPartialMonopoliesOfOtherColors(BuyDecision):
|
||||
def __call__(self, property_: "Property", player: "Player"):
|
||||
num_partial_monopolies = 0
|
||||
for property_type, properties in player.properties_by_type.items():
|
||||
if property_type in ("railroad", "utility"):
|
||||
continue
|
||||
if len(properties) == 3:
|
||||
num_partial_monopolies += 1
|
||||
if num_partial_monopolies == 3:
|
||||
print(
|
||||
f"{player.name} isn't buying {property_} because "
|
||||
f"they have {num_partial_monopolies} monopolies"
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class BuyIfOwnFewerThanFivePropertiesOrHaveOneOfThisColor(BuyDecision):
|
||||
def __call__(self, property_, player):
|
||||
num_properties = len(player.properties)
|
||||
if num_properties < 5:
|
||||
print(f"{player} wants to buy {property_}")
|
||||
return True
|
||||
for property_type, properties in player.properties_by_type.items():
|
||||
if property_type == property_.type:
|
||||
print(f"{player} wants to buy {property_}")
|
||||
return True
|
||||
print(f"{player} doesn't want to buy {property_}")
|
||||
return False
|
||||
|
||||
|
||||
class BuyIfNoOneOwnsTypeAndIsOfTheOneTypeOwned(BuyDecision):
|
||||
"""
|
||||
ALGORITHM
|
||||
---------
|
||||
If nobody owns this type of property, buy it.
|
||||
If only one player owns all owned property of this type, buy it.
|
||||
If this player owns any of this type fo property, buy it.
|
||||
"""
|
||||
|
||||
def __call__(self, property_, player):
|
||||
properties_of_this_type = Property.instances_by_type()[property_.type]
|
||||
if not any(p.owner for p in properties_of_this_type):
|
||||
return True
|
||||
# prevent others from getting monopolies
|
||||
if (
|
||||
len(set([p.owner for p in Property.instances_by_type()[property_.type]]))
|
||||
== 1
|
||||
):
|
||||
return True
|
||||
|
||||
players_property_types = player.properties_by_type.keys()
|
||||
if player.properties and property_.type in players_property_types:
|
||||
return True
|
||||
return False
|
||||
Reference in New Issue
Block a user