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)

これは見事に機能します。私の問題は、プレーヤーの手のセットから手を削除したいということです (プレーヤーはブラックジャックで分割され、複数のハンドが生成される可能性があります)。次の関数では、各プレイヤーの手札をループするつもりです。ハンドの値が 21 より大きい場合、ハンドを削除します。(以下の remove() 機能は、通常、fold_hand() という名前の Player メソッドを介して呼び出される 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() への唯一の呼び出しは、ゲーム ループ内の 1 つのインデント内の 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]の方法の 1 つです。多くの場合、この構文は、インデックス 3 から 7 までのリスト エントリを取得するフォームで使用されますが、最初の数字を除外することで取得できます。リストの先頭からすべてを取得し、最後の番号を省略すると、リストの最後までのすべてを取得できます)。

于 2012-04-09T20:24:16.513 に答える