2016-08-18 4 views
3

Ich erstelle eine Python-Anwendung, um das Spiel Perudo (oder Lügnerwürfel) zu spielen.Miniaturlisten an eine größere Liste anhängen

Ich versuche, eine Funktion zu erstellen, die alle möglichen Bewegungen berechnet, die der Spieler (oder AI) machen darf, und gibt eine Liste von ihnen zurück, so dass es illegale zurückweisen kann.

Umdrehungen werden als eine Liste von 2 Nummern gespeichert, z. [10,6] repräsentiert zehn Sechsen. Wenn die Startvariable currentbid ist(neunzehn drei) und es sind 20 Würfel im Spiel, dann sind die einzigen möglichen Züge 19 Vieren, 19 Fünfen, 19 Sechsen, 20 Zweien, 20 Dreiern, 20 Vieren, 20 Fünfen und 20 Sechsen. Anrufe von denen sind nicht erlaubt. Das Programm sollte eine Ausgabe der oben als:

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

sondern gibt es als:

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

Was mache ich falsch?

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

Umm ... klingt ein bisschen wie Lügners Würfel oder Perudo aber ohne einen Sonder zu sein ... –

+0

@JonClements Ja, ich hatte, dass in der Post gestellt, aber es verschwunden zu sein scheint! Zurück jetzt. 1s sind etwas Besonderes, aber ich habe das noch nicht erwähnt: P Momentan sind sie nur unkündbar. – tburrows13

Antwort

1

Das Problem ist, dass Sie list s verwenden, die veränderbare Objekte sind, und Sie sind Referenzen zu schaffen, anstatt Kopien. Man könnte es beheben die self.bid Liste jedes Mal durch Kopieren, aber die meisten „pythonic“ Lösung ist nicht list zu verwenden, aber tuple s zu verwenden, statt:

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 

Beachten Sie, dass dies nicht self.bid nicht aktualisiert (aber Sie können hinzufügen, dass in), und Sie erhalten eine list von unveränderlichen tuple s.

EDIT: Weil tuple s sind unveränderlich, ich Tupel verwendet haben Auspacken zwei Variablen zu erstellen. Dies ist das folgende Problem zu vermeiden:

>>> 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 

ich bid = (bid[0]+1, bid[1]) schreiben konnte, aber unter Verwendung von zwei Variablen ist, imho, leichter zu verstehen.


Im Allgemeinen ist es eine gute Faustregel, um sicherzustellen, dass alle Mitglieder der list s das gleiche bedeuten, während Werte verschiedene Dinge in tuple s oder dict Bedeutung s gehen oder benutzerdefinierte Behälter wie NamedTuple oder benutzerdefinierten Klassen.

In diesem Beispiel ist der äußere list enthält eine Anzahl von Angeboten, aber jeder der inneren list s hat eine Anzahl der Würfel und einen Wert , die vielleicht eine list zeigt, ist der falsche Typ zu verwenden.

+0

Danke, das scheint die hilfreichste Antwort zu sein. Nur damit ich es vollständig verstehe; würde es funktionieren, wenn ich 'moves moves.append ((bid [0], bid [1]))' setze? Ich nehme an, Sie haben es nur für die Klarheit und um zu betonen, dass die beiden in der Tüll sind anders, im Anschluss an Ihre Faustregel (was sehr hilfreich ist übrigens). – tburrows13

+0

@Gloin Siehe Bearbeiten, um zu antworten. – RoadieRich

0

Sie fügen das gleiche Objekt in Ihre Liste ein, was erklärt, dass Sie den 6-fachen Wert erhalten.

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

von

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

Du bist besser dran hier ersetzen im Denken über eine Basis 6 Nummer, wo Sie effektiv eine Reihe von Zahlen für 20 Würfel von 0 haben - inklusive 126.

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

Also, um dann die gültigen Gebote, die noch übrig sind, können Sie die Mathematik über den Bereich von 117 tun - 126 und die Anzahl der Würfel und Rest erhalten, die gültig ist.

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] 

Welche gibt Ihnen:

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

Das Problem ist der Verweis auf self.bid. Es ist die gleiche Variable immer und immer wieder in der Liste, was bedeutet, wenn Sie es in Ihrer Schleife aktualisieren, aktualisieren Sie jede Instanz (in diesem Fall alle Variablen in der Liste). Ich habe neu geschrieben, was Sie tun wollen, um so zu arbeiten, wie Sie wollen, falls Sie das gleiche Format behalten wollen, aber wie andere gesagt haben, können Sie es vom Codierungsstandpunkt her aufräumen.

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

Aber warum ist 'available_bid' nicht nur ein Verweis auf 'bid'? Ist das der Unterschied zwischen "available_bid = bid" und "available_bid = [bid [0], bid [1]]"? Was ist der Unterschied? – tburrows13

+0

Ich bin ziemlich sicher, dass es mit dem Schlüsselwort "self" zu tun hat. Diese Dokumentation erklärt ziemlich gut das Schlüsselwort "self": https://pythontips.com/2013/08/07/the-self-variable-in-python-explained/ Grundsätzlich bezieht sich das self-Schlüsselwort auf eine Instanz einer Variablen innerhalb von eine Klasse oder Methode richtig? Wenn Sie also diese Methode ausführen und ständig auf die self.variable zugreifen, greifen Sie auf die einzelne Instanz zu und erstellen keine neuen Instanzen der Variablen. –

Verwandte Themen