# coding=gbk
"""
程序功能:

洗牌:将牌进行随机排列
发牌:1、初始化发牌,一下发两张
     2、要牌,一次发一张
计分:2到10正常,JQK都是10分,考虑A的特殊性
胜负判断:比较电脑和玩家的分数大小,并记录
是否要牌
继续还是退出

"""
# 洗牌函数  shuffle作用是随机打乱列表
from random import shuffle

import random

# numpy数组提供对应位置相加,不用自己计算
import numpy as np

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
poker_A = {"黑桃A", "红桃A", "方块A", "梅花A"}

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

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

'''
洗牌:重新对扑克牌进行随机排列
'''
def random_card():
    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 poker_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(poker_list)
    elif if_continue.upper() == "N":
        print("玩家停止要牌")
        return False
    else:
        print("输入错误,请重新输入!")
        return if_get_next_poker()     # 递归调用
    
    
"""
发牌:要牌的时候,需要从牌堆里随机抽取一张牌
"""
def get_one_poker(poker_list):
    # 发一张牌,必须在牌堆中删除这张牌
    # pop函数:在列表中删除并返回这个元素
    # random.randint(0, len(poker_list)-1)  (从0开始到牌的列表长度-1)代表52张牌,再随机抽取一张
    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("输入错误,重新输入:")
        return 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)
    
    # 展示各自刚拿到的牌  {}z这个符号一定要有,否则不显示format函数中的值
    print("玩家获得的牌:{}、{}".format(you_init_poker[0], you_init_poker[1]))
    print(f"电脑获得的牌:{computer_init_poker[0]},?\n")    # 与上面相同,注意最前方的 f 字母

    # 发出来的牌交到玩家和电脑的手里
    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)])
    
    # 判断初始牌面的分数大小
    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:
                pass
        # 玩家不要牌了,电脑开始要牌
        elif get_new_poker == False:
            # 电脑要牌规则:只要分数比玩家分数低就一直要,直到大于等于玩家的分数才停止
            # while score[0] > score[1]:
            #     computer_poker = get_one_poker(poker_list)
            #     computer_hand_poker.append(computer_poker)
            #
            #     score[1] = score_count(computer_hand_poker)
            #     print("电脑手中的牌是:{}".format(computer_hand_poker))
            #     return who_win(score[0], score[1])
            # 添加一个阈值判断,即当电脑自己的牌大于某个值时就不再要牌
            if score[1] <= 15 and score[0] > score[1]:
                computer_poker = get_one_poker(poker_list)
                computer_hand_poker.append(computer_poker)

                score[1] = score_count(computer_hand_poker)
                print("电脑手中的牌是:{}".format(computer_hand_poker))
                return who_win(score[0], score[1])
        else:
            pass

# 开始玩游戏
while True:
    input("游戏开始(按ENTER进入游戏):")
    print("这是第{}轮游戏".format(game_round))
    # 洗牌
    random_card()
    # 开始游戏
    score = every_round(poker_list)
    
    # 计算总比分
    total_score = np.add(total_score, score)
    
    print("本轮结束,总比分是玩家{}:电脑{}".format(total_score[0], total_score[1]))
    print("**************************************************************************")
    game_round += 1
    continue_or_quit()