作业需求:
1、生成一副扑克牌(自己设计扑克牌的结构,小王和大王可以分别用14、15表示 )
2、3个玩家(玩家也可以自己定义)
user_list = ["alex","武沛齐","李路飞"]
3、发牌规则
默认先给用户发一张牌,其中 J、Q、K、小王、大王代表的值为0.5,其他就是则就是当前的牌面值。
用户根据自己的情况判断是否继续要牌。
要,则再给他发一张。(可以一直要牌,但是如果自己手中的牌总和超过11点,你的牌就爆掉了(牌面变成0))
不要,则开始给下个玩家发牌。(没有牌则则牌面默认是0)
如果用户手中的所有牌相加大于11,则表示爆了,此人的分数为0,并且自动开始给下个人发牌。
4、最终计算并获得每个玩家的分值,例如:
result = {
"alex":8,
"武沛齐":9,
"李路飞":0
}
import random
import os
'''
思路:
1、初始化卡牌和玩家
2、进入回合循环
2.1 是否抽牌,不抽:当前玩家游戏状态=0,为下一个玩家发牌,若此时场内玩家等于1结束游戏,打印结果,否则进入2.2
抽:直接进入2.2
2.2 有无剩余牌,有:进入2.3
没有:结束游戏,打印结果
2.3 当前玩家点数是否>11,是:当前玩家游戏状态=0,若此时场内玩家等于1结束游戏,打印结果,否则重新进入2.1,开始下一回合
- 扑克牌用 字典 存在全局变量 deck 中,key 是牌 ,value 是点数
- 取牌:random_card = random.choice(list(deck.keys()))
- 取值:card_value = deck[random_card]
- 玩家信息用列表嵌套字典的方式储存
- 结构:[ {f'player {i}昵称': player_name, f'player {i}手牌': {}, f'player {i}得分':0.0 ,f'player {i}游戏状态': '1'},
{f'player {i+1}昵称': player_name, f'player {i+1}手牌': {}, f'player {i+1}得分':0.0 ,f'player {i}游戏状态': '1'} ]
- 取玩家手牌:current_player_deck = current_player_info[f'player {current_player_index + 1}手牌'] # 回合所在玩家手牌
current_player_deck 是一个玩家的所有信息:
{f'player {i}昵称': player_name, f'player {i}手牌': {}, f'player {i}得分':0.0 ,f'player {i}游戏状态': '1'}
'''
# 定义全局变量 DECK
global deck
# 创建一副扑克牌,并为所有牌面赋值
def create_pokers():
'''
输入:空
返回:一副用字典装的牌,他的值是对应的点数
思路:
- 创建一个字典,存放牌和对应的值
- 向牌中添加内容采用 deck['卡牌名称'] = 对应点数 的方式
'''
deck = {}
# 定义扑克牌的类型和点数
types = ['♣', '♥', '♦', '♠']
ranks = ['A','2', '3', '4', '5', '6', '7', '8', '9', '10']
# 特殊牌面
special_cards = ['J', 'Q', 'K']
Joker = ['Joker1', 'Joker2']
# 使用嵌套循环来创建每张牌并将其添加到字典中
for card_type in types:
# 第一个循环,为普通牌面赋值
for rank in ranks:
# 用'f'格式化字符串输出
card_name = f'{card_type}{rank}'
# 特殊情况,type = A
if rank == 'A':
card_value = 1.0
deck[card_name] = card_value # 将牌添加到字典,包括牌的属性和值
else:
card_value = float(rank)
deck[card_name] = card_value # 将牌添加到字典,包括牌的属性和值
# 第二个循环,为J、Q、K赋值
for rank in special_cards:
card_name = f'{card_type}{rank}' # 创建牌的名称
card_value = 0.5
deck[card_name] = card_value # 将牌添加到字典,包括牌的属性和值
# 为大小王赋值
for Joker in Joker:
card_name = f'{Joker}'
card_value = 0.5
deck[card_name] = card_value
return deck
def set_players_num(): # 初始化游戏玩家
'''
输入:空
返回:玩家列表
- 创建一个列表,用来存放所有玩家信息
[
{
f'player {i}昵称': player_name,
f'player {i}手牌': {},
f'player {i}得分':0.0 ,
f'player {i}游戏状态': '1'
},{
f'player {i+1}昵称': player_name,
f'player {i+1}手牌': {},
f'player {i+1}得分':0.0 ,
f'player {i+1}游戏状态': '1'
},
...
]
- 添加玩家: players.append(player_information)
- 其中 players 是玩家列表,player_information是单个玩家信息的字典,结构为:
{
f'player {i}昵称': player_name,
f'player {i}手牌': {},
f'player {i}得分':0.0 ,
f'player {i}游戏状态': '1'
}
- 取玩家信息:
- 取第 n 个玩家昵称: player1_name = players[n-1][f'player {n-1}昵称']
...
'''
while True:
players_num = input('请输入玩家人数:')
players_num = players_num.strip()
if players_num.isdecimal():
players_num = int(players_num)
if int(players_num) < 2:
print('\n至少需要两名玩家!,重新输入\n')
else:
break
else:
print('请输入整数')
players = [] # 创建一个空列表来保存玩家信息
for i in range(1, players_num + 1):
while True:
player_name = input(f'\n玩家{i}/{players_num}的昵称是:')
if player_name.strip():
player_information = {f'player {i}昵称': player_name, f'player {i}手牌': {}, f'player {i}得分': 0.0,
f'player {i}游戏状态': '1'} # 创建包含玩家信息的字典
players.append(player_information)
break
else:
print('请重新输入')
# 返回包含玩家信息的列表
return players
def get_poker(deck, player_deck): # 发牌
"""
deck:牌库
player_deck:玩家手牌库
"""
# 随机给某个玩家抽牌
if deck: # 检查deck是否为空
random_card = random.choice(list(deck.keys()))
card_value = deck[random_card]
print(f'\n抽到了一张:{random_card}')
del deck[random_card] # 从牌库中删除抽到的牌
player_deck[random_card] = card_value # 将抽到的牌添加到玩家的牌堆
return True
else:
print("扑克牌已经抽完了!游戏结束!")
input("\n按下任意键继续...")
return False
def calculate_total_value(player_deck): # 计算玩家手牌总点数
'''
player_deck:玩家手牌库
'''
total_value = sum(player_deck.values())
return total_value
def print_player_decks(current_player_info, index): # 打印玩家手牌及得分
'''
current_player_info:当前玩家的所有信息
index:回合索引(从0开始)
'''
print(f'你的手牌:', end=' ')
player_deck = current_player_info[f'player {index + 1}手牌']
card_list_temp = []
for card, value in player_deck.items():
card_list_temp.append(card)
output_string = ' '.join(card_list_temp)
print(output_string.ljust(30, ' '), end='') # 打印格式化后的玩家手牌
total_value = calculate_total_value(player_deck) # 统计手牌的value和
formatted_total_value = f'{total_value:.1f}'
print(formatted_total_value.rjust(4, ' '), end='')
print('点')
temp = float(formatted_total_value)
current_player_info[f'player {index + 1}得分'] = temp
def print_allplayer_decks(players_list): # 打印所有玩家手牌及得分,找到赢家
'''
players_list:所有玩家的信息
'''
print('\n\n')
list_all_players_score = []
winning_players_names = [] # 用于存储共同获胜的玩家昵称
for player, index in zip(players_list, range(1, len(players_list) + 1)):
player_name = next(iter(player.values())) # 获取玩家的昵称
player_deck = player[f'player {index}手牌'] # 获取玩家的手牌
print(f'{player_name}的手牌:', end=' ')
card_list_temp = []
for card, value in player_deck.items():
card_list_temp.append(card)
output_string = ' '.join(card_list_temp) # 将玩家手牌格式化为字符串
print(output_string.ljust(20, ' '), end='') # 打印格式化后的玩家手牌
total_value = player[f'player {index}得分'] # 计算玩家总得分
if total_value > 11:
total_value = 0.0
list_all_players_score.append(total_value) # 将玩家得分添加到列表中
formatted_total_value = f'{total_value:.1f}' # 格式化成一位小数的字符串
print(formatted_total_value.rjust(4, ' '), end='') # 打印玩家得分
print('点')
max_score = max(list_all_players_score)
# 找到最大分值对应的玩家
winning_players = [index for index, score in enumerate(
list_all_players_score, start=1) if score == max_score]
# 打印共同获胜的玩家昵称
for index in winning_players:
winning_player_name = next(
iter(players_list[index - 1].values())) # 减去1以匹配列表索引
winning_players_names.append(winning_player_name)
if len(winning_players) == 1:
print(f'\n玩家 {winning_players_names[0]} 获胜!,手牌共计{max_score}点')
else:
print(f'平局! 共同获胜的玩家: {", ".join(winning_players_names)}')
def count_active_players(players_list): # 获得游戏状态=1的玩家数
'''
players_list:所有玩家的信息
'''
count = 0
for player_info, index in zip(players_list, range(1, len(players_list) + 1)):
if player_info[f'player {index}游戏状态'] == '1':
count += 1
return count
def Round_action(players_list, current_player_index_round, game_continue): # 上一个玩家选择不要牌后直接为下一个玩家发牌
'''
players_list:所有玩家的信息
current_player_index_round:当前回合的索引(start:0)
game_continue:游戏状态标识符(=0游戏结束)
'''
# 直接复制主函数里的代码
current_player_info_round = players_list[current_player_index_round]
current_player_name_round = current_player_info_round[
f'player {current_player_index_round + 1}昵称']
print(f'\n轮到玩家{current_player_name_round}')
if_remain_poker = get_poker(
deck, current_player_info_round[f'player {current_player_index_round + 1}手牌'])
print_player_decks(current_player_info_round, current_player_index_round)
# 判断能否抽到(否表示没牌了)
if if_remain_poker == True: # 有剩余
# 判断该玩家当前分数
current_player_score = current_player_info_round[
f'player {current_player_index_round + 1}得分']
# >11
if current_player_score > 11.0:
# 该玩家游戏状态=0,current_player_info[f'player {current_player_index+1}得分']='0''
current_player_info_round[f'player {current_player_index_round + 1}游戏状态'] = '0'
current_player_info_round[f'player {current_player_index_round + 1}得分'] = 0.0
print('你的点数超过11了,最终得分为0!')
input("\n按下任意键继续...")
count_players_equal_1 = count_active_players(players_list)
# 判断游戏状态=1的玩家数,是否>=2
if count_players_equal_1 >= 2:
# 是,pass
pass
# 否,game_continue=0,游戏结束
else:
game_continue = 0
# <11 pass,继续游戏
else:
input("\n按下任意键继续...")
pass
return game_continue
if __name__ == '__main__':
os.system('cls')
print('\n\n-------------《扑克十一点》-------------\n\n')
deck = create_pokers() # 初始化扑克牌
players_list = set_players_num() # 初始化玩家
num_players = len(players_list) # 获得玩家数量
current_player_index = 0 # 当前玩家的索引
game_continue = 1 # 标识符,等于1游戏可以继续
input('\n按下任意键开始游戏...')
# 开始游戏,清除终端中的文字
os.system('cls')
# 开始抽卡循环 game_continue == 0时break
while True:
current_player_info = players_list[current_player_index] # 回合所在玩家全部信息
# 回合所在玩家昵称
current_player_name = current_player_info[f'player {current_player_index + 1}昵称']
# 回合所在玩家手牌
current_player_deck = current_player_info[f'player {current_player_index + 1}手牌']
# 判断游戏状态,=1可以参与本回合
# 状态=1可以参与本回合
if current_player_info[f'player {current_player_index + 1}游戏状态'] == '1':
# TODO 这里放玩家回合内的行动:
# 是否抽卡
print(f'\n\n轮到玩家:{current_player_name}\n\n')
print_player_decks(current_player_info, current_player_index)
Draw_or_not = input('是否继续抽牌?(输入1:是 其他:否) ')
# (是否抽卡)是,抽一张
if Draw_or_not == '1':
if_remain_poker = get_poker(deck, current_player_deck)
print_player_decks(current_player_info, current_player_index)
# 判断能否抽到(否表示没牌了)
if if_remain_poker == True: # (判断能否抽到)有剩余
# 判断该玩家当前分数
current_player_score = current_player_info[f'player {current_player_index + 1}得分']
# >11
if current_player_score > 11.0: # (是否超11)是
# 该玩家游戏状态=0,current_player_info[f'player {current_player_index+1}得分']='0''
current_player_info[f'player {current_player_index + 1}游戏状态'] = '0'
tempscore = float(0)
current_player_info[f'player {current_player_index + 1}得分'] = tempscore
print('你的点数超过11了,最终得分为0!')
input("\n按下任意键继续...")
# 判断游戏状态=1的玩家数,是否 <= 1
count_players_equal_1 = count_active_players(
players_list)
if count_players_equal_1 <= 1: # <= 1,结束游戏
game_continue = 0
else: # (是否超11)否
input("\n按下任意键继续...")
else: # (判断能否抽到) 无剩余,pass,game_continue=0,游戏结束
print('游戏结束!')
game_continue = 0
else: # (是否抽卡)否,不抽,为下一位玩家发牌
# 该玩家游戏状态=0
print('玩家选择不再抽牌!')
# 当前玩家踢出游戏
current_player_info[f'player {current_player_index + 1}游戏状态'] = '0'
input("\n按下任意键继续...")
# 下一位玩家发牌
os.system('cls')
print('\n\n上回合玩家选择不抽牌,立即为下一位玩家发牌!')
current_player_index = (
current_player_index + 1) % num_players # 索引+1
game_continue = Round_action(
players_list, current_player_index, game_continue) # 不询问直接发牌
# 判断游戏状态=1的玩家数,是否>=2
count_players_equal_1 = count_active_players(players_list)
if count_players_equal_1 <= 1: # 是,pass
print('游戏结束!')
game_continue = 0
# 游戏状态=0,该玩家本轮不行动
else:
print(f'\n\n本轮玩家{current_player_name}无法行动')
print_player_decks(current_player_info, current_player_index)
input("\n按下任意键继续...")
pass
# 增加索引+1,进行下一个玩家回合
current_player_index = (current_player_index + 1) % num_players
# 清除终端中的文字
os.system('cls')
# 如果游戏结束,退出循环
if game_continue == 0:
# 打印游戏结果
print_allplayer_decks(players_list)
input("\n按下任意键继续...")
break