python小游戏——21点

本文介绍了如何使用Python编程创建21点游戏。包括创建扑克牌、定义发牌规则、实现人机对战的双人21点游戏,以及详细的游戏流程和规则。玩家和电脑在保证点数不超过21的前提下,尽可能使点数最大化。游戏结束时会根据点数判断胜负,并展示结果。

编写一副扑克牌和一个发牌函数,要求:
(1) 创建一副扑克牌,不包含两个Joker,其它牌面每个四张,花色可以用任意特殊符号表示;
(2) 按照21点的游戏规则,使用学过的数据类型来指定每张牌的点数,其中数字牌的点数与同数字大小,J、Q和K的点数为0.5,A的点数为1;
(3) 发牌函数每次随机发一张的牌,同时需要从发牌集合中删除已发放的牌,函数要求返回发牌的面值、点数和剩余未发的牌;并打印剩余牌数。

在编译器中,编写一个简易的人机对战的双人21点游戏。游戏规则如下:
(1) 游戏者在保证自身点数不超过21点的情况下,所持点数大于对手被判赢,超过21点判输。
(2) 游戏中,电脑可能要进行多轮发牌。首轮发牌时,双方各两张牌,且需要显示PC获得的牌中的一张的牌面(控制台打印);次轮以及以后的轮次,双方各发一张牌,PC的牌面不再显示,但需要在控制台打印自身获得的牌面和总点数;每一轮开始时要在控制台打印轮次信息。
(3) 每一轮发牌之后,人机双方均可叫停游戏或游戏可能自动终止;PC每一轮随机叫停或继续下一轮,人一方也通过控制台输入指令,叫停或者继续游戏;任何一方叫停或此时有任何一方的牌面大于21点,游戏将会被强制终止(游戏终止时需要在控制台打印该信息,并打印游戏终止的原因),并进行输赢的判定(在控制台打印判定结果,以及判定依据)。
(4) 游戏结果可能有如下几种:1)双方点数均超过21点,双方平手;2)其中一方超过21点,未超过21点的一方赢;3)双方均为超过21点,则点数较大的一方赢,若此时点数相同,则平手。
(5) 其它要求:每一轮,PC点数小于21时,随机叫停比赛。PC获得21点时,叫停比赛的概率为100%。

import random
from sys import exit


class Poke:
    # poke 类用来初始化一个牌堆
    def __init__(self):
        self.cards = [[face, number] for face in "♠♥♦♣" for number in [2, 3, 4, 5, 6, 7, 8, 9, 10, 'A', 'J', 'Q', 'K']]
        random.shuffle(self.cards)  # random.shuffle函数用来将序列进行随机排列


class Dealer:
    # Dealer类用来初始化一个发牌的人
    # 主要作用是是用来是实现取牌和发牌
    def __init__(self):
        self.cards = Poke().cards


    def give_one_card(self):
        # 给玩家发牌
        if not self.cards:  # 如果获取牌失败
            self.cards.extend(Poke().cards)
        return self.cards.pop()


class Player:
    def __init__(self, name):
        # 初始化对象属性
        self.name = name
        self.score = 0
        self.points = 0
        self.cards_in_hand = []

    def init(self):
        # 重置计数器和牌列表
        self.cards_in_hand = []
        self.points = 0

    def now_count(self):
        # 更新计算器
        point = 0

        for face, suite in self.cards_in_hand:
            if suite in ['J', 'Q', 'K']:
                suite = 0.5
            if suite == 'A':
                suite = 1
            point += suite
            self.points=point

    def is_win(self, player):
        # 未提前结束回合时判断玩家输赢
        # param:player进行比较的玩家

        s1 = self.points
        s2 = player.points
        if s1 > s2:
            print(f"玩家{self.name}点数为{s1}, 电脑{player.name}点数为{s2}, 人类玩家{self.name}赢了!")
            self.score += 1
        elif s1 == s2:
            print(f"玩家{self.name}点数为{s1}, 电脑{player.name}点数为{s2}, 平局!")
        else:
            print(f"玩家{self.name}点数为{s1}, 电脑{player.name}点数为{s2}, 电脑玩家{player.name}赢了!")
            player.score += 1

    def get(self, *cards):
        # w玩家取发的牌,并更新计算器
        # *cards 一个或多个list类型表示的牌

        for card in cards:
            self.cards_in_hand.append(card)
        self.now_count()  # 重置分数


