2016-08-18 47 views
3

我創建了一個python應用程序來玩遊戲Perudo(或者說謊者的骰子)。將微型列表添加到更大的列表

我正在嘗試創建一個函數來計算玩家(或AI)允許進行的所有可能的移動,並返回它們的列表,以便它可以拒絕非法移動。

圈數存儲爲2個數字的列表,例如, [10,6]代表十六個。 如果起始變量currentbid[19,3](十九三分),並且有20個骰子在場,那麼唯一可能的移動方式是19四十九,五十九,六六十,二十三,二十三,二十四,二十五和二十六。打電話是不允許的。 程序應該輸出上面爲:

[[19,4],[19,5],[19,6],[20,2],[20,3],[20,4],[20,5],[20,6]] 

,而是將其作爲:

[[20,6],[20,6],[20,6],[20,6],[20,6],[20,6],[20,6],[20,6]] 

我在做什麼錯?

def calcpossiblemoves(self, currentbid, totalnoofdice): 
    self.possiblemoves = [] # Create a list of possible moves that will be added too 

    self.bid = currentbid 

    while self.bid[0] <= totalnoofdice: 

     while self.bid[1] < 6: 
      self.bid[1] += 1 
      self.possiblemoves.append(self.bid)  # <- I think the problem is something to do with this line 
      print(self.possiblemoves) #For tracking the process 

     # Increase 1st number, reset 2nd number to 1 

     self.bid[0] += 1 
     self.bid[1] = 1 # Which will get increased to 2 
     #print("Reached 6") 
    return self.possiblemoves 
+0

唔......聽起來有點像大話骰或Perudo但沒有1的是特殊的... –

+0

@JonClements是的,我已經把那在後,但它似乎已經消失了!回到現在。 1是特殊的,但我還沒有把它放在:P現在它們只是不可接受的。 – tburrows13

回答

1

的問題是,你正在使用list s,這是可變的對象,而你正在創建引用,而不是拷貝。您可以通過每次複製self.bid列表修復它,但最「Python的」解決方案是不使用list,而是利用tuple S,而不是:

def calcpossiblemoves(self, currentbid, totalnoofdice): 
    possiblemoves = [] 

    numberof, value = currentbid 

    while numberOf <= totalnoofdice: 

     while value < 6: 
      value += 1 
      possiblemoves.append((numberOf, value)) 

     # Increase 1st number, reset 2nd number to 1 

     numberof += 1 
     value = 1 # Which will get increased to 2 
     #print("Reached 6") 
    return self.possiblemoves 

注意,這不更新self.bid(但你可以很容易地加入),並且你得到一個不可變的tuplelist

編輯:因爲tuple s爲不可變的,我用元組拆包創建兩個變量。這是爲了避免以下問題:

>>> bid = (1, 2) 
>>> bid[0] += 1 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'tuple' object does not support item assignment 

我可以寫bid = (bid[0]+1, bid[1]),但使用兩個變量是,恕我直言,更容易理解。


一般情況下,這是一個好的經驗法則來確保的list一切都成員意味着同樣的事情,而價值觀意味着不同的東西在tuple S或dict S,或諸如NamedTuple或自定義自定義容器去類。

在這個例子中,外list包含許多出價的,但每個內list S的具有數骰子和一,其指示list也許是錯誤的類型來使用。

+0

謝謝,這似乎是最有幫助的答案。只是爲了讓我完全理解它;如果我把'可能的moves.append((bid [0],bid [1]))',它會起作用嗎?我假設你只是爲了清晰起見,並強調在薄紗中兩者是不同的,遵循你的經驗法則(這是非常有用的btw)。 – tburrows13

+0

@Gloin見編輯回答。 – RoadieRich

0

您在列表中追加了相同的對象,這說明您獲得了最後一個值的6倍。

通過

self.possiblemoves.append(list(self.bid)) # make a copy of the list to make it independent from next modifications on self.bid 
1

你在這裏思考的一個基地6號最好更換

self.possiblemoves.append(self.bid)  # <- I think the problem is something to do with this line 

,你有有效的數字範圍爲0〜20個骰子 - 126包容。

current_bid = [19, 3] 
offset = current_bid[0] * 6 + current_bid[1] 
# 117 - and divmod(117, 6) == (19, 3) 

所以,再拿到那剩下的有效出價,則超過117的範圍內做數學 - 126,並獲得骰子,其餘這就是有效的數量。

valid_bids_with1s = ([n // 6, n % 6 + 1] for n in range(offset, 126)) 
valid_bids = [[a, b] for a, b in valid_bids_with1s if b != 1] 

它給你:

[[19, 4], 
[19, 5], 
[19, 6], 
[20, 2], 
[20, 3], 
[20, 4], 
[20, 5], 
[20, 6]] 
0

問題是對self.bid的引用。當你在你的循環中更新它時,它是一個又一個重複列表中的變量,你正在更新每個實例(本例中列表中的所有變量)。如果你想保持相同的格式,但是正如其他人所說的那樣,我已經重寫了你正在嘗試以你想要的方式工作,你可以從編碼的角度來清理它。

def calcpossiblemoves(currentbid, totalnoofdice): 
    possiblemoves = []# in range(totalnoofdice) #Create a list of possible moves that will be added too 

    bid = currentbid 
    available_bid = None 

    while bid[0] <= totalnoofdice: 

     while bid[1] < 6: 
      bid[1] += 1 
      available_bid = [bid[0],bid[1]] 
      possiblemoves.append(available_bid)  # <- I think the problem is something to do with this line 
      print(possiblemoves) #For tracking the process 

     # Increase 1st number, reset 2nd number to 1 

     bid[0] += 1 
     bid[1] = 1 # Which will get increased to 2 
     #print("Reached 6") 
    return possiblemoves 

calcpossiblemoves([19,3],20) 
+0

但爲什麼'available_bid'只是對'bid'的引用?這是「available_bid = bid」和「available_bid = [bid [0],bid [1]]」之間的區別嗎?有什麼不同? – tburrows13

+0

我很確定它與關鍵字「self」有關。本文檔很好地解釋了「self」關鍵字:https://pythontips.com/2013/08/07/the-self-variable-in-python-explained/基本上,self關鍵字指的是一個變量的實例一個類或方法是否正確?因此,如果您正在運行此方法並不斷訪問self.variable,那麼您將訪問單個實例,而不是創建該變量的新實例。 –