2011-08-24 78 views
0

我仍然認爲自己是一個編程新手(我的名聲很大程度上是因爲gamedev.SE),因此我遇到了一個我自己無法解決的問題。如何跟蹤骰子滾動腳本中滾動的特定值?

我有一個函數,它接受指定數量的骰子並將它們滾動並返回結果。但是,如果它恰好將可用的最高值(例如,6)放在6面模具上,則會移除相關模具,然後在該位置滾動兩個新模子。它按預期工作,但我在實現另一個必要的部分時遇到問題:跟蹤1的滾動數量,特別是在最初的擲骰中滾動的數量。

from random import randint 

def roll_die(number, sides=6): 
    results = [] 
    for dice in range(number): 
     roll = randint(1, sides) 
     if roll == sides: 
      #rolling two new dice instead 
      results.append(roll_die(2, sides)) 
     else: 
      results.append(roll) 
    return sum(results) 

我也不能確定是否存儲在列表中的結果,然後將其加爲做到這一點的最好辦法,但我想我永遠也不會達到足夠多的骰子是擔心這一點。

我該如何跟蹤第一個擲骰子?當我說「第一」時,我的意思是在最初指定的數量內滾動,在因六個滾動而添加新的骰子之前。

回答

2

你(和對方的回答)使這種過於複雜。

不要立即擲新骰子。計算完成記賬後,需要擲出多少新擲骰子並擲骰。

請勿建立所有滾動的列表。你不需要它。滾動最初的骰子,收集統計數據,然後遞歸推出更多骰子。

避免編寫顯式循環來累積數據。 Python知道如何積累數據。只要告訴它你想在列表中結束(通過列表理解)。

不要進行多次遞歸調用。一個會做。想想你如何用物理骰子來做到這一點:你把六個人一起拉出來,然後把它們翻倍並重新卷好。

from random import randint 

def roll_dice(count, sides=6): 
    if count == 0: return (0, 0) # we need to guard against infinite recursion. 
    initial = [randint(1, sides) for die in range(count)] 
    initial_mins = initial.count(1) 
    initial_maxes = initial.count(sides) 
    # Add up all the dice that weren't maximum. 
    subtotal = sum(result for result in initial if result != sides) 
    # Recurse to re-roll the maxed-out dice. 
    ignored, reroll = roll_dice(2 * initial_maxes, sides) 
    return (initial_mins, subtotal + reroll) 

請注意,遞歸調用會返回一些我們忽略的初始值,因爲我們只關心第一次滾動的值。我們解開遞歸結果並保留有趣的值,即遞歸重新擲骰子的總數。

我們也能做到這一點反覆,並且最多隻能加在第一次迭代的:

from random import randint 

def roll_dice(count, sides=6): 
    initial_mins = None 
    result = 0 
    while count: 
     dice = [randint(1, sides) for die in range(count)] 
     if initial_mins == None: initial_mins = dice.count(1) 
     result += sum(result for result in dice if result != sides) 
     count = 2 * dice.count(sides) # number to roll the next time through. 
    return (initial_mins, result) 

注意如何None定點值用於確保我們設定的initial_mins在第一時間通過再每隔一段時間跳過一次。這比使用「不可能」的整數值(如-1)更清潔。擁抱動態打字。:)

+0

第一個版本進入無限循環;第二個是非常好的,所以謝謝你!列表推斷絕對是我需要更多練習的東西。 – RxS

+1

呃,對不起。如果你想要這種方式的話,需要檢查'count == 0'。 :)修正。 –

2

具有第二陣列也許original = []和的追加如果在else一個sides追加rollroll == sides一部分。你可以然後return [sum(results), original]。在你的if roll == sides:你然後必須做一些像results.append(roll_die(2,sides)[0])

回答你的清單問題,你可以將卷的值添加到每個卷,然後返回該值。

一個例子:

from random import randint 

def roll_die(number, sides=6): 
    results = [] 
    ones = 0 
    for dice in range(number): 
     roll = randint(1, sides) 
     if roll == sides: 
      #rolling two new dice instead 
      results.append(roll_die(2, sides)[0]) 
     else: 
      results.append(roll) 
     if roll == 1: 
      ones += 1 
    return sum(results), ones 
+0

我從閱讀你的答案中得到了想法,所以我不想單獨發佈它並可能從你那裏投票,所以我只是將它編輯成你的答案。如果你不喜歡它,請隨時取出。 – agf

+0

不用擔心,謝謝。 – smitec

+0

@agf啊,所以它會返回一個元組,並且任何遞歸也將返回一個元組,並且將索引追加到元組索引0(新卷的總和)?我是否正確閱讀? – RxS