2017-02-22 4 views
0

私はテキストベースのオブジェクト指向のカードゲームを作ろうとしています。 2人のプレイヤーがそれぞれ1枚のカードから1枚のカードを引き、最も強いカードを持つプレーヤーが勝ちます。このゲームには4つのクラスがあります:カード、デッキ、プレイヤー、ゲーム。私の質問は:どのように私は各プレイヤーのカードを互いに比較し、最も強いカードを決定することができます。コードに関するその他の提案はすべて歓迎します。最高のHWGについて。2枚のトランプカードに値とスーツがある場合、それらの値を比較するにはどうすればよいですか? Python3

ここ

は私のコードです:

カード

class Card(): 

    values = [None, None, 2, 3, 4, 5, 6, 7, 8, 9, 10, "Jack", "Queen", "King", 
     "Ace"] 
    suits = ["hearts", "spades", "diamond", "clubs"] 

    def __init__(self, value, suit): 
     self.value = value 
     self.suit = suit 

    def __repr__(self): 
     return str(self.values[self.value]) + " of " + str(self.suits[self.suit]) 

デッキ

from random import shuffle 
from card import Card 

class Deck(): 

    def __init__(self): 
     self.cards = [] 
     for v in range(2, 15): 
      for s in range(4): 
       self.cards.append(Card(v, s)) 
     shuffle(self.cards) 

プレーヤー

from deck import Deck 

class Player(): 

    def __init__(self, name): 
     self.name = name 
     self.card = None 
     self.wins = 0 

ゲーム

from player import Player 
from deck import Deck 
import getch 

class Game(): 

    def __init__(self): 
     player1_name = input("Player One Name: ") 
     player2_name = input("Player Two Name: ") 
     self.deck = Deck() 
     self.player1 = Player(player1_name) 
     self.player2 = Player(player2_name) 
     self.cards = self.deck.cards 

    def game_loop(self): 
     while len(self.cards) >= 2: 
      print("\nPress enter to draw") 
      getch.getch() 
      player1_card = self.cards.pop() 
      player2_card = self.cards.pop() 
+0

を私はあなたが慎重に検討すべきだと思います値は 'int'と' str'の混合であり、 'str'だけで合う...そして、実際には、実際のインスタンス自体は' Card'クラスレベルのインデックスに対応する 'ints '属性を持っています変数。何か問題は見えますか?これは 'enum'の正式なユースケースです –

+0

2つのカードを比較するために、リスト(値とスーツ)の値とスーツのインデックスを何らかの方法で使用できますか? – HWG

+0

ええ、確かに。私は面倒です。間違いなく 'enum'を使用します。あなたのコードははるかに読みやすく、素敵できちんとしたものになります。しかし、確かに、指標を使うことができます。 –

答えて

0
あなたのカードのクラスの演算子を実装することができ

__gt__(), __lt__(),など...あなたはより価値の高いカードやデッキを決定するために、最大()のような標準ライブラリ関数の数を使用することができ、さらには、ソートに使用できるより

()を使って単純に「手」を並べ替えることができます。たとえば、リスト[カード、カード、...]です。

1

ここにアプローチのスケッチがあります。これを独自のアプローチと簡単に組み合わせることができます。最も大きな変更はCardクラスです。ここで、私はCardクラスを作るためにnamedtupleを使用しましたが、あなたの現在のクラスは、単にtuple値をラップすることができます:

import enum 
from functools import total_ordering 
from collections import namedtuple 

@total_ordering 
class OrderedEnum(enum.Enum): 
    def __lt__(self, other): 
     if isinstance(other, type(self)): 
      return self.value < other.value 
     return NotImplemented 

Rank = OrderedEnum('Rank', ['one', 'two', 'three', 'four', 'five', 'six', 
        'seven', 'eight', 'nine', 'jack', 'queen','king', 'ace']) 

Suit = OrderedEnum('Suit', ['clubs', 'diamonds', 'hearts', 'spades']) 

Card = namedtuple('Card', ['rank', 'suit']) 

c1 = Card(Rank.four, Suit.clubs) 
c2 = Card(Rank.four, Suit.spades) 
c3 = Card(Rank.ace, Suit.diamonds) 

さて、アクションで:

>>> c1 
Card(rank=<Rank.four: 4>, suit=<Suit.clubs: 1>) 
>>> c2 
Card(rank=<Rank.four: 4>, suit=<Suit.spades: 4>) 
>>> c1 < c2 
True 
>>> c1 > c3 
False 

タプルソートは辞書式です!ニース!

