python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)

导语 我小时候能玩的东西,远没有现在这么丰富,打扑克是其中之一。
什么“三打哈”、“丰收”、“二百四”啊!不知道你们那各种方言玩法都叫啥,我这个是湖南老家的。
python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)
文章图片

我的话不经常打牌,大学的时候有手机之后就直接一个宿舍偶尔联网玩一下。
工作这几年,和朋友一起打牌的次数用一只手也能数过来。
BUT每年回湖南老家过年,少不了和亲戚一起打麻将打牌一起嗨皮一下,这是逃不掉的一个法
则了~(当然打牌的话大家不要沉迷哈,你们都懂的.....)
今天小编就给大家编写一个扑克牌的小游戏叭!希望大家喜欢哈,可以先来拿代码练练手~
所有文章完整的素材+源码都在 粉丝白嫖源码福利,请移步至CSDN社区或文末公众hao即可免费。

python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)
文章图片

正文 一、项目介绍 1)玩家模块规范标准
用一个长度为2的字符串表示一张牌:(D,C,H,S) + (A,2,3,4,5,6,7,8,9,0,J,Q,K) 用"jk"、"JK"分别
表示小王、大王 游戏顺序是逆时针方向 角色用一个字符串表示。
("banker","banker_opposite","banker_left","banker_right")分别表示庄家、庄家的对家、庄
家的左边、庄家的右边 不考虑甩牌,使用python进行设计 。
player模块设计:
1.1 设计函数:

de add_card_and_is_snatch(current_card): 表示玩家摸到一张牌curernt_card,并选择是否抢庄。 current_card表示一张牌(长度为2的字符串) 如果抢庄,返回相应的牌的字符串,否则返回'' 设计函数: def add_left_cards(left_cards): 只需要庄家才会用到,表示底牌是left_cards,left_cards是一个长度为2的字符串的list 需要返回玩家准备埋到底牌的牌,返回值也是一个长度为2的字符串的list 。

1.2设计函数:
def finish_one_round(current_turn_out_cards): 表示这一轮出牌结束,玩家被告知这一轮的出牌信息, current_turn_out_cards表示一个三元组(order,role,card)的list, 每一个三元组表示这一轮你出牌之前的某一个人出的牌的信息, order是一个整数,表示出牌顺序(1,2,3,4)role是一个字符串,表示角色("banker","banker_opposite","banker_left","banker_right")card是一张牌。

1.3 设计函数:
def set_main_value(main_value): 玩家被告知主面值是什么,main_value是一个字符(A,2,3,4,5,6,7,8,9,0,J,Q,K)表示主面值 。

1.4设计函数:
def set_main_color(main_color): 玩家被告知主花色是什么,main_color是一个字符(D,C,H,S)表示主花色 。

1.5 设计函数:
def player_init(): 表示现在开始一局新的游戏,并初始化相关变量 设计函数: defset_role(role): 玩家被告知自己的角色是什么,role是一个字符串("banker","banker_opposite","banker_left","banker_right") 。

1.6设计函数:
def play_out_cards(turn, current_turn_out_cards): turn表示当前是第几轮出牌,current_turn_out_cards表示一个三元组(order,role,card)的list, 每一个三元组表示这一轮你出牌之前的某一个人出的牌的信息, order是一个整数,表示出牌顺序(1,2,3,4) role是一个字符串,表示角色("banker","banker_opposite","banker_left","banker_right") card是一张牌函数需要返回决定出的一张牌 。

1.7设计函数:
def show_cards(): 需要返回当前玩家的手牌(长度为2的字符串的list) 。

2)UI说明
1.1 import UI
1.2在游戏初始化模块添加代码:
# Initialize pygame pygame.init() setting = UI.Setting() SCREEN_WIDTH, SCREEN_HEIGHT = setting.SCREEN_WIDTH, setting.SCREEN_HEIGHT x, y = 150, 60 os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y) screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("升级") background = UI.Background(screen, setting)

