Ulq*_*aru 16 python list object cmp playing-cards
这是我第一次出现堆栈溢出,所以如果格式不适合该网站,我很抱歉.我刚刚开始学习编程,差不多已经过去了2周.我正在从http://openbookproject.net/thinkcs/python/english3e/index.html学习python, 直到现在一切都很好,我刚刚被困了好几个小时.我google了很多但找不到合适的解决方案来解决我的问题所以我在这里.
正如CH17所解释的那样,我试图让OldMaidGame()运行没有问题.http://openbookproject.net/thinkcs/python/english3e/ch17.html - 大部分代码也来自前一章.
我发现的是我无法使用Deck.remove,Hand.remove_matches或任何其他类型的删除功能.经过一些调试后,我发现当程序检查卡片/手/等中是否存在给定卡片时会出现问题.它不可能匹配.然后经过一些回顾章节,(在第16章),我发现'如果卡在甲板/手/等:删除(卡)'等查找.cmp()的对象,以确定卡实际上是否存在于deck/hand/etc中.这是我在电子书给定代码上添加'ace'之后的cmp版本.
def __cmp__(self, other):
""" Compares cards, returns 1 if greater, -1 if lesser, 0 if equal """
# check the suits
if self.suit > other.suit: return 1
if self.suit < other.suit: return -1
# suits are the same... check ranks
# check for aces first.
if self.rank == 1 and other.rank == 1: return 0
if self.rank == 1 and other.rank != 1: return 1
if self.rank != 1 and other.rank == 1: return -1
# check for non-aces.
if self.rank > other.rank: return 1
if self.rank < other.rank: return -1
# ranks are the same... it's a tie
return 0
Run Code Online (Sandbox Code Playgroud)
该CMP本身似乎罚款据我所知,OFC我可以使用上如何使它更好的(像ACE检查)的一些技巧.所以我不知道为什么牌组/手牌中的牌总是返回假.这是给定的删除功能:
class Deck:
...
def remove(self, card):
if card in self.cards:
self.cards.remove(card)
return True
else:
return False
Run Code Online (Sandbox Code Playgroud)
我拼命想让它发挥作用,我想出了这个:
class Deck:
...
def remove(self, card):
""" Removes the card from the deck, returns true if successful """
for lol in self.cards:
if lol.__cmp__(card) == 0:
self.cards.remove(lol)
return True
return False
Run Code Online (Sandbox Code Playgroud)
似乎工作正常,直到我转移到其他非工作删除功能:
class OldMaidHand(Hand):
def remove_matches(self):
count = 0
original_cards = self.cards[:]
for card in original_cards:
match = Card(3 - card.suit, card.rank)
if match in self.cards:
self.cards.remove(card)
self.cards.remove(match)
print("Hand {0}: {1} matches {2}".format(self.name, card, match))
count = count + 1
return count
Run Code Online (Sandbox Code Playgroud)
我再次做了一些调整:
class OldMaidHand(Hand):
def remove_matches(self):
count = 0
original_cards = self.cards[:]
for card in original_cards:
match = Card(3 - card.suit, card.rank)
for lol in self.cards:
if lol.__cmp__(match) == 0:
self.cards.remove(card)
self.cards.remove(match)
print("Hand {0}: {1} matches {2}".format(self.name, card, match))
count = count + 1
return count
Run Code Online (Sandbox Code Playgroud)
删除工作正常,但我尝试删除匹配时会出错(x不在列表中).另一个我们左右,我可能也能做到这一点,但因为我已经感觉我走错了道路,因为我无法修复原来的"卡片在甲板/手/等"等等,我来到这里寻找一些答案/提示.
感谢阅读,我非常感谢你能给予的任何帮助:)
---------------------编辑1 * >
这是我目前的代码:http: //pastebin.com/g77Y4Tjr
---------------------编辑2 * >
我已经尝试过在这里建议的每一个cmp,我仍然无法找到一个带有'in'的卡片.
>>> a = Card(0, 5)
>>> b = Card(0, 1)
>>> c = Card(3, 1)
>>> hand = Hand('Baris')
>>> hand.add(a)
>>> hand.add(b)
>>> hand.add(c)
>>> d = Card(3, 1)
>>> print(hand)
Hand Baris contains
5 of Clubs
Ace of Clubs
Ace of Spades
>>> d in hand.cards
False
>>>
Run Code Online (Sandbox Code Playgroud)
我也尝试过card.py @DSM已经成功使用了,我也遇到了错误,比如它在排序函数中说它无法比较两个卡对象.
所以我想知道,也许这是Python 3.2的问题,或者语法在某处发生了变化?
"所以我想知道,也许这是Python 3.2的一个问题,或者语法在某处发生了变化?"
哦,你在运行Python 3.2? 这将永远不会在Python 3中工作:python 3不使用__cmp__!
查看数据模型(查找__eq__).还读什么在Python 3的新功能对于一些其他的东西它的方式太容易错过.
对不起,这是我们这里的Python程序员; 我们应该早点抓住这个.大多数人可能会查看所有代码,实现甚至没有考虑到源代码显然是python 2代码,并假设这是我们正在使用的.Python 3.2中甚至不存在cmp函数,但是因为__cmp__它永远不会被调用,因此它不会被NameError引发.
如果我在Python 3.2中运行代码,我会完全重现您的问题:
>>> c = Card(0,2)
>>> str(c)
'2 of Clubs'
>>> c in [c]
True
>>> c in Deck().cards
False
Run Code Online (Sandbox Code Playgroud)
在Python 3中,您要么实现所有丰富的cmps,要么实现__eq__其中一个并使用total_ordering装饰器.
from functools import total_ordering
@total_ordering
class Card(object):
"""Represents a standard playing card."""
suit_names = ["Clubs", "Diamonds", "Hearts", "Spades"]
rank_names = [None, "Ace", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "Jack", "Queen", "King"]
def __init__(self, suit=0, rank=2):
self.suit = suit
self.rank = rank
def __str__(self):
return '%s of %s' % (Card.rank_names[self.rank],
Card.suit_names[self.suit])
def __repr__(self): return str(self)
def __lt__(self, other):
t1 = self.suit, self.rank
t2 = other.suit, other.rank
return t1 < t2
def __eq__(self, other):
t1 = self.suit, self.rank
t2 = other.suit, other.rank
return t1 == t2
>>> c = Card(2,3)
>>> c
3 of Hearts
>>> c in Deck().cards
True
Run Code Online (Sandbox Code Playgroud)