上次我基于“插入排序法”写了一个斗地主的小程序,但是功能太简单,其他地方问题也很多,比如现实中发牌是依次给每一位玩家发一张牌,直到发完。而我上次代码的意思是先给一号玩家发17张,再给其他玩家各发18张。
这次在上次的基础上,增加了叫地主\抢地主的功能,增强了下交互界面,优化了发牌方式。
代码如下:#card_game
import random
from Fight import fight
"""该程序是基于“插入排序法”扩展的斗地主游戏小程序,其核心是实现市面上斗地主游戏发牌自动排序的功能"""
def shuffle():
"""
此函数用于洗牌,牌库为列表Deck,其中3-10分别代表3-10四花色的牌
11代表‘J’牌,12代表‘Q’牌,13代表‘K’牌,99代表‘A’牌,100代表‘2’牌
233代表‘小王’牌,666代表‘大王牌’
在之后的程序中,我将用代码实现现实中的牌面,输出正确的牌
"""
Deck =[3,3,3,3, #3
4,4,4,4, #4
5,5,5,5, #5
6,6,6,6, #6
7,7,7,7, #7
8,8,8,8, #8
9,9,9,9, #9
10,10,10,10, #10
11,11,11,11, #J
12,12,12,12, #Q
13,13,13,13, #K
99,99,99,99, #A
100,100,100,100, #2
233, #小王
666] #大王
random.shuffle(Deck) #洗牌
return Deck
def sort(lst):
'''此函数是本程序的核心,插入排序法的python版本'''
for i in range(1,len(lst)):
key = lst[i]
j = i - 1
while j >= 0 and lst[j] < key:
lst[j+1] = lst[j]
j-=1
lst[j+1] = key
return lst
def replace(lst):
'''此函数是将数字替换成现实中的牌面'''
while 11 in lst:
lst[lst.index(11)] = 'J'
while 12 in lst:
lst[lst.index(12)] = 'Q'
while 13 in lst:
lst[lst.index(13)] = 'K'
while 99 in lst:
lst[lst.index(99)] = 'A'
while 100 in lst:
lst[lst.index(100)] = 2
while 233 in lst:
lst[lst.index(233)] = '小王'
while 666 in lst:
lst[lst.index(666)] = '大王'
return lst
def anti_replace(lst):
'''将牌面还原为数字'''
while 'J' in lst:
lst[lst.index('J')] = 11
while 'Q' in lst:
lst[lst.index('Q')] = 12
while 'K' in lst:
lst[lst.index('K')] = 13
while 'A' in lst:
lst[lst.index('A')] = 99
while 2 in lst:
lst[lst.index(2)] = 100
while '小王' in lst:
lst[lst.index('小王')] = 233
while '大王' in lst:
lst[lst.index('大王')] = 666
return lst
def HoleCards(lst): # 盖牌
hole_cards = replace(lst)
return hole_cards
def FirstCards(lst): # 第一个玩家的17张牌排序
first_cards = replace(sort(lst))
print('一号玩家的牌:', first_cards)
return first_cards
def SecondCards(lst): # 第二个玩家的17张牌排序
second_cards = replace(sort(lst))
print('二号玩家的牌', second_cards)
return second_cards
def ThirdCards(lst): # 第三个玩家的17张牌排序
third_cards = replace(sort(lst))
print('三号玩家的牌', third_cards)
return third_cards
def Final(lst,lst1):
landlord_cards = lst + lst1
landlord_cards = replace(sort(anti_replace(landlord_cards)))
print('盖牌',lst1)
print('地主牌:',landlord_cards)
def main():
print('-----斗地主-----\n')
Deck = shuffle() # 洗牌
hole_cards = Deck[:3] # 斗地主起始的三张盖牌
first_cards =[]
second_cards =[]
third_cards = []
while len(Deck) > 0: # 依次发牌,一次一张
first_cards.append(Deck.pop()) # 第一个玩家拿的牌
second_cards.append(Deck.pop()) # 第二个玩家拿的牌
third_cards.append(Deck.pop()) # 第三个玩家拿的牌
HoleCards(hole_cards)
first_cards = FirstCards(first_cards)
second_cards = SecondCards(second_cards)
third_cards = ThirdCards(third_cards)
try:
landlord = fight(first_cards,second_cards,third_cards)
Final(landlord,HoleCards(hole_cards))
except TypeError:
pass
if __name__ == '__main__':
main()
在主程序中,引入的Fight程序是用来实现叫地主|抢地主功能的,代码如下:#Fight
def fight(lst1,lst2,lst3):
'''抢地主函数'''
lst1,lst2,lst3 = lst1,lst2,lst3
j = 0
p1,p2,p3 = 0,0,0
length = len(input('请一号玩家输入"叫地主|不叫":'))
if length > 2:
p1 += 1
j = 1
if j < 1:
length = len(input('请二号玩家输入"叫地主|不叫":'))
if length > 2:
p2 += 1
j = 1
elif j == 1:
length = len(input('请二号玩家输入"抢地主|不抢":'))
if length > 2:
p2 += 1
j = 1
if j < 1:
length = len(input('请三号玩家输入"叫地主|不叫":'))
if length > 2:
p3 += 1
j = 1
elif j == 1:
length = len(input('请三号玩家输入"抢地主|不抢":'))
if length > 2:
p3 += 1
if p1 > p2 and p1 > p3:
print('一号玩家是地主!')
return lst1
if p2 > p1 and p2 > p3:
print('二号玩家是地主!')
return lst2
if p3 > p1 and p3 > p2:
print('三号玩家是地主!')
return lst3
if p1 == 1 and p2 == 1 and p3 ==1:
length = len(input('请一号玩家输入"抢地主|不抢":'))
if length > 2:
print('一号玩家是地主!')
return lst1
else:
print('二号玩家是地主!')
return lst2
if p1 == p2 == 1 and p3 == 0:
length = len(input('请一号玩家输入"抢地主|不抢":'))
if length > 2:
print('一号玩家是地主!')
return lst1
else:
print('二号玩家是地主!')
return lst2
if p2 == p3 == 1 and p1 == 0:
length = len(input('请二号玩家输入"抢地主|不抢":'))
if length > 2:
print('二号玩家是地主!')
return lst2
else:
print('三号玩家是地主!')
return lst3
if p1 == p3 == 1 and p2 == 0:
length = len(input('请一号玩家输入"抢地主|不抢":'))
if length > 2:
print('二号玩家是地主!')
return lst2
else:
print('三号玩家是地主!')
return lst3
if p1 == 0 and p2 == 0 and p3 == 0:
print('看来三位玩家对牌都不满意,请重新开始游戏!')
return None
程序运行结果:
-----斗地主-----
一号玩家的牌: ['大王', 2, 2, 'K', 'Q', 'J', 'J', 10, 9, 8, 8, 7, 6, 5, 5, 5, 3, 3]
二号玩家的牌 [2, 'A', 'K', 'K', 'Q', 'J', 10, 10, 9, 9, 8, 7, 6, 6, 5, 4, 4, 3]
三号玩家的牌 ['小王', 2, 'A', 'A', 'A', 'K', 'Q', 'Q', 'J', 10, 9, 8, 7, 7, 6, 4, 4, 3]
请一号玩家输入"叫地主|不叫":叫地主
请二号玩家输入"抢地主|不抢":抢地主
请三号玩家输入"抢地主|不抢":不抢
请一号玩家输入"抢地主|不抢":抢地主
一号玩家是地主!
盖牌 [7, 5, 7]
地主牌: ['大王', 2, 2, 'K', 'Q', 'J', 'J', 10, 9, 8, 8, 7, 7, 7, 6, 5, 5, 5, 5, 3, 3]
-----斗地主-----
一号玩家的牌: [2, 2, 'K', 'K', 'Q', 'Q', 10, 9, 9, 8, 8, 7, 7, 5, 4, 4, 3, 3]
二号玩家的牌 ['大王', 2, 'A', 'A', 'K', 'Q', 'Q', 'J', 'J', 'J', 8, 8, 7, 7, 6, 6, 5, 4]
三号玩家的牌 ['小王', 2, 'A', 'A', 'K', 'J', 10, 10, 10, 9, 9, 6, 6, 5, 5, 4, 3, 3]
请一号玩家输入"叫地主|不叫":不叫
请二号玩家输入"叫地主|不叫":不叫
请三号玩家输入"叫地主|不叫":不叫
看来三位玩家对牌都不满意,请重新开始游戏!
程序待优化的地方:
对牌进行排序的功能可以写成class类。
牌面可以实现不同的花色。
附上github地址:card_sort_game