Module mk2lib.cards

Classes for representing Machi Koro 2 Landmark and Establishment cards.

Classes

class Card (name: str, effect: CardEffect, quantity: int)
Expand source code
@dataclass
class Card(ABC):
    """
    Base card class with common fields.
    """

    name: str  # Enterprise type
    effect: CardEffect  # Effect of this card
    quantity: int  # Number of cards of that type

    @abstractmethod
    def get_real_price(self, game: MachiKoroGame, buyer: Player) -> int | None:
        """
        Calculate real price of this card for buyer & respecting game's active effects.

        This will apply all modifiers and effect rules to the base cost of card.

        :param game: Game for which price is checked. Used to check e.g. effects.
        :param buyer: Player, who wants to buy card. Used to check e.g. landmark count.
        :return: Integer with final cost of card. None if purchase is not possible.
        """
        raise NotImplementedError  # pragma: no cover

Base card class with common fields.

Ancestors

  • abc.ABC

Subclasses

Instance variables

var effect : CardEffect

The type of the None singleton.

var name : str

The type of the None singleton.

var quantity : int

The type of the None singleton.

Methods

def get_real_price(self, game: MachiKoroGame, buyer: Player) ‑> int | None
Expand source code
@abstractmethod
def get_real_price(self, game: MachiKoroGame, buyer: Player) -> int | None:
    """
    Calculate real price of this card for buyer & respecting game's active effects.

    This will apply all modifiers and effect rules to the base cost of card.

    :param game: Game for which price is checked. Used to check e.g. effects.
    :param buyer: Player, who wants to buy card. Used to check e.g. landmark count.
    :return: Integer with final cost of card. None if purchase is not possible.
    """
    raise NotImplementedError  # pragma: no cover

Calculate real price of this card for buyer & respecting game's active effects.

This will apply all modifiers and effect rules to the base cost of card.

:param game: Game for which price is checked. Used to check e.g. effects. :param buyer: Player, who wants to buy card. Used to check e.g. landmark count. :return: Integer with final cost of card. None if purchase is not possible.

class Establishment (name: str,
effect: CardEffect,
quantity: int,
activation_numbers: list[int],
cost: int,
category: Kind,
order: ActivationOrder)
Expand source code
@dataclass
class Establishment(Card):
    """Represents an Establishment card in Machi Koro 2."""

    activation_numbers: list[int]  # Numbers that this establishment activate on
    cost: int  # Price of this establishment to build
    category: Kind  # Category of this card
    order: ActivationOrder  # Activation order (color) of this card

    def get_real_price(self, game: MachiKoroGame, buyer: Player) -> int:
        """
        Get real price of this card for buyer.

        For Establishment card, it's always the only price drawn on the card.

        :param game: Game for which price is checked. Used to check e.g. effects.
        :param buyer: Player, who wants to buy card. Used to check e.g. landmark count.
        :return: Integer with final cost of card.
        """
        return self.cost  # Establishment always have one price for everyone

Represents an Establishment card in Machi Koro 2.

Ancestors

Instance variables

var activation_numbers : list[int]

The type of the None singleton.

var category : Kind

The type of the None singleton.

var cost : int

The type of the None singleton.

var order : ActivationOrder

The type of the None singleton.

Methods

def get_real_price(self, game: MachiKoroGame, buyer: Player) ‑> int
Expand source code
def get_real_price(self, game: MachiKoroGame, buyer: Player) -> int:
    """
    Get real price of this card for buyer.

    For Establishment card, it's always the only price drawn on the card.

    :param game: Game for which price is checked. Used to check e.g. effects.
    :param buyer: Player, who wants to buy card. Used to check e.g. landmark count.
    :return: Integer with final cost of card.
    """
    return self.cost  # Establishment always have one price for everyone

Get real price of this card for buyer.

For Establishment card, it's always the only price drawn on the card.

:param game: Game for which price is checked. Used to check e.g. effects. :param buyer: Player, who wants to buy card. Used to check e.g. landmark count. :return: Integer with final cost of card.

Inherited members

class Landmark (name: str,
effect: CardEffect,
quantity: int,
cost: list[int | None],
is_promo: bool,
kind: LandmarkKind)
Expand source code
@dataclass
class Landmark(Card):
    """Represents a Landmark card in Machi Koro 2."""

    cost: list[int | None]  # List of prices to buy this card for each landmark count
    is_promo: bool  # Whether this card is a part of promo addon
    kind: LandmarkKind  # Kind (and color) of this landmark

    def get_real_price(self, game: MachiKoroGame, buyer: Player) -> int | None:
        """
        Calculate real price of this card for buyer & respecting game's active effects.

        This will select right price for player's built landmark count, then will
        apply all active discounts. If player is not allowed to buy this card - it
        will return None.

        :param game: Game for which price is checked. Used to check e.g. effects.
        :param buyer: Player, who wants to buy card. Used to check e.g. landmark count.
        :return: Integer with final cost of card. None if purchase is not possible.
        """
        real_price = self.cost[len(buyer.landmarks)]
        if real_price is None:
            return None
        if buyer.have_loan_office:
            real_price -= 2
        if self.name == "launch_pad":
            if Effect.LAUNCH_PAD_DISCOUNT in game.active_effects:
                real_price -= 5
        if self.name == "loan_office":
            if not game.is_player_eligible_for_loan_office(buyer):
                return None
        return real_price

Represents a Landmark card in Machi Koro 2.

Ancestors

Instance variables

var cost : list[int | None]

The type of the None singleton.

var is_promo : bool

The type of the None singleton.

var kind : LandmarkKind

The type of the None singleton.

Methods

def get_real_price(self, game: MachiKoroGame, buyer: Player) ‑> int | None
Expand source code
def get_real_price(self, game: MachiKoroGame, buyer: Player) -> int | None:
    """
    Calculate real price of this card for buyer & respecting game's active effects.

    This will select right price for player's built landmark count, then will
    apply all active discounts. If player is not allowed to buy this card - it
    will return None.

    :param game: Game for which price is checked. Used to check e.g. effects.
    :param buyer: Player, who wants to buy card. Used to check e.g. landmark count.
    :return: Integer with final cost of card. None if purchase is not possible.
    """
    real_price = self.cost[len(buyer.landmarks)]
    if real_price is None:
        return None
    if buyer.have_loan_office:
        real_price -= 2
    if self.name == "launch_pad":
        if Effect.LAUNCH_PAD_DISCOUNT in game.active_effects:
            real_price -= 5
    if self.name == "loan_office":
        if not game.is_player_eligible_for_loan_office(buyer):
            return None
    return real_price

Calculate real price of this card for buyer & respecting game's active effects.

This will select right price for player's built landmark count, then will apply all active discounts. If player is not allowed to buy this card - it will return None.

:param game: Game for which price is checked. Used to check e.g. effects. :param buyer: Player, who wants to buy card. Used to check e.g. landmark count. :return: Integer with final cost of card. None if purchase is not possible.

Inherited members