导语 我小时候能玩的东西,远没有现在这么丰富,打扑克是其中之一。
什么“三打哈”、“丰收”、“二百四”啊!不知道你们那各种方言玩法都叫啥,我这个是湖南老家的。
文章图片
我的话不经常打牌,大学的时候有手机之后就直接一个宿舍偶尔联网玩一下。
工作这几年,和朋友一起打牌的次数用一只手也能数过来。
BUT每年回湖南老家过年,少不了和亲戚一起打麻将打牌一起嗨皮一下,这是逃不掉的一个法
则了~(当然打牌的话大家不要沉迷哈,你们都懂的.....)
今天小编就给大家编写一个扑克牌的小游戏叭!希望大家喜欢哈,可以先来拿代码练练手~
所有文章完整的素材+源码都在 粉丝白嫖源码福利,请移步至CSDN社区或文末公众hao即可免费。
文章图片
正文
一、项目介绍
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)素材(图片等)
背景、扑克牌等(图片过多仅展示部分素材)
文章图片
三、代码展示 参考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
文章图片
四、效果展示 ?
文章图片
文章图片
?运行截图——
文章图片
总结 好啦好啦!这款简单的小游戏写到这里就结束了,看到这里是谁的DNA动了呢?嘻嘻嘻
小编友情提醒:小赌怡情,大赌伤身伤感情。打牌要尽兴,但切记得失心太重哦!
老规矩的撒素材完整的资料源码等关注我的都知道的啦自己去拿哈
完整的免费源码领取处:找我吖!文末公众hao可自行领取,滴滴我也可!
推荐往期文章—— 项目1.0超级玛丽
程序员自制游戏:超级玛丽100%真实版,能把你玩哭了~【附源码】
项目1.1扫雷
Pygame实战:据说这是史上最难扫雷游戏,没有之一,你们感受下......
?项目1.4水果忍者
【Pygame实战】风靡全球的切水果游戏升级版“水果忍者”上线啦,你敢来PK嘛?
项目2.0联网、人机一体五子棋游戏
Pygame实战:下五子棋吗?信不信我让你几步你也赢不了?
项目2.1宇宙激战射击游戏
【Pygame实战】飞机射击大作:宇宙激战一触即发...这款超经典的射击游戏也该拿出来重启了~
文章汇总—— 项目1.0 Python—2021 |已有文章汇总 | 持续更新,直接看这篇就够了
(更多内容+源码都在文章汇总哦!!欢迎阅读~)
文章图片
【python合集|【Pygame实战】打扑克牌嘛(赢了输了?这款打牌游戏,竟让我废寝忘食。)】
文章图片
推荐阅读
- 算法设计与分析|4 评价类算法(变异系数法笔记(附Python代码))
- Django|Django 编写第一个Django应用,第2部分
- flask|(零八)Flask有手就行——数据库迁移Flask-Migrate
- vuejs|基于Flask + Vue前后端分离的资产管理系统实现
- python|Python序列以及切片操作
- flask框架快速入门|【flask高级】从源码深入理解flask的应用上下文和请求上下文
- FDTD学习笔记|Lumerical官方案例、FDTD时域有限差分法仿真学习(十五)——y分支的逆向设计(Inverse design of y-branch)
- python|LeetCode 括号生成
- 笔记|解决ModularNotFoundError: No module named “cv2.aruco“