621 lines
29 KiB
Python
621 lines
29 KiB
Python
# -*- coding: utf-8 -*-
|
||
# Created by: Raf
|
||
# Modify by: Vincentzyx
|
||
|
||
import GameHelper as gh
|
||
from GameHelper import GameHelper
|
||
import os
|
||
import sys
|
||
import time
|
||
import threading
|
||
import pyautogui
|
||
import win32gui
|
||
from PIL import Image
|
||
import multiprocessing as mp
|
||
import cv2
|
||
import numpy as np
|
||
|
||
from PyQt5 import QtGui, QtWidgets, QtCore
|
||
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsItem, QGraphicsPixmapItem, QInputDialog, QMessageBox
|
||
from PyQt5.QtGui import QPixmap, QIcon
|
||
from PyQt5.QtCore import QTime, QEventLoop
|
||
from MainWindow import Ui_Form
|
||
|
||
from douzero.env.game import GameEnv
|
||
from douzero.evaluation.deep_agent import DeepAgent
|
||
import traceback
|
||
|
||
import BidModel
|
||
import LandlordModel
|
||
import FarmerModel
|
||
|
||
EnvCard2RealCard = {3: '3', 4: '4', 5: '5', 6: '6', 7: '7',
|
||
8: '8', 9: '9', 10: 'T', 11: 'J', 12: 'Q',
|
||
13: 'K', 14: 'A', 17: '2', 20: 'X', 30: 'D'}
|
||
|
||
RealCard2EnvCard = {'3': 3, '4': 4, '5': 5, '6': 6, '7': 7,
|
||
'8': 8, '9': 9, 'T': 10, 'J': 11, 'Q': 12,
|
||
'K': 13, 'A': 14, '2': 17, 'X': 20, 'D': 30}
|
||
|
||
AllEnvCard = [3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
|
||
8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12,
|
||
12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 17, 17, 17, 17, 20, 30]
|
||
|
||
AllCards = ['rD', 'bX', 'b2', 'r2', 'bA', 'rA', 'bK', 'rK', 'bQ', 'rQ', 'bJ', 'rJ', 'bT', 'rT',
|
||
'b9', 'r9', 'b8', 'r8', 'b7', 'r7', 'b6', 'r6', 'b5', 'r5', 'b4', 'r4', 'b3', 'r3']
|
||
|
||
helper = GameHelper()
|
||
helper.ScreenZoomRate = 1.25 # 请修改屏幕缩放比
|
||
|
||
class MyPyQT_Form(QtWidgets.QWidget, Ui_Form):
|
||
def __init__(self):
|
||
super(MyPyQT_Form, self).__init__()
|
||
self.setupUi(self)
|
||
self.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint | # 使能最小化按钮
|
||
QtCore.Qt.WindowCloseButtonHint) # 窗体总在最前端 QtCore.Qt.WindowStaysOnTopHint
|
||
self.setFixedSize(self.width(), self.height()) # 固定窗体大小
|
||
# self.setWindowIcon(QIcon('pics/favicon.ico'))
|
||
window_pale = QtGui.QPalette()
|
||
# window_pale.setBrush(self.backgroundRole(), QtGui.QBrush(QtGui.QPixmap("pics/bg.png")))
|
||
self.setPalette(window_pale)
|
||
self.Players = [self.RPlayer, self.Player, self.LPlayer]
|
||
self.counter = QTime()
|
||
|
||
# 参数
|
||
self.MyConfidence = 0.95 # 我的牌的置信度
|
||
self.OtherConfidence = 0.9 # 别人的牌的置信度
|
||
self.WhiteConfidence = 0.95 # 检测白块的置信度
|
||
self.LandlordFlagConfidence = 0.9 # # 检测地主标志的置信度
|
||
self.ThreeLandlordCardsConfidence = 0.9 # 检测地主底牌的置信度
|
||
self.PassConfidence = 0.85
|
||
self.WaitTime = 1 # 等待状态稳定延时
|
||
self.MyFilter = 40 # 我的牌检测结果过滤参数
|
||
self.OtherFilter = 25 # 别人的牌检测结果过滤参数
|
||
self.SleepTime = 0.1 # 循环中睡眠时间
|
||
self.RunGame = False
|
||
self.AutoPlay = False
|
||
self.BidThreshold1 = 65 # 叫地主阈值
|
||
self.BidThreshold2 = 72 # 抢地主阈值
|
||
self.JiabeiThreshold = (
|
||
(85, 72), # 叫地主 超级加倍 加倍 阈值
|
||
(85, 75) # 叫地主 超级加倍 加倍 阈值 (在地主是抢来的情况下)
|
||
)
|
||
self.MingpaiThreshold = 92
|
||
# 坐标
|
||
self.MyHandCardsPos = (250, 764, 1141, 70) # 我的截图区域
|
||
self.LPlayedCardsPos = (463, 355, 380, 250) # 左边截图区域
|
||
self.RPlayedCardsPos = (946, 355, 380, 250) # 右边截图区域
|
||
self.LandlordFlagPos = [(1281, 276, 110, 140), (267, 695, 110, 140), (424, 237, 110, 140)] # 地主标志截图区域(右-我-左)
|
||
self.ThreeLandlordCardsPos = (763, 37, 287, 136) # 地主底牌截图区域,resize成349x168
|
||
self.PassBtnPos = (686, 659, 419, 100)
|
||
self.GeneralBtnPos = (616, 631, 576, 117)
|
||
# 信号量
|
||
self.shouldExit = 0 # 通知上一轮记牌结束
|
||
self.canRecord = threading.Lock() # 开始记牌
|
||
self.card_play_model_path_dict = {
|
||
'landlord': "baselines/douzero_ADP/landlord.ckpt",
|
||
'landlord_up': "baselines/douzero_ADP/landlord_up.ckpt",
|
||
'landlord_down': "baselines/douzero_ADP/landlord_down.ckpt"
|
||
}
|
||
|
||
def init_display(self):
|
||
self.WinRate.setText("评分")
|
||
self.InitCard.setText("开始")
|
||
self.UserHandCards.setText("手牌")
|
||
self.LPlayedCard.setText("上家出牌区域")
|
||
self.RPlayedCard.setText("下家出牌区域")
|
||
self.PredictedCard.setText("AI出牌区域")
|
||
self.ThreeLandlordCards.setText("地主牌")
|
||
self.SwitchMode.setText("自动" if self.AutoPlay else "单局")
|
||
for player in self.Players:
|
||
player.setStyleSheet('background-color: rgba(255, 0, 0, 0);')
|
||
|
||
def switch_mode(self):
|
||
self.AutoPlay = not self.AutoPlay
|
||
self.SwitchMode.setText("自动" if self.AutoPlay else "单局")
|
||
|
||
def init_cards(self):
|
||
self.RunGame = True
|
||
GameHelper.Interrupt = False
|
||
self.init_display()
|
||
# 玩家手牌
|
||
self.user_hand_cards_real = ""
|
||
self.user_hand_cards_env = []
|
||
# 其他玩家出牌
|
||
self.other_played_cards_real = ""
|
||
self.other_played_cards_env = []
|
||
# 其他玩家手牌(整副牌减去玩家手牌,后续再减掉历史出牌)
|
||
self.other_hand_cards = []
|
||
# 三张底牌
|
||
self.three_landlord_cards_real = ""
|
||
self.three_landlord_cards_env = []
|
||
# 玩家角色代码:0-地主上家, 1-地主, 2-地主下家
|
||
self.user_position_code = None
|
||
self.user_position = ""
|
||
# 开局时三个玩家的手牌
|
||
self.card_play_data_list = {}
|
||
# 出牌顺序:0-玩家出牌, 1-玩家下家出牌, 2-玩家上家出牌
|
||
self.play_order = 0
|
||
|
||
self.env = None
|
||
|
||
# 识别玩家手牌
|
||
self.user_hand_cards_real = self.find_my_cards(self.MyHandCardsPos)
|
||
self.UserHandCards.setText(self.user_hand_cards_real)
|
||
self.user_hand_cards_env = [RealCard2EnvCard[c] for c in list(self.user_hand_cards_real)]
|
||
# 识别三张底牌
|
||
self.three_landlord_cards_real = self.find_three_landlord_cards(self.ThreeLandlordCardsPos)
|
||
self.ThreeLandlordCards.setText("底牌:" + self.three_landlord_cards_real)
|
||
self.three_landlord_cards_env = [RealCard2EnvCard[c] for c in list(self.three_landlord_cards_real)]
|
||
for testCount in range(1, 5):
|
||
if len(self.three_landlord_cards_env) > 3:
|
||
self.ThreeLandlordCardsConfidence += 0.05
|
||
elif len(self.three_landlord_cards_env) < 3:
|
||
self.ThreeLandlordCardsConfidence -= 0.05
|
||
else:
|
||
break
|
||
self.three_landlord_cards_real = self.find_three_landlord_cards(self.ThreeLandlordCardsPos)
|
||
self.ThreeLandlordCards.setText("底牌:" + self.three_landlord_cards_real)
|
||
self.three_landlord_cards_env = [RealCard2EnvCard[c] for c in list(self.three_landlord_cards_real)]
|
||
# 识别玩家的角色
|
||
self.user_position_code = self.find_landlord(self.LandlordFlagPos)
|
||
if self.user_position_code is None:
|
||
items = ("地主上家", "地主", "地主下家")
|
||
item, okPressed = QInputDialog.getItem(self, "选择角色", "未识别到地主,请手动选择角色:", items, 0, False)
|
||
if okPressed and item:
|
||
self.user_position_code = items.index(item)
|
||
else:
|
||
return
|
||
self.user_position = ['landlord_up', 'landlord', 'landlord_down'][self.user_position_code]
|
||
for player in self.Players:
|
||
player.setStyleSheet('background-color: rgba(255, 0, 0, 0);')
|
||
self.Players[self.user_position_code].setStyleSheet('background-color: rgba(255, 0, 0, 0.1);')
|
||
|
||
# 整副牌减去玩家手上的牌,就是其他人的手牌,再分配给另外两个角色(如何分配对AI判断没有影响)
|
||
for i in set(AllEnvCard):
|
||
self.other_hand_cards.extend([i] * (AllEnvCard.count(i) - self.user_hand_cards_env.count(i)))
|
||
self.card_play_data_list.update({
|
||
'three_landlord_cards': self.three_landlord_cards_env,
|
||
['landlord_up', 'landlord', 'landlord_down'][(self.user_position_code + 0) % 3]:
|
||
self.user_hand_cards_env,
|
||
['landlord_up', 'landlord', 'landlord_down'][(self.user_position_code + 1) % 3]:
|
||
self.other_hand_cards[0:17] if (self.user_position_code + 1) % 3 != 1 else self.other_hand_cards[17:],
|
||
['landlord_up', 'landlord', 'landlord_down'][(self.user_position_code + 2) % 3]:
|
||
self.other_hand_cards[0:17] if (self.user_position_code + 1) % 3 == 1 else self.other_hand_cards[17:]
|
||
})
|
||
print("开始对局")
|
||
print("手牌:",self.user_hand_cards_real)
|
||
print("地主牌:",self.three_landlord_cards_real)
|
||
# 生成手牌结束,校验手牌数量
|
||
if len(self.card_play_data_list["three_landlord_cards"]) != 3:
|
||
QMessageBox.critical(self, "底牌识别出错", "底牌必须是3张!", QMessageBox.Yes, QMessageBox.Yes)
|
||
self.init_display()
|
||
return
|
||
if len(self.card_play_data_list["landlord_up"]) != 17 or \
|
||
len(self.card_play_data_list["landlord_down"]) != 17 or \
|
||
len(self.card_play_data_list["landlord"]) != 20:
|
||
QMessageBox.critical(self, "手牌识别出错", "初始手牌数目有误", QMessageBox.Yes, QMessageBox.Yes)
|
||
self.init_display()
|
||
return
|
||
# 得到出牌顺序
|
||
self.play_order = 0 if self.user_position == "landlord" else 1 if self.user_position == "landlord_up" else 2
|
||
|
||
# 创建一个代表玩家的AI
|
||
ai_players = [0, 0]
|
||
ai_players[0] = self.user_position
|
||
ai_players[1] = DeepAgent(self.user_position, self.card_play_model_path_dict[self.user_position])
|
||
|
||
self.env = GameEnv(ai_players)
|
||
|
||
try:
|
||
self.start()
|
||
except Exception as e:
|
||
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||
print(e)
|
||
traceback.print_tb(exc_tb)
|
||
self.stop()
|
||
|
||
def sleep(self, ms):
|
||
self.counter.restart()
|
||
while self.counter.elapsed() < ms:
|
||
QtWidgets.QApplication.processEvents(QEventLoop.AllEvents, 50)
|
||
|
||
def start(self):
|
||
self.env.card_play_init(self.card_play_data_list)
|
||
print("开始出牌\n")
|
||
while not self.env.game_over:
|
||
# 玩家出牌时就通过智能体获取action,否则通过识别获取其他玩家出牌
|
||
if self.play_order == 0:
|
||
self.PredictedCard.setText("...")
|
||
action_message = self.env.step(self.user_position)
|
||
# 更新界面
|
||
self.UserHandCards.setText("手牌:" + str(''.join(
|
||
[EnvCard2RealCard[c] for c in self.env.info_sets[self.user_position].player_hand_cards]))[::-1])
|
||
|
||
self.PredictedCard.setText(action_message["action"] if action_message["action"] else "不出")
|
||
self.WinRate.setText("评分:" + action_message["win_rate"])
|
||
print("\n手牌:", str(''.join(
|
||
[EnvCard2RealCard[c] for c in self.env.info_sets[self.user_position].player_hand_cards])))
|
||
print("出牌:", action_message["action"] if action_message["action"] else "不出", ",得分:",
|
||
action_message["win_rate"])
|
||
if action_message["action"] == "":
|
||
helper.ClickOnImage("pass_btn", region=self.PassBtnPos)
|
||
else:
|
||
hand_cards_str = ''.join([EnvCard2RealCard[c] for c in self.env.info_sets[self.user_position].player_hand_cards])
|
||
if len(hand_cards_str) == 0 and len(action_message["action"]) == 1:
|
||
helper.SelectCards(action_message["action"], True)
|
||
else:
|
||
helper.SelectCards(action_message["action"])
|
||
tryCount = 20
|
||
result = helper.LocateOnScreen("play_card", region=self.PassBtnPos, confidence=0.85)
|
||
while result is None and tryCount > 0:
|
||
if not self.RunGame:
|
||
break
|
||
print("等待出牌按钮")
|
||
self.detect_start_btn()
|
||
tryCount -= 1
|
||
result = helper.LocateOnScreen("play_card", region=self.PassBtnPos, confidence=0.85)
|
||
self.sleep(100)
|
||
helper.ClickOnImage("play_card", region=self.PassBtnPos, confidence=0.85)
|
||
self.sleep(2200)
|
||
self.detect_start_btn()
|
||
self.play_order = 1
|
||
elif self.play_order == 1:
|
||
self.RPlayedCard.setText("...")
|
||
pass_flag = helper.LocateOnScreen('pass',
|
||
region=self.RPlayedCardsPos,
|
||
confidence=self.PassConfidence)
|
||
self.detect_start_btn()
|
||
while self.RunGame and self.have_white(self.RPlayedCardsPos) == 0 and pass_flag is None:
|
||
print("等待下家出牌")
|
||
self.sleep(100)
|
||
pass_flag = helper.LocateOnScreen('pass', region=self.RPlayedCardsPos,
|
||
confidence=self.PassConfidence)
|
||
self.detect_start_btn()
|
||
self.sleep(200)
|
||
# 未找到"不出"
|
||
if pass_flag is None:
|
||
# 识别下家出牌
|
||
self.RPlayedCard.setText("等待动画")
|
||
self.sleep(1200)
|
||
self.RPlayedCard.setText("识别中")
|
||
self.other_played_cards_real = self.find_other_cards(self.RPlayedCardsPos)
|
||
print("下家出牌", self.other_played_cards_real)
|
||
self.sleep(500)
|
||
# 找到"不出"
|
||
else:
|
||
self.other_played_cards_real = ""
|
||
print("\n下家出牌:", self.other_played_cards_real)
|
||
self.other_played_cards_env = [RealCard2EnvCard[c] for c in list(self.other_played_cards_real)]
|
||
self.other_played_cards_env.sort()
|
||
self.env.step(self.user_position, self.other_played_cards_env)
|
||
# 更新界面
|
||
self.RPlayedCard.setText(self.other_played_cards_real if self.other_played_cards_real else "不出")
|
||
self.play_order = 2
|
||
self.sleep(500)
|
||
elif self.play_order == 2:
|
||
self.LPlayedCard.setText("...")
|
||
self.detect_start_btn()
|
||
pass_flag = helper.LocateOnScreen('pass', region=self.LPlayedCardsPos,
|
||
confidence=self.PassConfidence)
|
||
while self.RunGame and self.have_white(self.LPlayedCardsPos) == 0 and pass_flag is None:
|
||
print("等待上家出牌")
|
||
self.detect_start_btn()
|
||
self.sleep(100)
|
||
pass_flag = helper.LocateOnScreen('pass', region=self.LPlayedCardsPos,
|
||
confidence=self.PassConfidence)
|
||
self.sleep(200)
|
||
# 不出
|
||
# 未找到"不出"
|
||
if pass_flag is None:
|
||
# 识别上家出牌
|
||
self.LPlayedCard.setText("等待动画")
|
||
self.sleep(1200)
|
||
self.LPlayedCard.setText("识别中")
|
||
self.other_played_cards_real = self.find_other_cards(self.LPlayedCardsPos)
|
||
# 找到"不出"
|
||
else:
|
||
self.other_played_cards_real = ""
|
||
print("\n上家出牌:", self.other_played_cards_real)
|
||
self.other_played_cards_env = [RealCard2EnvCard[c] for c in list(self.other_played_cards_real)]
|
||
self.other_played_cards_env.sort()
|
||
self.env.step(self.user_position, self.other_played_cards_env)
|
||
self.play_order = 0
|
||
# 更新界面
|
||
self.LPlayedCard.setText(self.other_played_cards_real if self.other_played_cards_real else "不出")
|
||
self.sleep(500)
|
||
else:
|
||
pass
|
||
self.sleep(100)
|
||
|
||
print("{}胜,本局结束!\n".format("农民" if self.env.winner == "farmer" else "地主"))
|
||
# QMessageBox.information(self, "本局结束", "{}胜!".format("农民" if self.env.winner == "farmer" else "地主"),
|
||
# QMessageBox.Yes, QMessageBox.Yes)
|
||
self.detect_start_btn()
|
||
|
||
def find_landlord(self, landlord_flag_pos):
|
||
for pos in landlord_flag_pos:
|
||
result = helper.LocateOnScreen("landlord_words", region=pos,
|
||
confidence=self.LandlordFlagConfidence)
|
||
if result is not None:
|
||
return landlord_flag_pos.index(pos)
|
||
return None
|
||
|
||
def detect_start_btn(self):
|
||
result = helper.LocateOnScreen("change_player_btn", region=(400, 400, 934, 800))
|
||
if result is not None:
|
||
print("点击换对手")
|
||
self.stop()
|
||
if self.AutoPlay:
|
||
helper.ClickOnImage("change_player_btn", region=(400, 400, 934, 800))
|
||
self.sleep(1000)
|
||
self.beforeStart()
|
||
result = helper.LocateOnScreen("finish_round", region=(810,840,200,80), confidence=0.8)
|
||
if result is not None:
|
||
helper.ClickOnImage("finish_round", region=(810,840,200,80), confidence=0.8)
|
||
self.sleep(1000)
|
||
result = helper.LocateOnScreen("next_round", region=(958,869,300,100), confidence=0.8)
|
||
if result is not None:
|
||
helper.ClickOnImage("next_round", region=(958,869,300,100), confidence=0.8)
|
||
self.sleep(1000)
|
||
self.beforeStart()
|
||
result = helper.LocateOnScreen("yes_btn", region=(680, 661, 435, 225))
|
||
if result is not None:
|
||
helper.ClickOnImage("yes_btn", region=(680, 661, 435, 225))
|
||
self.sleep(1000)
|
||
result = helper.LocateOnScreen("get_award_btn", region=(680, 661, 435, 225))
|
||
if result is not None:
|
||
helper.ClickOnImage("get_award_btn", region=(680, 661, 435, 225))
|
||
self.sleep(1000)
|
||
result = helper.LocateOnScreen("yes_btn_sm", region=(669, 583, 468, 100))
|
||
if result is not None:
|
||
helper.ClickOnImage("yes_btn_sm", region=(669, 583, 468, 100))
|
||
self.sleep(200)
|
||
|
||
|
||
def find_three_landlord_cards(self, pos):
|
||
img, _ = helper.Screenshot()
|
||
img = img.crop((pos[0], pos[1], pos[0] + pos[2], pos[1] + pos[3]))
|
||
img = img.resize((349, 168))
|
||
three_landlord_cards_real = ""
|
||
for card in AllCards:
|
||
result = pyautogui.locateAll(needleImage=helper.Pics['o' + card], haystackImage=img,
|
||
confidence=self.ThreeLandlordCardsConfidence)
|
||
three_landlord_cards_real += card[1] * self.cards_filter(list(result), self.OtherFilter)
|
||
if len(three_landlord_cards_real) > 3:
|
||
three_landlord_cards_real = ""
|
||
for card in AllCards:
|
||
result = pyautogui.locateAll(needleImage=helper.Pics['o' + card], haystackImage=img,
|
||
confidence=self.ThreeLandlordCardsConfidence + 0.05)
|
||
three_landlord_cards_real += card[1] * self.cards_filter(list(result), self.OtherFilter)
|
||
if len(three_landlord_cards_real) < 3:
|
||
three_landlord_cards_real = ""
|
||
for card in AllCards:
|
||
result = pyautogui.locateAll(needleImage=helper.Pics['o' + card], haystackImage=img,
|
||
confidence=self.ThreeLandlordCardsConfidence + 0.1)
|
||
three_landlord_cards_real += card[1] * self.cards_filter(list(result), self.OtherFilter)
|
||
return three_landlord_cards_real
|
||
|
||
def find_my_cards(self, pos):
|
||
user_hand_cards_real = ""
|
||
img, _ = helper.Screenshot()
|
||
cards, _ = helper.GetCards(img)
|
||
for c in cards:
|
||
user_hand_cards_real += c[0]
|
||
# for card in AllCards:
|
||
# result = pyautogui.locateAll(needleImage=helper.Pics['m'+card], haystackImage=img, confidence=self.MyConfidence)
|
||
# user_hand_cards_real += card[1] * self.cards_filter(list(result), self.MyFilter)
|
||
return user_hand_cards_real
|
||
|
||
def find_other_cards(self, pos):
|
||
other_played_cards_real = ""
|
||
img, _ = helper.Screenshot()
|
||
imgCv = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
|
||
for card in AllCards:
|
||
result = gh.LocateAllOnImage(imgCv, helper.PicsCV['o' + card], region=pos, confidence=self.OtherConfidence)
|
||
if len(result) > 0:
|
||
other_played_cards_real += card[1] * self.cards_filter(list(result), self.OtherFilter)
|
||
if other_played_cards_real == "DX":
|
||
other_played_cards_real = "XD"
|
||
return other_played_cards_real
|
||
|
||
def cards_filter(self, location, distance): # 牌检测结果滤波
|
||
if len(location) == 0:
|
||
return 0
|
||
locList = [location[0][0]]
|
||
count = 1
|
||
for e in location:
|
||
flag = 1 # “是新的”标志
|
||
for have in locList:
|
||
if abs(e[0] - have) <= distance:
|
||
flag = 0
|
||
break
|
||
if flag:
|
||
count += 1
|
||
locList.append(e[0])
|
||
return count
|
||
|
||
def have_white(self, pos): # 是否有白块
|
||
img, _ = helper.Screenshot()
|
||
result = pyautogui.locate(needleImage=helper.Pics["white"], haystackImage=img,
|
||
region=pos, confidence=self.WhiteConfidence)
|
||
if result is None:
|
||
return 0
|
||
else:
|
||
return 1
|
||
|
||
def stop(self):
|
||
try:
|
||
self.RunGame = False
|
||
self.env.game_over = True
|
||
self.env.reset()
|
||
self.init_display()
|
||
self.PreWinrate.setText("局前预估胜率:")
|
||
self.BidWinrate.setText("叫牌预估胜率:")
|
||
except AttributeError as e:
|
||
pass
|
||
if self.AutoPlay:
|
||
play_btn = helper.LocateOnScreen("change_player_btn", region=(400, 400, 934, 404))
|
||
while play_btn is None and self.AutoPlay:
|
||
play_btn = helper.LocateOnScreen("change_player_btn", region=(400, 400, 934, 404))
|
||
self.sleep(100)
|
||
if play_btn is not None:
|
||
helper.LeftClick((play_btn[0], play_btn[1]))
|
||
self.beforeStart()
|
||
|
||
def beforeStart(self):
|
||
self.RunGame = True
|
||
GameHelper.Interrupt = True
|
||
HaveBid = False
|
||
isTaodou = False
|
||
is_stolen = 0
|
||
while True:
|
||
if not self.RunGame:
|
||
return
|
||
outterBreak = False
|
||
jiaodizhu_btn = helper.LocateOnScreen("jiaodizhu_btn", region=(765, 663, 116, 50))
|
||
qiangdizhu_btn = helper.LocateOnScreen("qiangdizhu_btn", region=(783, 663, 116, 50))
|
||
jiabei_btn = helper.LocateOnScreen("jiabei_btn", region=self.GeneralBtnPos)
|
||
self.detect_start_btn()
|
||
while jiaodizhu_btn is None and qiangdizhu_btn is None and jiabei_btn is None:
|
||
self.detect_start_btn()
|
||
print("等待加倍或叫地主")
|
||
self.sleep(100)
|
||
jiaodizhu_btn = helper.LocateOnScreen("jiaodizhu_btn", region=(765, 663, 116, 50))
|
||
qiangdizhu_btn = helper.LocateOnScreen("qiangdizhu_btn", region=(783, 663, 116, 50))
|
||
jiabei_btn = helper.LocateOnScreen("jiabei_btn", region=self.GeneralBtnPos)
|
||
if jiabei_btn is None:
|
||
img, _ = helper.Screenshot()
|
||
cards, _ = helper.GetCards(img)
|
||
cards_str = "".join([card[0] for card in cards])
|
||
win_rate = BidModel.predict(cards_str)
|
||
if not HaveBid:
|
||
with open("cardslog.txt", "a") as f:
|
||
f.write(str(int(time.time())) + " " + cards_str + " " + str(round(win_rate, 2)) + "\n")
|
||
print("预计叫地主胜率:", win_rate)
|
||
self.BidWinrate.setText("叫牌预估胜率:" + str(round(win_rate, 2)) + "%")
|
||
is_stolen = 0
|
||
if jiaodizhu_btn is not None:
|
||
HaveBid = True
|
||
if win_rate > self.BidThreshold1:
|
||
helper.ClickOnImage("jiaodizhu_btn", region=(765, 663, 116, 50), confidence=0.9)
|
||
else:
|
||
helper.ClickOnImage("bujiao_btn", region=self.GeneralBtnPos)
|
||
elif qiangdizhu_btn is not None:
|
||
is_stolen = 1
|
||
HaveBid = True
|
||
if win_rate > self.BidThreshold2:
|
||
helper.ClickOnImage("qiangdizhu_btn", region=(783, 663, 116, 50), confidence=0.9)
|
||
else:
|
||
helper.ClickOnImage("buqiang_btn", region=self.GeneralBtnPos)
|
||
else:
|
||
pass
|
||
if HaveBid:
|
||
result = helper.LocateOnScreen("taodouchang", region=(835,439,140,40), confidence=0.9)
|
||
if result is not None:
|
||
isTaodou = True
|
||
print("淘豆场,跳过加倍")
|
||
break
|
||
else:
|
||
llcards = self.find_three_landlord_cards(self.ThreeLandlordCardsPos)
|
||
print("地主牌:", llcards)
|
||
img, _ = helper.Screenshot()
|
||
cards, _ = helper.GetCards(img)
|
||
cards_str = "".join([card[0] for card in cards])
|
||
if len(cards_str) == 20:
|
||
win_rate = LandlordModel.predict(cards_str)
|
||
self.PreWinrate.setText("局前预估胜率:" + str(round(win_rate, 2)) + "%")
|
||
print("预估地主胜率:", win_rate)
|
||
else:
|
||
user_position_code = self.find_landlord(self.LandlordFlagPos)
|
||
user_position = "up"
|
||
while user_position_code is None:
|
||
user_position_code = self.find_landlord(self.LandlordFlagPos)
|
||
self.sleep(50)
|
||
user_position = ['up', 'landlord', 'down'][user_position_code]
|
||
win_rate = FarmerModel.predict(cards_str, llcards, user_position) - 5
|
||
print("预估农民胜率:", win_rate)
|
||
self.PreWinrate.setText("局前预估胜率:" + str(round(win_rate, 2)) + "%")
|
||
if win_rate > self.JiabeiThreshold[is_stolen][0]:
|
||
chaojijiabei_btn = helper.LocateOnScreen("chaojijiabei_btn", region=self.GeneralBtnPos)
|
||
if chaojijiabei_btn is not None:
|
||
helper.ClickOnImage("chaojijiabei_btn", region=self.GeneralBtnPos)
|
||
else:
|
||
helper.ClickOnImage("jiabei_btn", region=self.GeneralBtnPos)
|
||
elif win_rate > self.JiabeiThreshold[is_stolen][1]:
|
||
helper.ClickOnImage("jiabei_btn", region=self.GeneralBtnPos)
|
||
else:
|
||
helper.ClickOnImage("bujiabei_btn", region=self.GeneralBtnPos)
|
||
outterBreak = True
|
||
break
|
||
if outterBreak:
|
||
break
|
||
|
||
llcards = self.find_three_landlord_cards(self.ThreeLandlordCardsPos)
|
||
while len(llcards) != 3:
|
||
print("等待地主牌", llcards)
|
||
self.sleep(100)
|
||
llcards = self.find_three_landlord_cards(self.ThreeLandlordCardsPos)
|
||
|
||
print("等待加倍环节结束")
|
||
if not isTaodou:
|
||
self.sleep(7000)
|
||
else:
|
||
self.sleep(2000)
|
||
if win_rate > self.MingpaiThreshold:
|
||
helper.ClickOnImage("mingpai_btn", region=self.GeneralBtnPos)
|
||
self.init_cards()
|
||
|
||
|
||
if __name__ == '__main__':
|
||
app = QtWidgets.QApplication(sys.argv)
|
||
app.setStyleSheet("""
|
||
QPushButton{
|
||
text-align : center;
|
||
background-color : white;
|
||
font: bold;
|
||
border-color: gray;
|
||
border-width: 2px;
|
||
border-radius: 10px;
|
||
padding: 6px;
|
||
height : 14px;
|
||
border-style: outset;
|
||
font : 14px;
|
||
}
|
||
QPushButton:hover{
|
||
background-color : light gray;
|
||
}
|
||
QPushButton:pressed{
|
||
text-align : center;
|
||
background-color : gray;
|
||
font: bold;
|
||
border-color: gray;
|
||
border-width: 2px;
|
||
border-radius: 10px;
|
||
padding: 6px;
|
||
height : 14px;
|
||
border-style: outset;
|
||
font : 14px;
|
||
padding-left:9px;
|
||
padding-top:9px;
|
||
}
|
||
QComboBox{
|
||
background:transparent;
|
||
border: 1px solid rgba(200, 200, 200, 100);
|
||
font-weight: bold;
|
||
}
|
||
QComboBox:drop-down{
|
||
border: 0px;
|
||
}
|
||
QComboBox QAbstractItemView:item{
|
||
height: 30px;
|
||
}
|
||
QLabel{
|
||
background:transparent;
|
||
font-weight: bold;
|
||
}
|
||
""")
|
||
my_pyqt_form = MyPyQT_Form()
|
||
my_pyqt_form.show()
|
||
sys.exit(app.exec_())
|