1.3使用接口说明:
a) initial(self): 每轮游戏初始化函数,重置卡组等功能;b) add_card(self, card, turn): 发牌阶段,turn 为目的发牌玩家的位置 0-3,card 为所发牌值;c) add_cards_over(self, inputs, outputs, main_color, master): 发牌阶段结束后调用此函数;input 为发给庄家的 6 张底牌,output 为庄家压底的 6 张牌;mian_color 为此局的主色,master 是庄家玩家的位置 0-3;d) push_cards(self, cards, turn): 打牌阶段,函数意义是 turn 玩家打出 cards,cards 为card 列表,即所有打出的牌 值;e) turn_over(self): 一轮牌结束阶段;清空四位玩家打出的所有牌;f) update_point (self, point, level1, level2): 一轮牌结束阶段,更新当前得分和级数;point为当前得分,level1 为东西位置玩 家当前的级数,level2 为南北玩家当前的级数 。

1.4传递变量说明:
a) card: (D,C,H,S) + (A,2,3,4,5,6,7,8,9,0,J,Q,K) 用"jk"、"JK"分别表示小王、大王 黑桃-spade 红桃-heart 方快-diamond 草花-club 黑桃 3 : card = ‘s3’b) turn: 整数 0-3 (0, 1, 2, 3) 等价于 ('East', 'North', 'West', 'South')

二、运行环境 1)小编使用的环境:Python3、Pycharm社区版、Pygame 模块部分自带就不一一
展示啦。
模块安装:pip install -i https://pypi.douban.com/simple/+模块名

2)素材(图片等)
背景、扑克牌等(图片过多仅展示部分素材)
python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)
文章图片


