【问题标题】:NIM game, random range has error when range is between 1 and 1, need quick fix (not duplicate)NIM 游戏,范围在 1 和 1 之间时随机范围有错误,需要快速修复(不重复)
【发布时间】:2018-12-06 22:12:47
【问题描述】:

伙计们。我正在使用以下规则编写 NIM 游戏:

  • 从 n 个弹珠开始
  • 轮流移除堆中 1 到一半的弹珠(当前)
  • 失败者拿走最后一个弹珠/秒

我随机分配了弹珠的初始数量。我将“取”值定义为 1 到一半之间的随机整数。我这样做的方式是

nHalf = int(nNumMarbles/2)
nCTake = int(random.randrange(1,nHalf))

我这样做是为了使奇数的一半向下舍入(确实如此)。问题出现在游戏结束时,当用户将 nNumMarbles 降到 2 并且计算机必须 nC 取一个介于 1 和 nHalf 之间的随机数 - 即 1 和 1 之间。这是游戏的运行方式它已运行(错误在底部):

Python 3.6.3(v3.6.3:2c5fed8,2017 年 10 月 3 日,18:11:49)[MSC v.1900 64 bit (AMD64)] on win32 键入“copyright”、“credits”或“license()” 更多信息。

============ 重启:C:/Users/Name/Documents/CISPROG1/NIM.py ============ 14 欢迎来到 NIM 游戏!堆里有 14 颗弹珠。你和电脑将轮流从 桩。你们中的任何一个人最多可以拿走剩余的一半 转动。失败者拿走最后一个弹珠。

计算机将首先运行。

轮到电脑了!电脑需要 3 个弹珠。

还剩 11 个!

轮到你了!取 1 到 7 个弹珠:

2 你拿了 2 个弹珠。

还剩 9 个!

轮到电脑了!电脑需要 1 个弹珠。

还剩 8 个!

轮到你了!取 1 到 4 个弹珠:

1 你拿了 1 个弹珠。

还剩 7 个!

轮到电脑了!电脑需要 2 个弹珠。

还剩 5 个!

轮到你了!取 1 到 3 个弹珠:

1 你拿了 1 个弹珠。

还剩 4 个!

轮到电脑了!电脑需要 1 个弹珠。

还剩 3 个!

轮到你了!取 1 到 2 个弹珠:

1 你拿了 1 个弹珠。

还剩 2 个!

Traceback(最近一次调用最后一次):文件 “C:/Users/Name/Documents/CISPROG1/NIM.py”,第 27 行,在 nCTake = int(random.randrange(1,nHalf)) 文件“C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\random.py”,行 198,在随机范围内 raise ValueError("randrange() 的空范围 (%d,%d, %d)" % (istart, istop, width)) ValueError: randrange() 的空范围 (1,1, 0)

...这是我的程序:

import random
import sys
import time

nNumMarbles = int(random.randrange(10,100))
print(str(nNumMarbles))
print("Welcome to the game of NIM! \n"
      "There are " + str(nNumMarbles) + " marbles in the pile. \n"
      "You and the computer will take turns taking marbles from the pile. \n"
      "Either of you can take at most half of what remains per turn. \n"
      "The loser takes the last marble/s. \n")
#let 1 --> computer goes first, 2 --> user goes first
nFirst = random.randint(1,2)
if nFirst == 1:
    print("The computer will go first. \n")
else:
    print("You will go first. \n")

#Game progression if Computer goes first (only case I am testing)
if nFirst == 1:
    while nNumMarbles > 0:
        #Computer's turn:
        nHalf = int(nNumMarbles/2)
        nCTake = int(random.randrange(1,nHalf))
        nNumMarbles = nNumMarbles - nCTake
        print("Computer's turn! Computer takes " + str(nCTake) + " marbles. \n")
        if nNumMarbles == 0:
            print("The computer took the last marble! You win!")
            time.sleep(3)
            exit()
        else:
            pass
        print(str(nNumMarbles) + " left! \n")
        #User's turn:
        print("Your turn! Take between 1 and " +str(nHalf) + " marbles: \n")
        nUTake = int(input())
        nNumMarbles = nNumMarbles - nUTake
        print("You took " + str(nUTake) + " marbles. \n")
        if nNumMarbles == 0:
            print("You took the last marble! You lose!")
            time.sleep(3)
            exit()
        else:
            pass
        print(str(nNumMarbles) + " left! \n")

出了什么问题?如何修复它,以便当范围在 1 和 1 之间时,计算机取 (nCtake) 1,即最后一个弹珠?

【问题讨论】:

  • 撞了?我需要的是更好的方法来定义 nCtake(这样 randrange(1,1) 可以只替换为“1”。我试图添加一堆异常,但它变得丑陋了

标签: python random numbers range


【解决方案1】:

“问题出现在游戏结束时”。实际上,问题来得更早。只是直到最后你才注意到它。 random.randrange(a,b) 返回区间 [a,b) 内的随机整数。请注意,这从不包括b。您的代码不会选择介于 1 和剩余弹珠数量一半之间的随机整数。相反,它会选择一个介于 1 和 1 之间的随机数,小于弹珠的一半。

解决方法很简单:使用random.randint(a,b)。这是一个按照您期望 random.randrange 工作的方式工作的函数。

一个小点:您不需要使用int 和常规除法来计算nHalf。只需使用nHalf = nNumMarbles//2。此外,将intrandom.randrange 一起使用从来没有任何意义。该函数已经返回一个整数,即使它不是您想要的整数。

【讨论】:

    猜你喜欢
    • 2017-01-03
    • 2017-03-09
    • 1970-01-01
    • 2018-04-22
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多