>>> hand = [c2, c1, c3] 
>>> hand 
[Card(rank=<Rank.four: 4>, suit=<Suit.spades: 4>), Card(rank=<Rank.four: 4>, suit=<Suit.clubs: 1>), Card(rank=<Rank.ace: 13>, suit=<Suit.diamonds: 2>)] 
>>> sorted(hand) 
[Card(rank=<Rank.four: 4>, suit=<Suit.clubs: 1>), Card(rank=<Rank.four: 4>, suit=<Suit.spades: 4>), Card(rank=<Rank.ace: 13>, suit=<Suit.diamonds: 2>)] 
>>> 

注、私は単にショートカットですtotal_orderingデコレータを使用しました、そして実際に、私は簡単に手で全体のクラスを行う方が良いかもしれないと思います。 Here'sレシピ。

EDIT だから、ここで私はあなたのCardDeckクラスを実装する方法をされ、手の込んだします。 enumnamedtupleを使用すると、コードがどれだけ読みやすくなるかを確認します。アクションで今

import enum 
from functools import total_ordering 
from collections import namedtuple 
from random import shuffle 

@total_ordering 
class OrderedEnum(enum.Enum): 
    def __lt__(self, other): 
     if isinstance(other, type(self)): 
      return self.value < other.value 
     return NotImplemented 

Rank = OrderedEnum('Rank', ['one', 'two', 'three', 'four', 'five', 'six', 
        'seven', 'eight', 'nine', 'jack', 'queen','king', 'ace']) 
Suit = OrderedEnum('Suit', ['clubs', 'diamonds', 'hearts', 'spades']) 
CardValue = namedtuple('CardValue', ['rank', 'suit']) 

@total_ordering 
class Card(object): 
    def __init__(self, rank, suit): 
     self.value = CardValue(rank, suit) 
    def __repr__(self): 
     return "Card({:s}, {:s})".format(self.value.rank, self.value.suit) 
    def __lt__(self, other): 
     if isinstance(other, type(self)): 
      return self.value < other.value 
     return NotImplemented 
    def __eq__(self, other): 
     if isinstance(other, type(self)): 
      return self.value == other.value 
     return NotImplemented 

class Deck(object): 
    def __init__(self): 
     self.cards = [] 
     for rank in Rank: 
      for suit in Suit: 
       self.cards.append(Card(rank, suit)) 
     shuffle(self.cards) 

は、:

>>> deck = Deck() 
>>> c1 = deck.cards.pop() 
>>> c2 = deck.cards.pop() 
>>> c1 
Card(Rank.queen, Suit.hearts) 
>>> c2 
Card(Rank.king, Suit.clubs) 
>>> c1 == c2 
False 
>>> c1 > c2 
False 
>>> c1 < c2 
True 
>>> c1.value 
CardValue(rank=<Rank.queen: 11>, suit=<Suit.hearts: 3>) 
>>> c2.value 
CardValue(rank=<Rank.king: 12>, suit=<Suit.clubs: 1>) 

はまた、__repr__に試すべきであるとの通知を使用すると、かなりのメッセージをしたい場合は、__str__を使用し、オブジェクトを表します。 this question

0

"King"や "Ace"などの文字列を使用しないように、各カードの値をintとして保存することをお勧めします。これを行い、repr()を変更して、これらの文字列を使用して人間が判読可能なバージョンを印刷することができます。

カードのクラスは、次のようになります。カードの値はintとして、すべての時間をどのように格納されるか

class Card(object): 
    suits = ["Clubs", "Diamonds", "Hearts", "Spades"] #list of suits 
    values = [None, "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"] #list of card values 

    def __init__(self, suit= 0, value= 2): 
     """ 
     Initializes card 
     :param suit: Suit of card int value 0-3 
     :param value: Value of card int value 0-13 
     """ 
     self.suit = suit 
     self.value = value 

    def __str__(self): 
     """ 
     Returns a readable format of the card 
     """ 
     return "%s of %s" %(Card.values[self.value], 
          Card.suits[self.suit]) 

注意してください。ゲームのクラスでは、あなたが2枚のカードを比較する機能を持つことができ

、私はあなたがこれをしたいかどうかはわかりませんが、それはこのようなものになります:

def compare(card1, card2): 
    """ 
    Compares the value of two cards and returns the greater of the two 
    :param card1: A card object 
    :param card2: A second card object 
    :return: The higher value card, if tie returns 0 
    """ 
    if card1.value > card2.value: 
     return card1 
    elif card2.value == card1.value: 
     return 0 
    else: 
     return card2 
+0

ええ、今は 'card1.value> 48'が実際に評価されます。良くない。これは 'enum'の原型です。そして、あなたの 'compare'関数は、すでにクラスを持っていればあなたがやることではなく、豊富な比較演算子を実装するでしょう。 –

関連する問題