You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在列表中嵌入类对象?MTG卡牌模拟开发技术求助

MTG Simulator: Fixing Object Display & Implementing Play Rules

Hey there! Let's break down how to fix your card display issue and implement the core play rules you need for your MTG simulator.

Fixing the Card Object Display Problem

Right now, when you print your list of Card objects, you're seeing memory addresses because Python uses the default __repr__ method for objects in containers (like lists). Your current __str__ method is also a bit redundant—let's fix both and add the is_tapped property you need for gameplay at the same time:

class Card:
    """Define MTG Card"""
    def __init__(self, name, cc, supertype):
        """(Card, int, str) -> NoneType"""
        self.name = name
        self.cc = cc
        self.supertype = supertype
        self.is_tapped = False  # Track if the card is tapped

    def __str__(self):
        # Return a human-friendly string for direct printing
        return f"{self.name} (Cost: {self.cc}, Type: {self.supertype})"

    def __repr__(self):
        # Return a string that shows useful info when in lists/debugging
        return f"Card('{self.name}', {self.cc}, '{self.supertype}')"

    def tap(self):
        """Mark the card as tapped"""
        if not self.is_tapped:
            self.is_tapped = True

    def untap(self):
        """Reset the card to untapped state"""
        if self.is_tapped:
            self.is_tapped = False

Why this works:

  • The __repr__ method tells Python what to show when your Card is in a list or printed directly in debug contexts.
  • We added tap() and untap() methods to handle the core state you need for land usage rules.

Implementing Core Play Rules

Next, let's update your Deck class to handle the 1-land-per-turn rule and mana payment via tapped lands. We'll also adjust how you store cards in the deck (using individual Card instances instead of [Card, amount] pairs to track state per-card):

from random import shuffle
import csv

class Deck:
    """Define MTG Deck"""
    def __init__(self, name, author, colour, cards):
        self.name = name
        self.author = author
        self.colour = colour
        self.cards = cards  # List of individual Card objects
        self.hand = []
        self.in_play = []  # Track cards on the battlefield
        self.csvData = []
        self.lands_played_this_turn = 0

    def shuffle_deck(self):
        """Shuffle the main deck"""
        shuffle(self.cards)

    def draw_card(self):
        """Draw a card from deck to hand"""
        if self.cards:
            self.hand.append(self.cards.pop())

    def play_land(self, card):
        """Play a land card, respecting the 1-per-turn limit"""
        if (card.supertype.lower() == "land" 
            and self.lands_played_this_turn < 1
            and card in self.hand):
            card.tap()
            self.in_play.append(card)
            self.hand.remove(card)
            self.lands_played_this_turn += 1
            return True
        return False

    def cast_spell(self, spell):
        """Cast a spell by tapping enough untapped lands"""
        if spell not in self.hand:
            return False
        
        # Count available untapped lands
        untapped_lands = [c for c in self.in_play if c.supertype.lower() == "land" and not c.is_tapped]
        if len(untapped_lands) >= spell.cc:
            # Tap the required number of lands
            for land in untapped_lands[:spell.cc]:
                land.tap()
            self.in_play.append(spell)
            self.hand.remove(spell)
            return True
        return False

    def end_turn(self):
        """Reset state for the next turn"""
        # Untap all cards in play
        for card in self.in_play:
            card.untap()
        self.lands_played_this_turn = 0

Adjust your card input logic:

Instead of storing [Card, amount] pairs, expand them into individual Card instances so you can track each card's state:

# Replace dcards.extend([[Card(userCardName, userCC, userSuperType), userAmount]])
for _ in range(userAmount):
    dcards.append(Card(userCardName, userCC, userSuperType))

Additional Code Improvements

  • Remove redundant cardData: Your Card class already stores name, cc, and supertype as separate properties—cardData duplicates this data unnecessarily.
  • CSV deck loading: Add a method to load decks from CSV files to avoid manual input every time:
    def load_from_csv(self, filepath):
        with open(filepath, 'r') as f:
            reader = csv.reader(f)
            next(reader)  # Skip header row
            for row in reader:
                name, cc, supertype, amount = row
                for _ in range(int(amount)):
                    self.cards.append(Card(name, int(cc), supertype))
    
  • Type hints: Add type hints to your methods for better readability and IDE support (e.g., def __init__(self, name: str, cc: int, supertype: str) -> None:).
  • Battlefield tracking: The in_play list we added keeps cards on the battlefield separate from your hand, which is critical for tracking tapped lands and creatures.

内容的提问来源于stack exchange,提问作者jimbob88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:12:43