没错!C语言小白又开始学习python啦,现在光荣晋升一位python小白,于是我又用python重新编了一次之前的游戏,具体规则请参见我的上一篇文章。
遗憾的是,下面200行代码并没有涉及到面向对象的思想,重新编这个游戏只是为了熟悉python基础语法用来练手的。代码如下:
import random
from time import time, sleep
def input_name(): #输入每位玩家姓名(为了显示的美观性,字符长度不要超过7,1个汉字当做2个字符计算)
for i in range(4):
card_P[i] = input("请输入第{}位玩家的名字:".format(i+1))
print("\n", end = '')
sleep(0.5)
def shuffle(cards, card_num): #洗牌
random.seed(time)
for i in range(200):
swap_x = random.randint(0,card_num)
swap_y = random.randint(0,card_num)
cards[swap_x],cards[swap_y] = cards[swap_y],cards[swap_x]
def give_card(): #发牌
for i in range(56):
card[i//14].append(init_card[i])
for i in range(4): #用空字符填充每位玩家手牌至56张
card[i] += ['']*42
def count_cards(cards): #计算传入列表中最后一个非空字符位置
temp = -1 #用反向递减序号递减至非空字符位置,数字处理后返回
while cards[temp] == '':
temp -= 1
if len(cards) == abs(temp)-1: #处理列表所有元素均为空字符的情况
return 0
return len(cards)-abs(temp)+1
def print_card(): #在窗体中打印每位玩家的姓名及已经打出的手牌
global playernum
cnt = count_cards(card_P)
for i in range(cnt):
print(card_P[i]+'\t\t', end = '')
if i % playernum == playernum - 1 and i != cnt-1: #断行
print('\n')
print('\n')
def judge(): #判断是否满足奖励条件
global fruits_num, playernum
fruits_num = [0, 0, 0, 0] #表示明牌区不同种类水果牌对应水果个数
for i in range(playernum, count_cards(card_P)):
d = {'香蕉':0, '草莓':1, '樱桃':2, '柠檬':3}
if card_P[i] != '': #处理空字符索引越界情况
fruits_num[d[card_P[i][0:2]]] += int(card_P[i][2]) #水果个数累加
print("{:*^54}".format("水果个数"))
print("{:13}{:13}{:13}{:13}\n".format('香蕉'+str(fruits_num[0])+'个','草莓'+str(fruits_num[1])\
+'个','樱桃'+str(fruits_num[2])+'个','柠檬'+str(fruits_num[3])+'个')+'*'*58+"\n")
ls_back = [] #表示满足奖励条件的水果牌种类
for i in range(4):
if fruits_num[i]%5 == 0 and fruits_num[i] != 0:
ls_back.append(i)
return ls_back #返回满足奖励条件的水果牌种类
def punish(n): #罚牌
rec_player = [0, 1, 2, 3]
rec_player.remove(n) #在罚牌过程中获得牌的玩家列表
for i in rec_player:
if out_flag[i] == 0: #已出局的玩家不能获得牌
card[i][card[i].index('')] = card[n].pop(0)
card[n].append('')
def reward(n, fruit_kinds): #奖励牌
d = {0:'香蕉', 1:'草莓', 2:'樱桃', 3:'柠檬'}
i = playernum
for kind in fruit_kinds:
while i < count_cards(card_P):
if card_P[i] != '' and card_P[i][0:2] == d[kind]: #明牌区符合条件的水果牌交给第n位玩家
card[n][card[n].index('')] = card_P[i]
for j in range(15):
if j*playernum+i < 155: #将待删除的牌用下一位置的牌覆盖
card_P[j*playernum+i] = card_P[(j+1)*playernum+i]
i -= 1
i += 1
shuffle(card[n], card[n].index('')-1) #玩家得到牌之后洗牌
for i in range(4): #同时清除另一明牌区符合条件的牌(明牌区有两个:card_P,show_card,暗牌区是card)
for j in range(56):
if show_card[i][j] != '' and show_card[i][j][0:2] == d[kind]:
show_card[i][j] = ''
def del_empty_string(): #删除列表中某些元素
global playernum, counts, card_P
i = 0
while i < counts-playernum + 2: #删除card_P列表中counts位置之前连续的playernum个空字符
if card_P[i:i+playernum] == ['']*playernum:
del card_P[i:i+playernum]
card_P += ['']*playernum #此行代码使card_P变成局部变量!!!
i -= 1; counts -= playernum
i += 1
for i in range(4): #删除show_card[i]列表中非空字符之前的空字符
while show_card[i].index('') < count_cards(show_card[i]):
del show_card[i][show_card[i].index('')]
show_card[i].append('')
def ring_bell(): #按铃阶段
bell = input('请按铃:')
print("\n", end = '')
if bell[0] == '0':
return None
elif bell[0] in ['q', 'p', 'z', 'm']:
d = {'q':0, 'p':1, 'z':2, 'm':3} #将输入的按键转化为明确代表玩家身份的数字0,1,2,3
fruit_kinds = judge() #接收满足条件的水果牌(可能是空列表,没有满足条件的牌)
sleep(1)
if len(fruit_kinds) == 0: #判断是否有水果牌满足条件
if card[d[bell[0]]].index('') == 0:
print("判断错误!您手上没有牌可以惩罚。\n")
else:
print("判断错误!已惩罚。\n")
punish(d[bell[0]])
else:
reward(d[bell[0]], fruit_kinds)
del_empty_string() #执行reward之后,show_card和card_P列表中出现可以被删除的空字符
print("判断正确!已奖励。\n")
print_surplus_cards(cal_cards())
else:
print("请输入正确的按键!\n")
ring_bell()
def judge_out(): #判断是否有人出局
global playernum, counts
temp = 0 #用于指示第temp个出局标志为0的玩家(当玩家数小于4时提供正确的card_P索引)
for i in range(4): #遍历四个玩家以判断是否满足出局条件
if out_flag[i] == 0:
if card[i].index('')+count_cards(show_card[i]) == 0:
sleep(1)
print("{:=^54}".format(card_P[temp]+"出局")+"\n")
out_flag[i] += 1 #该玩家出局标志置为1
del card_P[temp:counts+1:playernum] #清除该出局玩家对应的牌
counts -= counts//playernum + 1 #明牌区索引变量随之改变
playernum -= 1
temp += 1
def print_surplus_cards(cards): #打印场上玩家剩余牌数
global playernum
sleep(1)
temp = 16*playernum-14
print('-'*(temp//2)+"剩余牌数"+'-'*(temp//2))
for i in range(len(cards)):
print("{:4}:{:>2}张\t".format(card_P[i], cards[i]), end = '')
print('\n'+'-'*(temp+8)+"\n\n\n")
def cal_cards(): #计算储存场上玩家牌数的列表
cards = []
for i in range(4):
if out_flag[i] == 0:
cards.append(card[i].index('')+show_card[i].index(''))
return cards
def judge_over(playernum): #判断游戏是否结束
cards = cal_cards()
isTrue = card[0].index('') == 0 and card[1].index('') == 0 and card[2].index('') == 0 and card[3].index('') == 0
if playernum == 2 or isTrue: #玩家只剩下两人或者所有人的牌出完时游戏结束
print_surplus_cards(cards)
for i in range(len(cards)):
if cards[i] == max(cards):
break
sleep(3)
print("{:=^54}".format("游戏结束")+"\n")
if isTrue:
print("所有人的牌出完了,", end = '')
print("{}胜利!\n".format(card_P[i]))
return 1
return 0
def play(): #游戏正式开始
print("{:=^54}".format("游戏开始")+"\n")
sleep(1)
global playernum, counts
i = 0 #用于指示出牌局数
while i < 1000:
if out_flag[i % 4] == 1: #玩家出局时跳过该玩家出牌局
i += 1
cnt1 = i % 4
cnt2 = i // 4
if input("请{}输入0出牌:".format(card_P[counts%playernum])) == '0':
sleep(1)
if card[cnt1][0] != '': #处理无牌可出情况
card[cnt1].append('')
show_card[cnt1][cnt2] = card[cnt1].pop(0) #show_card列表中将出现可以被删除的空字符
cnt_temp = counts
if out_flag[cnt1] == 0:
while card_P[cnt_temp] == '':
cnt_temp -= playernum
card_P[cnt_temp+playernum] = show_card[cnt1][cnt2]
del_empty_string() #删除上述空字符
print_card()
ring_bell()
judge_out()
sleep(1)
if judge_over(playernum):
break
else:
print("\n嘿嘿!您手上没牌了哦。\n")
sleep(1)
i += 1; counts += 1
else:
print("\n请输入正确的按键!\n")
init_card = ['香蕉1']*5+['香蕉2']*3+['香蕉3']*3+['香蕉4']*2+['香蕉5']+\
['草莓1']*5+['草莓2']*3+['草莓3']*3+['草莓4']*2+['草莓5']+\
['樱桃1']*5+['樱桃2']*3+['樱桃3']*3+['樱桃4']*2+['樱桃5']+\
['柠檬1']*5+['柠檬2']*3+['柠檬3']*3+['柠檬4']*2+['柠檬5']
card = [[], [], [], []] #card的0,1,2,3四个位置分别代表四个玩家的手牌(暗牌区)
show_card = [['']*56, ['']*56, ['']*56, ['']*56] #show_card的0,1,2,3四个位置分别代表四个玩家已经打出的手牌(明牌区)
playernum = 4 #记录场上玩家数目,当有玩家出局时更新此变量,不同函数的执行过程和结果随该变量发生改变
card_P = ['']*160 #储存用于在窗体打印的玩家姓名和打出的手牌
out_flag = [0, 0, 0, 0] #玩家是否出局的标志,0,1,2,3四个位置分别代表四个玩家
fruits_num = [0, 0, 0, 0] #记录场上不同种类水果牌对应水果数目,0,1,2,3四个位置分别代表香蕉、草莓、樱桃、柠檬
counts = 4 #用于指示card_P列表下标索引
input_name()
print("…………发牌中…………\n")
sleep(3)
shuffle(init_card, 55)
give_card()
play()