腾讯欢乐斗地主辅助程序V1.0,PYTHON实现
来源:互联网 发布:mssql2005数据库 编辑:程序博客网 时间:2024/04/29 01:22
闲来无事写了这个玩意.深感PYTHON好用.蛋疼的是,实践效果和想象的有些差距.因为每手牌都要敲一次命令.加上还要分析,时间比较紧.
目测只有那种紧张刺激的炸弹局才有必要如此蛋疼地用吧.
# ===斗地主出牌记录及查询程序V1.0===# 作者:项楠(280145668@qq.com)# 版权所有,翻录不得究:-)# =====记录命令=====# 1表示下家,0表示上家,i表示本人(i可省略).例如:133表示下家出对3,i4447或4447表示本人出三带一.# 各种出牌的表示规则:# 单:d(大王),x(小王),2,a,k,Q,8,7,6,s(10),S(10)# 对:kk,99# 王炸:DX,dx,xd,# 三个:222,999# 炸弹:9999,3333,# 四带二:999945,333344,# 四带两对:99994455,33334477,# =====以下类型支持简写形式=====# 三带一:4449,49,3336,36, 重复数必须写在最前面# 三带一对:44499,499,33366,366# 飞机:66677789,6789,6667778899,6789-, "-"表示带对# 顺子:76543,3-7,7-3,AKQJS98,A-8,8-A, 可用"-"替代中间的数字# 连对:776655,7--5,5--7,AAKKQQJJSS,a--s,S--a, 可用"--"替代中间的数字# =====其他命令(均以"="开头)=====# 显示当前所有牌的剩余数量表:=# 显示某牌X的剩余数量(包括本人):=X# 显示上家(屏幕左方玩家)出牌历史:=0# 显示下家(屏幕下方玩家)出牌历史:=1# 显示本人出牌历史:=i# 撤销上次的出牌记录:==# =====完整对应表=====# D -> 大王# X -> 小王# 2 -> 2# A -> A# K -> K# Q -> Q# J -> J# S -> 10# 9 -> 9# 8 -> 8# 7 -> 7# 6 -> 6# 5 -> 5# 4 -> 4# 3 -> 3import reimport datetimeQUERY = '='LEFT_PLAYER = '0'RIGHT_PLAYER = '1'MYSELF = 'i'PLAYER_DICT = {LEFT_PLAYER: '上家', RIGHT_PLAYER: '下家', MYSELF: '本人', }PLAYER = ''.join(PLAYER_DICT)JOKERS = 'DX' # 大小王SPECIAL = '2'SEQUENCE = 'AKQJS9876543' # 顺子,连对,飞机3位重复数ALL = JOKERS + SPECIAL + SEQUENCE # 所有数字BOMB = SPECIAL + SEQUENCE # 炸弹,对子,三REG_DICT = {'jk1': JOKERS[0], 'jk2': JOKERS[1], 'sq': SEQUENCE, 'al': ALL, 'bb': BOMB, }CARD_DICT = {}for i, k in enumerate(ALL): if i < 2: CARD_DICT[k] = 1 # 大小王各一张 else: CARD_DICT[k] = 4 # 其他四张_RAW_REGEX = ( #(正则表达式,出牌类型) (r'^[%(al)s]$' % REG_DICT, '单'), (r'^([%(bb)s])\1$' % REG_DICT, '对'), (r'^%(jk1)s%(jk2)s$|^%(jk2)s%(jk1)s$' % REG_DICT, '王炸'), (r'^([%(bb)s])\1\1$' % REG_DICT, '三个'), (r'^([%(bb)s])\1\1\1$' % REG_DICT, '炸弹'), (r'^([%(bb)s])\1\1\1[%(al)s]{2}$' % REG_DICT, '四带二'), (r'^([%(bb)s])\1\1\1([%(al)s])\2([%(al)s])\3$' % REG_DICT, '四带两对'), (r'^([%(bb)s])\1\1[%(al)s]$' % REG_DICT, '三带一'), (r'^([%(bb)s])\1\1([%(al)s])\2$' % REG_DICT, '三带一对'), (r'^([%(sq)s])\1\1([%(sq)s])\2\2[%(al)s]{2}$' % REG_DICT, '飞机带单'), (r'^([%(sq)s])\1\1([%(sq)s])\2\2(?:([%(al)s])\3){2}$' % REG_DICT, '飞机带对'), (r'^(?:([%(sq)s])\1){3,10}$' % REG_DICT, '连对'), (r'^[%(sq)s]{5,12}$' % REG_DICT, '顺子'), #(r'^$'%REG_DICT,''),)RAW_REGEX = [re.compile(pat) for pat, name in _RAW_REGEX]def _sequence(cards, num): a = SEQUENCE.index(cards[0]) b = SEQUENCE.index(cards[-1]) s = min(a, b) t = max(a, b) raw_cards = '' for i, card in enumerate(SEQUENCE): if s <= i <= t: raw_cards += card * num return raw_cardsdef double_sequence(cards): return _sequence(cards, 2)def single_sequence(cards): return _sequence(cards, 1)_ALIAS_REGEX = ( #(正则表达式,出牌类型,解释函数) (r'^[%(bb)s][%(al)s]$' % REG_DICT, '三带一', lambda c: c[0] * 3 + c[1:]), (r'^[%(bb)s]([%(al)s])\1$' % REG_DICT, '三带一对', lambda c: c[0] * 3 + c[1:]), (r'^[%(bb)s]{2}[%(al)s]{2}$' % REG_DICT, '飞机带单', lambda c: c[0] * 3 + c[1] * 3 + c[2:]), (r'^[%(bb)s]{2}[%(al)s]{2}-$' % REG_DICT, '飞机带对', lambda c: c[0] * 3 + c[1] * 3 + c[2] * 2 + c[3] * 2), (r'^[%(sq)s]--[%(sq)s]$' % REG_DICT, '连对', double_sequence), (r'^[%(sq)s]-[%(sq)s]$' % REG_DICT, '顺子', single_sequence), #(r'^$'%REG_DICT,''),)ALIAS_REGEX = [re.compile(pat) for pat, name, f in _ALIAS_REGEX]class Cards(dict): def __init__(self): super(Cards, self).__init__(CARD_DICT) self._all = ALL def status(self): print(" 各张牌剩余情况:") for k in self._all: print(' %s : %s' % (k, self[k])) def sub(self, cards): for k in cards: self[k] -= 1 def add(self, cards): for k in cards: self[k] += 1class Game(object): def __init__(self): self.logs = list() # 用于存放出牌记录 self.cards = Cards() # 初始化扑克牌对象 self.insert_trys = (self.is_raw, self.is_alias) # 解析出牌命令的函数序列 def over(self): "判断当前游戏是否结束" logs = self.logs if not logs: # 没有出牌记录的游戏是不可能结束的 return False count_left = 0 count_right = 0 count_myself = 0 for log in logs: player_type, card_type, cards = log.split() if player_type == PLAYER_DICT[LEFT_PLAYER]: count_left += len(cards) elif player_type == PLAYER_DICT[RIGHT_PLAYER]: count_right += len(cards) else: count_myself += len(cards) first_player = logs[0].split()[0] if first_player == PLAYER_DICT[LEFT_PLAYER]: # 如果地主是上家 if count_left == 20 or count_right == 17 or count_myself == 17: return True elif first_player == PLAYER_DICT[RIGHT_PLAYER]: # 如果地主是下家 if count_left == 17 or count_right == 20 or count_myself == 17: return True else: # 如果地主是自己 if count_left == 17 or count_right == 17 or count_myself == 20: return True return False def log(self, line): self.logs.append(line) print(' ' + line) def format_cmd(self, cmd): return re.sub(r'\s', '', cmd).upper() def dispatch(self, cmd): "根据首字符对命令进行一个初次分配" cmd = self.format_cmd(cmd) if not cmd: return False flag = cmd[0] if flag in QUERY: return self.is_query(cmd) if flag in PLAYER: return self.is_insert(cmd) if flag in ALL: # 本人出的牌 return self.is_insert(MYSELF + cmd) return False def is_insert(self, cmd): "先尝试原始形式,再尝试简写形式" return any(f(cmd[0], cmd[1:]) for f in self.insert_trys) def is_raw(self, player, cards): for i, reg in enumerate(RAW_REGEX): if reg.search(cards): self.log('%s\t%s\t%s' % ( PLAYER_DICT[player], # 玩家位置 _RAW_REGEX[i][1], # 出牌类型 cards, # 牌内容 )) self.cards.sub(cards) return True return False def is_alias(self, player, cards): for i, reg in enumerate(ALIAS_REGEX): if reg.search(cards): f = _ALIAS_REGEX[i][2] raw_cards = f(cards) # 把简写出牌形式转换为原始形式.例如3-7转化为76543. self.log('%s\t%s\t%s' % ( PLAYER_DICT[player], # 玩家位置 _ALIAS_REGEX[i][1], # 出牌类型 raw_cards, )) self.cards.sub(raw_cards) return True return False def is_query(self, cmd): if cmd == '=': self.cards.status() return True if cmd == '==': # 撤销最近一次插入操作(如果有的话) if self.logs: _, _, cards = self.logs.pop().split() self.cards.add(cards) return True if re.search(r'^=[%s]$' % PLAYER, cmd): player = PLAYER_DICT[cmd[1]] print(' %s出牌记录:' % player) for log in self.logs: player_type, card_type, cards = log.split() if player == player_type: print(' %s\t%s\t%s' % (player_type, card_type, cards)) return True if re.search(r'^=[%(al)s]$' % REG_DICT, cmd): k = cmd[1] print(' 还有%s张%s' % (self.cards[k], k)) return True return False def log_to_file(self): if self.logs: with open(datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '.txt', 'w') as f: f.write('\n'.join(self.logs))def tour(): while 1: print('=========新局开始===========') game = Game() while 1: cmd = input('enter:') if cmd == '': break if game.dispatch(cmd) is False: print(' 无法识别的命令,请再试') continue # 每次合法的命令执行后,判断当前局是否结束 if game.over(): print('=========本局结束=========') break game.log_to_file()if __name__ == '__main__': tour()
一个简单的运行示例:
>>>
=========新局开始===========
enter:9-3
本人 顺子 9876543
enter:9-3
本人 顺子 9876543
enter:3-8
本人 顺子 876543
=========本局结束=========
=========新局开始===========
enter:
0 0
- 腾讯欢乐斗地主辅助程序V1.0,PYTHON实现
- IOS游戏辅助--QQ欢乐斗地主记牌器的实现
- 迷上斗地主v1.0
- 欢乐斗地主玩法规则
- Python练习题(1)_斗地主实现
- python 贪心算法实现 斗地主发牌
- 昨天晚上斗了几场地主,得到一门挑战赛冠军,喜得10000。开发欢乐斗地主游戏辅助神器
- QQ欢乐斗地主的心得体会
- 《QQ欢乐斗地主》山寨版
- 九度题目1363:欢乐斗地主
- 玩欢乐斗地主后的启发
- 对于斗地主残局,用python实现solver
- 一起斗地主 v1.3 网络版 绿色
- QQ欢乐斗地主的心得体会--坑杀盟友
- QQ欢乐斗地主心得体会 (三):高倍场攻略
- 九度OJ 1363 欢乐斗地主 (模拟,细心)
- QQ欢乐豆斗地主心得体会(四):合谋赢豆
- java仿欢乐斗地主,功能一般,大神勿笑
- 使用静态成员处理时间类
- mysql 的 find_in_set函数使用方法
- popToViewController:animated:的崩溃
- libxml/HTMLparser.h file not found 解决方法 (libxml.dylib错误处理)
- IOS开发-在iPhone和Mac电脑之间传输文稿
- 腾讯欢乐斗地主辅助程序V1.0,PYTHON实现
- ant 警告:sun.misc.BASE64Decoder 是 Sun 的专用 API,可能会在将来版本中删除
- android的setting语言列表 rk3188
- Path Sum II
- Apple Swift编程语言入门教程
- PHP 给当前时间加日期
- vim 显示中文成乱码问题解决
- 关于睡眠健康那些事
- GPU与DSP薄见