def main(dealer: Dealer, computer: Player, human: Player):
    # 游戏控制主函数
    count = 0  # 回合数

    while True:
        count += 1
        print(f"第{count}轮比赛开始:")
        flag = False  # 设置提前结束标志
        # 新回合初始化计数器和牌
        human.init()
        computer.init()
        # 准备发牌,两张牌给human, 两张牌给电脑{computer.name}
        human.get(dealer.give_one_card(), dealer.give_one_card())
        computer.get(dealer.give_one_card(), dealer.give_one_card())
        print(f"玩家{human.name}手中的牌是{human.cards_in_hand[-2]}, {human.cards_in_hand[-1]}")
        print(f"电脑{computer.name}手中的牌是{computer.cards_in_hand[-2]}, ?")
        # 判断是否21点
        human.now_count()
        computer.now_count()
        if human.points == 21 == computer.points:
            print("玩家{human.name}和电脑{computer.name}都为21点,平局!")
        elif human.points == 21:
            print("玩家{human.name}的点数为21点,恭喜玩家{human.name}赢了!")
            human.score += 1
        elif computer.points == 21:
            print("玩家{computer.name}的点数为21点,恭喜玩家{computer.name}赢了!")
            computer.score += 1
        else:  # 开始第二轮、或者第三轮阶段
            while True:


                if_next_card = input("(人类玩家:)是否继续要牌:(y/n)")
                print("(电脑玩家:)是否继续要牌:(y/n)", end='')
                listtemp = ['y', 'n']
                random.shuffle(listtemp)  # 随机化列表
                print(listtemp[0])

                if if_next_card in ['n', 'N'] or listtemp[0]=='n':
                    human.is_win(computer)
                    break


                else:
                    human.get(dealer.give_one_card())
                    print(human.points)

                    print(f"玩家{human.name}得到一张{human.cards_in_hand[-1]}, 玩家{human.name}手中的牌是{human.cards_in_hand}")
                    # 判断玩家是否超过21点,如果是提前结束标志设置为True
                    if human.points > 21:
                        print(f"玩家{human.name}的点数{human.points}超过了21点,玩家{human.name}输了!")
                        computer.score += 1
                        flag = True  # 表示提前结束
                        human.is_win(computer)
                        break
                    #print('y')
                    computer.get(dealer.give_one_card())
                    print(computer.points)

                    # 判断电脑玩家是否超过21点,如果是提前结束标志设置为True
                    print(f"玩家{computer.name}得到一张{computer.cards_in_hand[-1]}, 玩家{computer.name}手中的牌是{computer.cards_in_hand}")
                    if computer.points > 21:
                        human.score += 1
                        flag = True  # 表示提前结束
                        human.is_win(computer)
                        break
        print("-" * 40)
        # 是否进行下一局
        if_play_again = input("是否进行下一局:(Y/N)")
        # 如果继续,先打印总比分,再重新开始
        if if_play_again in ['Y', 'y']:
            print(f"玩家{human.name},电脑{computer.name}总比分为{human.score}:{computer.score}")
            # 如果停止,打印总比分并判处胜者后退出
        elif if_play_again in ['N', 'n']:
            print(f"玩家{human.name},电脑{computer.name}总比分为{human.score}:{computer.score}")
            if human.score > computer.score:
                print(f"{human.name}胜出!")
            elif human.score < computer.score:
                print(f"{computer.name}胜出!")
            else:
                print("战况激烈,你们打平了!")
            print("游戏结束")
            exit(0)
        else:
            print("输入有误,请重新输入:")


if __name__ == '__main__':
    computer = Player('Robot')
    human = Player('Lihaoer')
    dealer = Dealer()
    main(dealer, computer, human)


























在这里插入图片描述
代码二:

import random

