首页 > 解决方案 > 弹出列表后如何重新分配列表?

问题描述

如何为卡牌游戏制作可以在每场比赛开始时刷新的牌组?

我尝试过的代码似乎无法正常工作。它表明长度减少了,最后出现错误,即使它在继续后显示完整长度

      import random
import copy

deck=(2,3,4,5,6,7,8,9,10,'J','Q','K','A')

deck1=list(deck)

class player(object):
    def __init__ (self):
        self.hand=[]
        self.score=0
    def draw(self,num,d=deck1):
        for _ in range(num):
            
            ra=random.randint(
                0,len(d)-1)
            print('The number',ra,'the length=',len(d))
            self.hand.append(d.pop(ra))
            
def test1():
    
    ch1=input('Want to continue ? ')
    
    if ch1=='y':start()
    if ch1=='n':pass

def start():
    
    plr=player()
    dlr=player()
    deck1=copy.deepcopy(list(deck))    
    print('the length is',len(deck1),'\n')
    dlr.draw(2)
    plr.draw(2)
    test1()

start()
print(deck1)
test1()

输出:

> the length is 13 
>     
>     The number 11 the length= 13
>     The number 10 the length= 12
>     The number 3 the length= 11
>     The number 4 the length= 10
>     Want to continue ? y
>     the length is 13 
>     
>     The number 0 the length= 9
>     The number 3 the length= 8
>     The number 4 the length= 7
>     The number 3 the length= 6
>     Want to continue ? y
>     the length is 13 
>     
>     The number 3 the length= 5
>     The number 2 the length= 4
>     The number 1 the length= 3
>     The number 0 the length= 2
>     Want to continue ? y
>     the length is 13 
>     
>     The number 0 the length= 1

错误结束:

...File "C:\python38\lib\random.py", line 248, in randint
    return self.randrange(a, b+1)   File "C:\python38\lib\random.py", line 226, in randrange
    raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width)) 
ValueError: empty range for randrange() (0, 0, 0)

标签: python

解决方案


首要问题

第一个问题是 Python 的默认参数在定义函数时计算一次,而不是每次调用函数时(就像在 Ruby 中一样)参考

所以这段代码:

def draw(self,num,d=deck1):

通常改为:

def draw(self,num,d=None):
    if d is None:
        d = deck1

第二期

正常的补救措施不起作用,因为在调用者中定义了 deck1(即调用 Tree 是):

start ----> defines deck1
   draw --wants to access deck1

但这不可能在使用 python 调用父函数的子函数中访问父函数的变量,除非 draw 是 start 的嵌套函数。

修复——因为 draw 在它自己的类中,我们不能将 deck1 作为默认参数。

选项包括:

  1. 将 deck1 传递给 Player 类构造函数,或
  2. 通过deck1进行抽奖

使用选项 1(在这种情况下似乎更好),代码变为以下。

代码

import random
import copy

deck=(2,3,4,5,6,7,8,9,10,'J','Q','K','A')

deck1=list(deck)

class player(object):
    def __init__ (self, deck):
        self.hand=[]
        self.score=0
        self.deck = deck

    def draw(self, num):
        d = self.deck
        for _ in range(num):
            ra = random.randint(0, len(d)-1)
            print('The number',ra,'the length=',len(d))
            self.hand.append(d.pop(ra))  
            
def test1():
    ch1=input('Want to continue ? ')
    
    if ch1=='y':start()
    if ch1=='n':pass

def start():
    deck1=copy.deepcopy(list(deck)) 
    plr=player(deck1)
    dlr=player(deck1) 

    print('the length is',len(deck1),'\n')
    dlr.draw(2)
    plr.draw(2)
    test1()

start()
print(deck1)
test1()

输出

the length is 13 

The number 6 the length= 13
The number 9 the length= 12
The number 6 the length= 11
The number 3 the length= 10
Want to continue ? y
the length is 13 

The number 8 the length= 13
The number 9 the length= 12
The number 2 the length= 11
The number 5 the length= 10
Want to continue ? y
the length is 13 

The number 2 the length= 13
The number 2 the length= 12
The number 4 the length= 11
The number 6 the length= 10
Want to continue ? y
the length is 13 

The number 3 the length= 13
The number 9 the length= 12
The number 6 the length= 11
The number 1 the length= 10
Want to continue ?

最后说明

您的功能流程是递归的,即:

开始测试1 开始测试1 ...

这不是 Python 中的最佳实践,因为您最终会达到递归限制(默认情况下通常为 1000),但当前代码将适用于数百个游戏。正常模式是使用 while 循环而不是这种递归模式。


推荐阅读