三、代码展示 参考demo: judge 为裁判模块,myPlayer 为 AI 玩家,运行 judge.py。
主程序judge.py:
# coding:utf-8import random import pygame import os import timeimport myPlayer as p1 import myPlayer as p2 import myPlayer as p3 import myPlayer as p4import UI# H S D C # Heart Spade Diamond Club # K - King0 - small king , 1 - big king class Judge(): def __init__(self): self.cards = None self.players = [] self.players.append(p1.Player('East')) self.players.append(p2.Player('North')) self.players.append(p3.Player('West')) self.players.append(p4.Player('South'))self.level = [2,2]self.master = Noneself.false = [0 , 0, 0, 0]#记录每个人犯错次数self.main_color = None self.main_num = 2self.loser = 0# 记录先犯错的一方,最后判输def covert(self, s): if s == 1 or s == 14: return 'A' elif s < 10: return str(s) elif s == 10: return '0' elif s == 11: return 'J' elif s == 12: return 'Q' elif s == 13: return 'K'# 新游戏,初始化 def new_game(self, background): self.main_color = None self.false = [0 , 0, 0, 0] self.loser = -1 self.bottom = [] self.point = 0 self.biggest = [0, 0, 0, 0] self.player_cards = [[],[],[],[]]cards = self.create_card() random.shuffle(cards) for i in range(4): self.players[i].player_init() l = ['a', 'b', 'c', 'd'] for i in range(4): self.players[i].set_role(l[i]) for y in self.players: #y.initial_new_game() y.set_main_value(self.covert(self.main_num)) # 发牌 turn = 0 for i in range(48): x = self.players[turn].add_card_and_is_snatch(cards[i]) self.player_cards[turn].append(cards[i]) if x != '' and x[1] == self.covert(self.main_num) and self.main_color == None: self.main_color = x[0] if self.master == None:self.master = turn for y in self.players: y.set_main_color(self.main_color) elif x == '': None else: self.false[turn] += 1 if self.loser == -1: self.loser = turnbackground.add_card(cards[i], turn)turn += 1 turn %= 4 if self.main_color == None: col = ['H', 'C', 'D', 'S'] self.main_color = random.choice(col) for y in self.players: y.set_main_color(self.main_color) if self.master == None: self.master = random.randint(0, 3) self.bottom = self.players[self.master].add_left_cards(cards[48:]) for x in cards[48:]: self.player_cards[self.master].append(x)if len(self.bottom) != 6: self.false[self.master] += 1 if self.loser == -1: self.loser = self.master else: for x in self.bottom: if x in self.player_cards[self.master]: self.player_cards[self.master].remove(x) else: if self.loser == -1: self.loser = self.masterbackground.add_cards_over(cards[48:], self.bottom, self.main_color, self.master)'''生成一副牌''' def create_card(self): colors = ['H', 'S', 'D', 'C'] nums = 'A234567890JQK' cards = [] for color in colors: for i in range(13): c = color + nums[i] cards.append(c) cards.append('jk') cards.append('JK')return cards# 判断玩家手里是否有该花色的牌,y表示该轮是否要出主牌 def find_color(self,p_cards, this_color, y): for x in p_cards: if y == True: if x == this_color or x == 'jk' or x=='JK' or x ==self.covert(self.main_num): return True else: if x == this_color: return True return False# a先出, 判断b的数字是否大于a def is_big(self,b, a): num_order = ['A', 'K', 'Q', 'J', '0', '9','8','7','6','5','4','3','2'] for x in num_order: if x == a: return False if x == b: return True# 判断a 是否大于b,a先出 def is_bigger(self,a , b, this_color): if a == 'JK': return True if a == 'jk': if b == 'JK': return False else : return True if a[1] == self.main_num: if b == 'jk' or b=='JK' or b[0]==self.main_color and b[1]==self.covert(self.main_num): return False else: return True if a[0] == self.main_color: if b =='jk' or b=='JK' or b[1]==self.covert(self.main_num) or b[0]==self.main_color and self.is_big(b[1],a[1]): return False else: return True if a[0] == this_color: if b =='jk' or b=='JK' or b[1]==self.covert(self.main_num) or b[0]==self.main_color or b[0]==this_color and self.is_big(b[1],a[1]): return False else: return Trueif b =='jk' or b=='JK' or b[1]==self.covert(self.main_num) or b[0]==self.main_color or b[0]==this_color or self.is_big(b[1],a[1]): return False else: return Truedef add_points(self, cards): for x in cards: if x[1] == '5': self.point += 5 elif x[1] == '0' or x[1] == 'K': self.point += 10# 判断一轮中最大的牌是谁出的,是否加分 def get_max_index_and_add_points(self, cards, turn, this_color): index = 0 max_card = cards[0] for i in range(1,4): if not self.is_bigger(max_card, cards[i], this_color): index = i max_card = cards[i]if index % 2 != self.master % 2: self.add_points(cards)return (turn + index) % 4def is_a_card(self, s): if s == 'jk' or s == 'JK': return True if s[0] in ['H', 'S', 'D', 'C'] and s[1] in ['A', 'K', 'Q', 'J', '0', '9','8','7','6','5','4','3','2']: return True else: return False# 出牌到结束 def run_game(self, background): turn = self.master for i in range(12): UI.check_events() this_turn_cards = [] first_card = self.players[turn].play_out_cards(0 , this_turn_cards) this_turn_cards.append(first_card)if first_card in self.player_cards[turn]: self.player_cards[turn].remove(first_card) else: if self.loser == -1: self.loser = turnbackground.push_cards([first_card], turn)turn += 1 turn %= 4if not self.is_a_card(first_card): print('Please input a card') self.false[turn] += 1 if first_card == 'jk' or first_card == 'JK' or first_card[0]==self.main_color or first_card[1]==self.covert(self.main_num): this_color = self.main_color else: this_color = first_card[0]for j in range(1, 4): a_cards = self.players[turn].play_out_cards(j, this_turn_cards) if a_cards in self.player_cards[turn]: self.player_cards[turn].remove(a_cards) else: if self.loser == -1: self.loser = turn this_turn_cards.append(a_cards) #p_cards = self.players[turn].show_cards() p_cards = self.player_cards[turn] #print('a_cards = ', a_cards)############### if a_cards[0] == this_color: None elif this_color == self.main_color: if a_cards == 'jk' or a_cards == 'JK' or a_cards[1]==self.covert(self.main_num): None elif not self.find_color(p_cards, this_color, True): None else: self.false[turn] += 1 if self.loser == -1: self.loser = turn else: if self.find_color(p_cards, this_color, False): self.false[turn] += 1 if self.loser == -1: self.loser = turnbackground.push_cards([a_cards], turn)turn += 1 turn %= 4# 告诉所有玩家本轮出的牌 for i in range(4): self.players[i].finish_one_round(this_turn_cards, (i + turn ) % 4 )max_index = self.get_max_index_and_add_points(this_turn_cards, turn, this_color) turn = max_index self.biggest[max_index] += 1background.update_point(self.point, self.level[0], self.level[1]) background.turn_over()# 底牌是否得分 if turn % 2 != self.master % 2: self.add_points(self.bottom)if self.loser % 2 == self.master: self.main_num = self.level[(self.master + 1) % 2] self.master = (self.master + 1) % 2 elif self.loser % 2 != self.master and self.loser != -1: self.level[self.master % 2] += 1 self.main_num = self.level[self.master % 2] if self.master == self.master % 2: self.master += 2 else: self.master %= 2 elif self.point < 40: self.level[self.master % 2] += 1 self.main_num = self.level[self.master % 2] if self.master == self.master % 2: self.master += 2 else: self.master %= 2 else: self.main_num = self.level[(self.master + 1) % 2] self.master = (self.master + 1) % 2 # print(self.biggest)if __name__ == '__main__': # Initialize pygame pygame.init() setting = UI.Setting() SCREEN_WIDTH, SCREEN_HEIGHT = setting.SCREEN_WIDTH, setting.SCREEN_HEIGHT x, y = 150, 60 os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y) screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("升级") background = UI.Background(screen, setting) judge = Judge() #judge.level = [12,13] while True:time.sleep(0.5) judge.new_game(background) judge.run_game(background) background.initial()if judge.level[0] == 13 or judge.level[1] == 13: print(judge.level) if judge.level[0] > judge.level[1]: print('East and West WIN') else: print('South and North WIN') break

