在经历while循环后,从函数获取随机整数一直存在问题。该功能的目的是洗牌:
def shuffling(maindeck, shuffle_steps):
random.seed()
# sets a number of steps and creates a new array to be returned
steps = 0
shuffler = maindeck
while steps < shuffle_steps:
firstR = random.randrange(len(maindeck) - 1)
secondR = random.randrange(len(maindeck) - 1)
shuffler[firstR], shuffler[secondR] = shuffler[secondR], shuffler[firstR]
steps +=1
return shuffler
这是使用该功能的代码:
from deck import *
from shuffle import shuffling
gameState = True
while gameState:
input("Welcome to War! Press any key to continue... \n")
game_deck = shuffling(total_deck, 500)
while gameState and len(game_deck) > 1:
print("Both players draw a card...")
playerCard = game_deck.pop(0)
opponentCard = game_deck.pop(0)
# some code
keep_playing = input("Play again? (y/n) \n")
if keep_playing is not ('y' or 'Y'):
gameState = False
gameState = False
if len(game_deck) < 2:
print("No cards left!")
keepPlaying = input("Play again? (y/n) \n")
if keepPlaying is ('y' or 'Y'):
gameState = True
其中total_deck是来自文件deck.py的数组
这段代码在while循环的第一次迭代中运行良好,但是当循环迭代时,我得到了错误:
ValueError: empty range for randrange()
并且在
时发生错误random.randrange(len(Maindeck) - 1)
从开始被称为
len(Maindeck) - 1
现在得出等于或小于0的数字吗?为什么是这样?
答案 0 :(得分:1)
如果列表中有一组卡,并且想要重新整理整个序列,只需使用random.shuffle(sequence)进行就地改组。
如果要获取随机组合的副本,请使用random.sample()并将长度设置为序列的长度。
此行:
shuffler = maindeck
假设maindeck
属于某种可变列表数据结构,shuffler
引用的数据与maindeck
相同-您正在伪装maindeck
并将其返回-再往下,您正在操纵它。您可以使用random.sample()
来返回主甲板的改组副本。
random.seed()
设置生成您的随机性的Mersenne_Twister的开始内部状态-如果需要,可以设置一次,但不必每次遍历甲板时都设置一次。 Seeding
具有固定值的随机数将导致相同的随机数,因为您要使用相同的随机运算,因为每个随机运算都会更改内部状态-不需要任何种子就可以使用它,默认情况下会在源中完成:请参见Python's random: What happens if I don't use seed(someValue)?
您的代码应使用random.sample(maindeck,k=len(maindeck))
。
代码:
import random
random.seed(42) # generate same states if same operations are used
# https://en.wikipedia.org/wiki/Standard_52-card_deck
ranks = ["ace"] + [str(c) for c in range(2,11)] + ["jack", "queen", "king"]
colors = ["clubs","diamonds","hearts","spades"]
def generate_52_card_deck():
"""Returns a new deck of cards. Each card is a tuple of (rank,color)."""
return [ (r,c) for c in colors for r in ranks ]
deck = generate_52_card_deck()
print(deck)
# inplace
random.shuffle(deck)
print(deck)
new_deck = random.sample(deck,k=52)
print("sampled deck: ", new_deck[:10])
print("original deck: ", deck[::5])
输出:
# after generation (shortened)
[('ace', 'clubs'), ('2', 'clubs'), ('3', 'clubs'), ('4', 'clubs'),
('5', 'clubs'), ('6', 'clubs'), ('7', 'clubs'), ('8', 'clubs'),
('9', 'clubs'), ('10', 'clubs'), ('jack', 'clubs'), ('queen', 'clubs'),
('king', 'clubs'),
('ace', 'diamonds'), ('2', 'diamonds'), ('3', 'diamonds'), ('4', 'diamonds'),
('5', 'diamonds'), ('6', 'diamonds'), ('7', 'diamonds'), ... ,
('jack', 'spades'), ('queen', 'spades'), ('king', 'spades')]
# after shuffling once (shortened)
[('10', 'clubs'), ('jack', 'diamonds'), ('king', 'diamonds'), ('4', 'clubs'),
('9', 'diamonds'), ('king', 'hearts'), ('4', 'diamonds'), ('ace', 'spades'),
('7', 'diamonds'), ('queen', 'clubs'), ('8', 'spades'),
('queen', 'diamonds'), ('8', 'hearts'), ('4', 'hearts'), ...,
('9', 'spades'), ('2', 'clubs'), ('8', 'clubs'), ('2', 'spades')]
# first 10 cards ...
sampled deck: [('4', 'spades'), ('king', 'hearts'), ('ace', 'diamonds'),
('jack', 'clubs'), ('queen', 'hearts'), ('2', 'hearts'),
('6', 'diamonds'), ('3', 'spades'), ('8', 'hearts'),
('9', 'diamonds')]
# first 10 cards
original deck: [('10', 'clubs'), ('jack', 'diamonds'), ('king', 'diamonds'),
('4', 'clubs'), ('9', 'diamonds'), ('king', 'hearts'),
('4', 'diamonds'), ('ace', 'spades'), ('7', 'diamonds'),
('queen', 'clubs')]
如果您需要纸牌价值,请使用:
def get_base_card_value(c):
# ace == 11 not done here
v = {"ace":1 ,"jack":10, "queen":10, "king":10}
return v.get(c[0]) or int(c[0])
答案 1 :(得分:1)
啊!我看到了问题!您的游戏“用完了”主牌组,因为shuffling()
函数置换并返回了 the 原始牌组:
shuffler = maindeck
不会创建主卡座的副本。因此
game_deck.pop(0)
也从主甲板上拿卡。
修复:复制主卡座的深层副本并使用它(在shuffling()
中):
import copy
...
shuffler = copy.deepcopy(maindeck)
瞧!每个游戏都有一个全新的游戏甲板。