2

我的情况如下:我正在研究 BlackJack 的实现。我有卡片、手牌、玩家、甲板和游戏的课程。主要的游戏对象存储玩家和一副牌,而玩家存储存储卡片的手。

我经常做类似以下的事情。在这个例子中,我将初始牌发给每个玩家。

num_cards = 2
for player in self.players:
    new_hand = Hand()
    for i in range(num_cards):
        new_hand.add_card(self.deck.get_next_card())
    player.assign_hand(new_hand)

这非常有效。我现在的问题是我希望从玩家的手牌中删除一手牌(玩家可以在二十一点中分裂,导致生成多只手)。在下面的函数中,我打算循环遍历每个玩家的手牌。如果hand的值大于21,我想删除hand。(请注意,下面的 remove() 功能通常在 Player 类中执行,通过名为 fold_hand() 的 Player 方法调用。我遇到了同样的问题,因此为了说明目的,我将代码移到了更明显的地方。)

for player in self.players:
    for hand in player.hands:
        if hand.smallest_value() > 21:
            player.hands.remove(hand)

这不起作用。需要明确的是,我能够在 remove() 行之前打印出手,之后不会打印出来。也就是说,它似乎被删除了。然而,在下一轮比赛中,手又回来了。因此,玩家的手每回合都会增长。

上面的代码在 Game 类中名为 validate_player_hands() 的函数中。此函数从名为 play.py 的文件中调用,该文件用于开始/结束游戏并促进主游戏循环。因此,对 validate_player_hands() 的唯一调用是在 play.py 文件中,在游戏循环中缩进一个。我打电话:

game.validate_player_hands()

我也试过找到手的索引并使用'del'关键字,但结果是一样的。

为什么列表元素(名为 player.hands 的列表中的 Hand 对象)看起来已被删除时无法删除?

提前致谢,

典范RG

4

4 回答 4

3

如何使用简单的列表推导来消除手牌:

for player in self.players:
    player.hands = [hand for hand in player.hands if hand.smallest_value() <= 21]

编辑

带过滤器:

for player in self.players:
    player.hands = filter(lambda x: x.smallest_value() <= 21, player.hands)
于 2012-04-09T20:00:56.077 回答
2

创建一个副本并使用与对象长度相关的索引遍历对象。将要删除的每个元素设置为 0,然后过滤指针以清除零。

for player in self.players:
    for hand_idx in range(len(player.hands)):
        if player.hands[hand_idx].smallest_value() > 21:
            player.hands[hand_idx]=0
    player.hands=filter(None,hands)
于 2012-04-09T19:52:52.127 回答
0

您将需要执行以下操作:

newList = hands[:]   
for hand in newList:  
    if hand.smallest_value() > 21:  #your code here
            player.hands.remove(hand)

这允许您在迭代该副本时制作要修改的列表副本,从而避免 Mihai 提到的“树枝”场景。

于 2012-04-09T20:01:40.453 回答
0

这可以通过添加[:]到“for”语句的末尾来解决。这将创建列表的副本。然后,您可以在更改原始列表的同时遍历副本:

for player in self.players:
    for hand in player.hands[:]:
        if hand.smallest_value() > 21:
            player.hands.remove(hand)

(这是 Python 的列表切片语法。它是复制列表的最快方法之一。更常见的是,这种语法在表单some_list[3:8]中用于获取从索引 3 到 7(含)的列表条目,但是通过省略第一个数字,您可以获得从列表的开头开始的所有内容,并且通过省略最后一个数字,您可以将所有内容都放在列表的末尾)。

于 2012-04-09T20:24:16.513 回答