calthoff / self_taught

This repository contains the exercises for "The Self-Taught Programmer: The Definitive Guide to Programming Professionally."
http://theselftaughtprogrammer.io
272 stars 226 forks source link

Notes Chinese playing card war code #40

Open zhushiyang opened 2 years ago

zhushiyang commented 2 years ago
from random import shuffle

class Card:
    """
        扑克牌类
        功能:
            1.定义花色
            2.定义扑克牌
            3.比较牌的大小
    """
    # 定义花色
    suits = ["♠", "♥", "♦", "♣"]
    # 定义牌序,None用来占位
    values = [None, None, "2", "3",
              "4", "5", "6", "7",
              "8", "9", "10", "J",
              "Q", "K", "A"]

    # v:传入的牌序
    # s:传入的花色
    def __init__(self, v, s):
        """构造函数,传入牌序和花色"""
        self.value = v
        self.suit = s

    # 当类捕获到<时,会自动执行
    def __lt__(self, c2):
        """比较传入的排序和花色大小"""
        if self.value < c2.value:
            return True
        if self.value == c2.value:
            if self.suit < c2.suit:
                return True
            else:
                return False
        return False

    # 当类捕获到>时,会自动执行
    def __gt__(self, c2):
        """比较传入的排序和花色大小"""
        if self.value > c2.value:
            return True
        if self.value == c2.value:
            if self.suit > c2.suit:
                return True
            else:
                return False
        return False

    # Deck生成牌序时会调用,当类被调用时,返回花色和排序,如黑桃A
    def __repr__(self):
        v = self.suits[self.suit] + self.values[self.value]
        return v

class Deck:
    """
        牌堆类
        功能:
            1.洗牌
            2.减牌
    """

    def __init__(self):
        """构造函数:进行洗牌"""
        # 定义牌列表
        self.cards = []
        for v in range(2, 15):
            for s in range(4):
                # 调用扑克牌类,生成52张牌,添加到牌的列表中
                self.cards.append(Card(v, s))
        # 将牌列表随机打散
        shuffle(self.cards)
        print(f"牌序列表:{self.cards}")

    # 当牌被抽到后,需要从牌堆中删除
    def rm_card(self):
        if len(self.cards) == 0:
            return
        return self.cards.pop()

class Player:
    """
        玩家类
        功能:
            1.赢的次数
            2.手中的牌
            3.玩家名字
    """

    def __init__(self, name):
        """构造函数:初始化玩家"""
        # 玩家赢的次数
        self.wins = 0
        # 玩家手中剩余的牌
        self.cards = None
        # 玩家名字
        self.name = name

class Game:
    """
        游戏类
        功能:
            1.初始化游戏
            2.每次赢得比赛的玩家
            3.抽排
            4.游戏开始
    """

    def __init__(self):
        """构造函数:初始化游戏"""
        p1_name = input("请输入玩家1的名字:")
        p2_name = input("请输入玩家2的名字:")
        # 实例化Deck类,赋值给对象属性self.deck
        self.deck = Deck()
        # 初始化玩家
        self.p1 = Player(p1_name)
        self.p2 = Player(p2_name)

    def wins(self, winner):
        """每次赢得比赛的玩家"""
        w = f"玩家:{winner},赢了这一局"
        print(w)

    def drew(self, p1_name, p1_card, p2_name, p2_card):
        """玩家抽排"""
        d = f"玩家:{p1_name}抽到{p1_card},{p2_name}抽到{p2_card}"
        print(d)

    def play_game(self):
        """开始游戏"""
        # 调用self.deck.cards进行洗牌
        # cards存放的是洗好的牌
        cards = self.deck.cards
        print("--游戏开始--")
        # 每个人一张牌,所以最少剩余两张牌
        while len(cards) >= 2:
            response = input("输入q退出游戏,任意键继续!")
            if response == 'q':
                break
            # p1玩家从牌堆中抽一张牌
            p1_card = self.deck.rm_card()
            # p2玩家从牌堆中抽一张牌
            p2_card = self.deck.rm_card()
            # p1玩家的名字
            p1_name = self.p1.name
            # p2玩家的名字
            p2_name = self.p2.name
            # 开始抽排
            self.drew(p1_name, p1_card, p2_name, p2_card)
            # 比较玩家p1和玩家p2的牌大小
            if p1_card > p2_card:
                # 玩家p1赢了这局,统计玩家胜利次数的变量wins加1
                self.p1.wins += 1
                # 打印玩家p1胜利信息
                self.wins(self.p1.name)
            else:
                # 玩家p2赢了这局,统计玩家胜利次数的变量wins加1
                self.p2.wins += 1
                # 打印玩家p2胜利信息
                self.wins(self.p2.name)

        win = self.winner(self.p1, self.p2)
        print(f"游戏结束:{self.p1.name}赢了{self.p1.wins}局,{self.p2.name}赢了{self.p2.wins}局,{win}")

    def winner(self, p1, p2):
        """判断哪个玩家胜利"""
        if p1.wins > p2.wins:
            return p1.name + "赢了"
        if p1.wins < p2.wins:
            return p2.name + "赢了"
        return "平局"

game = Game()
game.play_game()