# creating a set of playing card
cardFace = [i for i in range(1, 11)] + ['J', 'Q', 'K']  # card face
pt = cardFace[0: 10] + [0.5] * 3  # point of each face
# ncf = [4] * 13 # the number of each face一共有四副牌
cards = cardFace * 4

# create dicts for pt and nf
ptDict = dict(zip(cardFace, pt))


#
def dealCard(cards):
    '''
    # select a card from the card set
    '''
    # get a card number
    face = random.choice(cards)#在一副牌中选取一张牌
    # remove the selected card from the card set
    cards.remove(face)#在这一副牌中删除掉这张牌

    # return a card value
    return face, cards


if __name__ == "__main__":
    ifStop = False  # stop condition是否停止
    yourPoints = 0  # your points人类玩家的点数
    pcPoints = 0  # PC's points电脑玩家的点数
    round0 = 0#第几轮
    while ifStop == False:
        round0 += 1
        print('#---------------------------------------')
        print('Round: {0}.'.format(round0))
        # get cards
        print('Dealing cards...')
        if round0 < 2:# 1 第一轮的时候
            # PC gets two cards
            face1, cards = dealCard(cards)#取出的第一张牌为face1,返回中的一副牌删除后的更新
            face2, cards = dealCard(cards)
            pcPoints += ptDict[face1] + ptDict[face2]
            print('PC got 2 new cards, one of them is {0}...'.format(random.choice([face1, face2])))
            # you get two cards
            face1, cards = dealCard(cards)
            face2, cards = dealCard(cards)
            yourPoints += ptDict[face1] + ptDict[face2]
            print('You got 2 new cards: {1} and {0}, and your total points: {2}...'.format(face1, face2, yourPoints))
        else:#第二轮开始,需要询问
            # PC gets 1 cards
            face1, cards = dealCard(cards)
            pcPoints += ptDict[face1]
            print('PC got a new card...')
            # you get 1 cards
            face1, cards = dealCard(cards)
            yourPoints += ptDict[face1]
            print('You got a new cards: {0}, and your total points: {1}...'.format(face1, yourPoints))

        print('{0} cards are left.'.format(len(cards)))

        if max([yourPoints, pcPoints]) > 21:
            # at least one of the player is broken
            ifStop = True
            broken = True
            print('At least one of the player lose due to the point greater than 21...')
        else:
            # words
            stopProb = int(min(1, (pcPoints / 21.0) ** 3) * 100)
            pcCMD = random.choice([1] * stopProb + [0] * (100 - stopProb))
            yourCMD = input('lay your card (1/0)?')

            # continue or stop
            if pcCMD == 1:
                ifStop = True
                print('PC stopped this round.')
            elif yourCMD == 1:
                ifStop = True
                print('You stopped this round.')

        # process the result of this turn
        if ifStop:
            print('You got {0} points, PC got {1} points.'.format(yourPoints, pcPoints))
            if pcPoints > 21 and yourPoints > 21:
                print('?????? Both of you and PC are broken ??????')
            elif pcPoints > 21 and yourPoints <= 21:
                print('!!!!!! PC is Broken, You Win !!!!!!')
            elif pcPoints <= 21 and yourPoints > 21:
                print('?????? You are Broken, You Lose ??????')
            elif pcPoints > yourPoints:
                print('?????? You Lose ??????')
            elif pcPoints == yourPoints:
                print('?????? TIE ??????')
            else:
                print('!!!!!! You Win !!!!!!')

    print('Game Over!')
import random

# 创建一个列表包含[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']
cardFace = [i for i in range(1, 11)] + ['J', 'Q', 'K']
print("cardFace:")
print(cardFace)
#创建它的值域[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0.5, 0.5, 0.5]
pt = cardFace[0: 10] + [0.5] * 3  # point of each face
print("pt:")
print(pt)
#创建四副牌
# ncf = [4] * 13 # the number of each face一共有四副牌
cards = cardFace * 4
print("cards:")
print(cards)


# zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
print("list(zip(cardFace, pt)):")
print(list(zip(cardFace, pt)))
ptDict = dict(zip(cardFace, pt))
print("ptDict:")
print(ptDict)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值