骰子滚动游戏。直方图?

时间:2013-12-04 00:04:48

标签: python python-3.x dice

需要帮助创建一个垂直直方图,其中“#”表示我获得的卷数。它最多包含80个字符。这就是我到目前为止所拥有的。我可以用我需要的方式打印所有内容,除了我的直方图有很多麻烦。

import random
from collections import defaultdict

def main():
    dice = int(input("Enter the number of dice: "))
    sides = int(input("Enter the number of sides: "))
    rolls = int(input("Enter the number of rolls to simulate: "))
    result = roll(dice, sides, rolls)
    for i in range(dice, dice * sides + 1):
        print('{:2d}{:10,d}{:10.4%}'.format(i, result[i], result[i] / rolls))
    print(histogram(result, dice, sides, rolls))

def roll(dice, sides, rolls):
    d = defaultdict(int)
    for i in range(rolls):
        d[sum(random.randint(1, sides) for i in range(dice))] += 1
    return d

def histogram(result, dice, sides, rolls):
    maxBar = str(80)
    for x in result:
        p = str(x)
        if p <= maxBar:
            p += '#'
    return p

main()

输出示例::

   5          7  0.0070% 
   6         64  0.0640% 
   7        191  0.1910% #
   8        429  0.4290% ###
   9        942  0.9420% #######
  10      1,629  1.6290% ############
  11      2,701  2.7010% #####################
  12      3,911  3.9110% ###############################
  13      5,375  5.3750% ##########################################
  14      6,849  6.8490% ######################################################
  15      8,383  8.3830% ##################################################################
  16      9,371  9.3710% ##########################################################################
  17     10,051 10.0510% ################################################################################
  18      9,972  9.9720% ###############################################################################
  19      9,453  9.4530% ###########################################################################
  20      8,371  8.3710% ##################################################################
  21      7,022  7.0220% #######################################################
  22      5,517  5.5170% ###########################################
  23      3,824  3.8240% ##############################
  24      2,586  2.5860% ####################
  25      1,661  1.6610% #############
  26        936  0.9360% #######
  27        462  0.4620% ###
  28        195  0.1950% #
  29         78  0.0780% 
  30         20  0.0200% 

2 个答案:

答案 0 :(得分:1)

如果我是你,我会使用字典来跟踪结果。对于您拥有的每个结果,将其转换为字符串并检查该字符串是否在字典中(或者,使用try:except块并捕获KeyError异常),如果没有则添加它,如果是,则递增它。这是一些示例代码:

num_dice = getNumDice() #however you're doing this
num_sides = getSides() #however you're doing this
num_rolls = getRolls() #however you're doing this

result_dict = {}

for _ in xrange(num_rolls):
  result = str(rollDice(num_dice,num_sides)) #you can build this yourself, I'm not doing everything for you! :)
  if result in result_dict:
    result_dict[result] +=1
  else:
    result_dict[result] = 1

#alternatively, using try/catch, see the commented code below
#in place of the if/else block:
#
#  try:
#    result_dict[result] +=1
#  except KeyError as e:
#    result_dict[result] = 1
#------------------------------------------------------------

这将使你的result_dict填充类似{'2':5,'3':8,'4':12,'5':26,'6':51,'7':92,'8 ':50,...,'12':9}。您应该能够轮询该数据以打印输出。如果您需要更多帮助,请使用一些试用代码进行评论,我将为您排除故障。

根据您的要求编辑以下的直方图

对于直方图,您应该返回一个函数,将您需要的“#”数量映射到您需要的数字。实际上,获得正确的比例是非常简单的交叉乘法。

sum_of_result   num_of_hashes
------------- = -------------
 total_rolls     total_hashes

如果将这些变量传递给直方图函数,它应该能够返回一个数组,其中每个结果旁边应该有多少个#,您可以将它们合并到打印函数中。让我们给它一个旋转。

def histogram(roll_array,total_hashes=80): 
# that second argument lets us reuse this code for a
# differently scaled histogram without changing our
# code -- this is HUGE in coding.

  total_rolls = sum([roll_array[i] for i in range(len(roll_array))])
# sums up all the results across the array. We could also
# pass this directly to histogram, but (as before) this makes
# the code a little more reusable.

  output_array = defaultdict(int)
  for i in range(len(roll_array)):
    output_array[i] = roll_array[i]*total_hashes/total_rolls
#   this iterates through the output_array, setting each index equal
#   to the number of hashes we should use to accurately describe
#   each result, using the math I talked about earlier.

  return output_array

现在我们有了一个函数,histogram(可能更好地描述为make_histogram或者等等)返回一个等长的数组(实际上是一个字典,但是函数就像一个数组)它传递的骰子卷阵列。给定roll_array(即main函数中d中表示的数量,该数组中的每个索引都有一个与准确显示该数量的哈希标记相关的值。 }})

现在为您的打印功能。你知道乘法如何与字符串一起使用,对吧?如果没有,请进入IDLE并立即查找。输入"I Shall Always Experiment With Code\n" 50次,然后尝试将其乘以50。

很酷,对吗?现在不是在main的末尾添加第二个print语句,而是尝试使用histogram的返回数组(再次,它是一个字典,但我们现在不需要关心它,因为所有键都是数字只是像数组中的索引一样显示那些与你当前的打印功能一致的#。

此外,这是一种离散的功能。可能值得将其从main函数中分离出来并制作def display_result(roll_array,hist_array):或类似内容。

同样,如果您需要帮助,请询问。

Here是我对此问题的完整代码,适用于任何未来的堆栈器:)

答案 1 :(得分:1)

我个人会做这样的事情:

import random
from collections import defaultdict

def main():
    dice = int(input("Enter the number of dice: "))
    sides = int(input("Enter the number of sides: "))
    rolls = int(input("Enter the number of rolls to simulate: "))
    result = roll(dice, sides, rolls)
    maxH = 0
    for i in range(dice, dice * sides + 1):
        if result[i] / rolls > maxH: maxH = result[i] / rolls
    for i in range(dice, dice * sides + 1):
        print('{:2d}{:10d}{:8.2%} {}'.format(i, result[i], result[i] / rolls, '#' * int(result[i] / rolls / maxH * 40)))


def roll(dice, sides, rolls):
    d = defaultdict(int)
    for _ in range(rolls):
        d[sum(random.randint(1, sides) for _ in range(dice))] += 1
    return d

main()