21点游戏

""
程序的功能模块设计:
洗牌:将牌进行随机排列
发牌:1、初始化发牌,一下发2张
    2、要牌,一下发一张
计分:2到10都是正常点数,J、Q、K都是10,A特殊性
胜负判断:比较电脑和玩家手中的分数谁大,并记录
是否要牌
继续还是退出
"""

# 洗牌函数,shuffle 作用是随机打乱列表
from random import shuffle
# 发牌时候用
import random

# 为什么要用numpy,nampy数组提供对应位置相加,不用自己计算
# 用在多轮游戏的分数统计
# pip install numpy
import numpy as np

# exit函数就是退出程序的意思
from sys import exit


# 初始化扑克牌
playing_cards = {
    "黑桃A": 1, "黑桃2": 2, "黑桃3": 3, "黑桃4": 4, "黑桃5": 5,
    "黑桃6": 6, "黑桃7": 7, "黑桃8": 8, "黑桃9": 9, "黑桃10": 10,
    "黑桃J": 10, "黑桃Q": 10, "黑桃K": 10,
    "红桃A": 1, "红桃2": 2, "红桃3": 3, "红桃4": 4, "红桃5": 5,
    "红桃6": 6, "红桃7": 7, "红桃8": 8, "红桃9": 9, "红桃10": 10,
    "红桃J": 10, "红桃Q": 10, "红桃K": 10,
    "方块A": 1, "方块2": 2, "方块3": 3, "方块4": 4, "方块5": 5,
    "方块6": 6, "方块7": 7, "方块8": 8, "方块9": 9, "方块10": 10,
    "方块J": 10, "方块Q": 10, "方块K": 10,
    "梅花A": 1, "梅花2": 2, "梅花3": 3, "梅花4": 4, "梅花5": 5,
    "梅花6": 6, "梅花7": 7, "梅花8": 8, "梅花9": 9, "梅花10": 10,
    "梅花J": 10, "梅花Q": 10, "梅花K": 10,
}

poker_name = list(playing_cards.keys())
# 扑克数量,几副扑克
poker_count = 1
poker_list = poker_name * poker_count

# 用于判断手中的牌是否有A,根据分数来进行选A的牌分值是0还是1
four_a = {"黑桃A", "红桃A", "方块A", "梅花A"}

# 计分器,玩家:电脑,初始分数都是0
total_score = np.array([0, 0])

# 记录游戏是第几回合
game_round = 1


"""
洗牌:重新对扑克进行随机排列
引用传值
"""
def random_card(poker_name_list):
    shuffle(poker_name_list)  # 洗牌函数

"""
计算手里的牌的分数,传进来的参数是一个list
"""
def score_count(hand_poker):
    # 声明一个变量,这个变量用来记录牌的总分数
    poker_score = 0
    # 标记:判断是否有A的标记,默认没有
    have_a = False

    # 计算手中牌的分数
    for k in hand_poker:
        poker_score += playing_cards[k]

    # 判断手中的牌是否有A,然后再根据A的规则进行分数计算
    for i in hand_poker:
        if i in four_a:
            have_a = True
            break
        else:
            continue

    if have_a == True:
        if poker_score + 10 <= 21:
            poker_score = poker_score + 10

    return poker_score

"""
判断输赢的函数
"""
def who_win(your_score, pc_score):
    if your_score > 21 and pc_score > 21:
        print("平局了")
        return np.array([0, 0])
    elif your_score > 21 and pc_score <= 21:
        print("对不起,玩家输了")
        return np.array([0, 1])
    elif your_score <= 21 and pc_score > 21:
        print("恭喜,玩家赢了")
        return np.array([1, 0])
    elif your_score <= 21 and pc_score <= 21:
        if your_score < pc_score:
            print("对不起,玩家输了")
            return np.array([0, 1])
        elif your_score > pc_score:
            print("恭喜,玩家赢了")
            return np.array([1, 0])
        else:
            print("平局了")
            return np.array([0, 0])

"""
是否继续要牌
"""
def if_get_next_poker():
    if_continue = input("是否继续要下一张牌?(Y/N)>>>>>>")
    if if_continue.upper() == "Y":
        return get_one_poker()
    elif if_continue.upper() == "N":
        print("玩家停止叫牌")
        return False
    else:
        print("输入错误,请重新输入")
        return if_get_next_poker()

"""
发牌:要牌的时候,需要从牌堆里随机抽取一张牌
"""
def get_one_poker():
    # 发一张牌,必须从牌堆中删除这张牌
    # pop 删除且返回
    return poker_list.pop(random.randint(0, len(poker_list) - 1))

"""
一轮游戏结束之后,询问玩家是继续还是结束
"""
def continue_or_quit():
    if_next_round = input("你还想玩下一局吗???(Y/N)>>>>>>")
    if if_next_round.upper() == "Y":
        if len(poker_list) < 15:
            print("剩余的扑克牌太少了,不能玩了,游戏结束")
            exit(1)
        else:
            return True
    elif if_next_round.upper() == "N":
        print("游戏结束,玩家不玩了")
        exit(1)
    else:
        print("输入错误,请再输入一次")
        continue_or_quit()

# 开局初始化牌,自动给电脑和玩家发两张牌
def start_game_init_two_poker(poker_database):
    return [poker_database.pop(random.randint(0, len(poker_database) - 1)),
            poker_database.pop(random.randint(0, len(poker_database) - 1))]

"""
每一次游戏的流程
"""
def every_round(poker_list):
    # 声明一个变量,这个变量代表着我们手里的扑克
    your_hand_poker = []
    # 再声明一个变量,这个变量代表着电脑手里的扑克
    computer_hand_poker = []

    # 一个回合的游戏,首先要自动的在牌堆中抽取两张牌
    you_init_poker = start_game_init_two_poker(poker_list)
    computer_init_poker = start_game_init_two_poker(poker_list)

    # 展示玩家所获得扑克
    print("玩家所获得的扑克牌是{}和{}".format(you_init_poker[0], you_init_poker[1]))

    print(f"电脑所获得的扑克牌是:{computer_init_poker[0]}, ?\n")

    # 荷官把牌放到了我们的手中
    your_hand_poker.extend(you_init_poker)
    computer_hand_poker.extend(computer_init_poker)

    # 计算初始牌面的分数
    score = np.array([score_count(your_hand_poker), score_count(computer_hand_poker)])

    # 首先判断一下初始化牌面分数的大小,如果有等于21点的,那么直接调用判断输赢函数
    if score[0] == 21 or score[1] == 21:
        print("初始化牌面分数有21点")
        return who_win(score[0], score[1])
    # 否则,判断自己手里的分数是否小于21点,如果小于21点,那么询问是否要下一张牌
    else:
        while score[0] <= 21:
            get_new_poker = if_get_next_poker()
            if get_new_poker != False:
                # 把新的扑克放到我自己手里
                your_hand_poker.append(get_new_poker)
                print("你手里的扑克牌是:{}".format(your_hand_poker))

                score[0] = score_count(your_hand_poker)

                # 判断分数大小
                if score[0] > 21:
                    print("你手里的扑克牌已经超过了21点")
                    print("电脑手里的扑克牌是:{}".format(computer_hand_poker))

                    return who_win(score[0], score[1])
                else:
                    continue
            # 玩家不要牌了,电脑开始叫牌
            elif get_new_poker == False:
                # 电脑的叫牌规则:只要分数比玩家分数低,就一直叫牌,直到大于等于玩家的分数才停止
                while score[1] < score[0]:
                    computer_poker = get_one_poker()
                    computer_hand_poker.append(computer_poker)

                    pc_score = score_count(computer_hand_poker)

                    score[1] = pc_score
                print("电脑手里的扑克牌是:{}".format(computer_hand_poker))
                return who_win(score[0], score[1])
            else:
                continue

# 开始玩游戏
while True:
    input("游戏开始,祝你好运,按“回车”正式开始")
    print("游戏是第{}轮".format(game_round))

    random_card(poker_list)

    # 开始游戏
    score = every_round(poker_list)

    # 计算总比分
    total_score = np.add(total_score, score)

    print("本轮技术,总比分是玩家{}:电脑{}".format(total_score[0], total_score[1]))

    game_round += 1
    continue_or_quit()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值