כתבו מחלקה בשם Card המממשת קלף משחק שלו שתי תכונות: צורה ומספר.
המחלקה תתמוך בפעולה __str__ ותאפשר להשוות בין שני קלפים לפי מספרם בלבד בעזרת סימני השוויון: < , <= , == , >= , > . השתמשו במתודות קסם.
כעת, כתבו מחלקה בשם Deck שתכליתה אחסון של אוסף קלפים. אם היא אינה מקבלת חפיסת קלפים היא תיצור בעצמה חפיסת קלפים רגילה בת 52 קלפים, כאשר נסיך ייוצג כ־11, מלכה כ־12 ומלך כ־13. המחלקה תתמוך בפעולות הבאות (נסו להשתמש בכמה שיותר מתודות קסם):
2.1 איחוד שתי חפיסות ליצירת חפיסה חדשה.
2.2 בדיקה של האם קלף מסוים נמצא בחפיסה
2.3 הפעולה len על חפיסה תחזיר את מספר הקלפים הנמצאים בה.
2.4 טריפת החפיסה.
2.5 שליפת קלף מהחפיסה – שליפת הקלף תוציא את הקלף מהחפיסה.
2.6 פעולה שמקבלת כפרמטרים את מספר השחקנים ואת מספר הקלפים שיחולקו לכל שחקן. הפעולה תיצור רשימה של ידי שחקנים, כאשר יד של שחקן היא בפני עצמה רשימת הקלפים שחולקו לו.
אשמח להבהרה: Deck מקבלת רשימה של קלפים או n קלפים? רשום “חפיסת קלפים” אבל זה לא עוזר לי להבנה.
orpazf
אני מימשתי עם רשימת קלפים
לייק 1
gonny
מרגיש לי ש2.6 לא באמת לחלוטין אמורה להיות פעולה של המחלקה deck. לטעמי היא יותר שייכת למחלקה של משהו כמו game.
orpazf
זו כמובן אפשרות. לדעתי מכיוון שחלוקת קלפים היא מחפיסה, ולא למשל מיד של שחקן או מסתם רשימת קלפים, היא מתאימה יותר להיות תחת Deck
gonny
לכן לא אמרתי שהיא שייכת ליד של שחקן, אלא למשחק עצמו. פה אנחנו ממש מבצעים פעולות של משחק ולא פעולות של deck. מה שאנחנו מקבלים בחזרה הוא לא מאפיין של deck.
import random
class Card:
def __init__(self, value, suit):
self.value = value
self.suit = suit.upper()
def __str__(self):
return f'{self.value}{self.suit}'
def __lt__(self, other):
return self.value < other.value
def __le__(self, other):
return self.value <= other.value
def __eq__(self, other):
return self.value == other.value
def __ne__(self, other):
return self.value != other.value
def __gt__(self, other):
return self.value > other.value
def __ge__(self, other):
return self.value >= other.value
class Deck:
def __init__(self, *cards):
if cards:
self.cards = list(cards)
else:
self.cards = [Card(value, suit) for suit in ['c', 'd', 'h', 's'] for value in range(1, 14)]
def __str__(self):
return str([str(card) for card in self.cards])
def __add__(self, other):
return Deck(*(self.cards + other.cards))
def __len__(self):
return len(self.cards)
def __contains__(self, other):
for card in self.cards:
if card == other and card.suit == other.suit:
return True
return False
def shuffle(self):
random.shuffle(self.cards)
def sort(self, by_value=False):
self.cards.sort()
self.cards.sort(key=lambda card: card.suit)
if by_value:
self.cards.sort()
def draw(self):
self.shuffle()
return self.cards.pop()
def deal(self, players, amount):
return [Deck(*[self.draw() for _ in range(amount)]) for _ in range(players)]
2 לייקים
orpazf
למה ב-init של Deck לעשות [cards*] במקום list(cards)?
יש לי קצת יותר בעיה עם has_card:
חפש מה אמור להיות השם של המתודה
אתה בודק את המקרה שבו הכרטיס מיוצג כמחרוזת. זה בעייתי א’ כי זה לא כרטיס גם אם זה מודפס כאילו זה כן, ממש כמו שאם יבקשו שתבדוק האם 1 ברשימה לא תבדוק האם “1” נמצא בה. ב’ אם אתה בכל זאת רוצה לבדוק, שים לב שאם מישהו מגדיר חפיסת קלפים שבה הקלפים הם diamonds, hearts וכו’ הבדיקה הזו לא תתפוס עבורם ותזרוק שגיאה של ניסיון המרה ל-int
class Deck:
def init(self, deck=None):
if deck is None:
deck = [Card(x,y) for x in SHAPES for y in VALUES]
self.deck = deck
def merge(self, other):
self.deck.extend(other.deck)
def __contains__(self, item):
return item in self.deck
def __len__(self):
return len(self.deck)
def shuffle(self):
random.shuffle(self.deck)
def drow_card(self):
return self.deck.pop()
def __str__(self):
return str([str(x) for x in self.deck])
בלי 2.6, כי אותו אממש כ-Game עם Deck ו-Hand
orpazf
א. merge שלך לא יוצרת חפיסה חדשה
ב. לדעתי הפעולה שכינית merge אמורה להיות תחת מתודת קסם (חפש איזו)
ג. אם אתה מעדיף לא לממש את 2.6 כחלק מהמחלקה, אתה מוזמן לממש אותה כפונקציה חיצונית (מאמינה שגם במשחק אתה תפריד את הפעולה הזו משאר המשחק)
ד. שולי למדי אבל השתרבבה לך טעות כתיב, זה אמור להיות draw ולא drow
כי לפעמים אני לא חושב
2.2. ההיגיון היה שניתן יהיה להעביר למתודה מחרוזת שמייצגת קלף ולא רק אובייקט של קלף ולבדוק אם הקלף שהמחרוזת מייצגת נמצא בחפיסה, אבל אכן לא חשבתי על מקרה בו הקלף יוגדר עם יותר מאות אחת, בכל מקרה עודכן.
בנוגע לפתרון שלך
בעקבות ההגדרה של __ eq__ שישווה רק את הערך המספרי של קלפים, נסיון לבדוק האם קלף בעל ערך מספרי קיים אך סמל “שונה” נמצא בחבילה יניב תוצאה שגויה. למשל: ‘13C’, ‘13 Clubs’ & ‘13akudgfkdzf’ כולם יחזירו True לבדיקה האם הם נמצאים בחבילה. זה לפחות מה שקרה לי עד שהוספתי השוואה גם של הסמל.
orpazf
אתה צודק, זה אחד החסרונות בהגדרה השרירותית שקלפים מוגדרים רק לפי הערך המספרי שלהם. זה יהיה נכון למשל עבור המשחק מלחמה ופחות עבור משחק כמו ברידג’.
המטרה שעמדה לנגד עיניי היתה להראות עוד כמה מתודות קסם, כולל גם את <, > וכו’, והם פחות תופסים עבור השוואה בין סדרות שונות - אז התפשרתי
yuval.cagan
מקבל את הפשרה. הייתי מגדיר אותה בתרגיל בכדי לחסוך כאב ראש
אבל תכלס גם את זה פתרתי בסוף, אז זה אפילו יותר מספק.