python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)
文章图片
四、效果展示 ?python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)
文章图片
python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)
文章图片
?运行截图—— python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)
文章图片


总结 好啦好啦!这款简单的小游戏写到这里就结束了,看到这里是谁的DNA动了呢?嘻嘻嘻
小编友情提醒:小赌怡情,大赌伤身伤感情。打牌要尽兴,但切记得失心太重哦!
老规矩的撒素材完整的资料源码等关注我的都知道的啦自己去拿哈
完整的免费源码领取处:找我吖!文末公众hao可自行领取,滴滴我也可!
推荐往期文章—— 项目1.0超级玛丽
程序员自制游戏:超级玛丽100%真实版,能把你玩哭了~【附源码】
项目1.1扫雷
Pygame实战:据说这是史上最难扫雷游戏,没有之一,你们感受下......
?项目1.4水果忍者
【Pygame实战】风靡全球的切水果游戏升级版“水果忍者”上线啦,你敢来PK嘛?
项目2.0联网、人机一体五子棋游戏
Pygame实战:下五子棋吗?信不信我让你几步你也赢不了?
项目2.1宇宙激战射击游戏
【Pygame实战】飞机射击大作:宇宙激战一触即发...这款超经典的射击游戏也该拿出来重启了~
文章汇总—— 项目1.0 Python—2021 |已有文章汇总 | 持续更新,直接看这篇就够了
(更多内容+源码都在文章汇总哦!!欢迎阅读~)
python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)
文章图片

【python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)】python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)
文章图片

    推荐阅读