Python扑克胜率脚本循环卡顿且无法终止问题求助
扑克胜率脚本优化:解决无法终止与延迟问题
我刚学Python两天,写了个扑克胜率计算脚本,功能是检测屏幕上的红桃K(KH.png)或红桃A(AH.png),检测到后计算胜率并终止程序。现在脚本能在检测到目标后完成胜率计算,但之后没法终止程序,而且输出“No ACES”“No KINGS”时延迟极高。
原代码
import pied_poker as pp import numpy as np import pyautogui import time np.random.seed(420) def kings_search(): while 1: try: pyautogui.locateOnScreen('KH.png', confidence=0.9) card_one = "kh" card_two = "kd" print("KINGS!") p1 = pp.Player('Artur', pp.Card.of(card_one, card_two)) p2 = pp.Player('Opponent', pp.Card.of()) # We don't know the opponent's cards, so we leave that empty community_cards = pp.Card.of("2h", "qh", "4h", "10c", "6c") print(p1) print(f'Community cards: {community_cards}') simulator = pp.PokerRound.PokerRoundSimulator(community_cards=community_cards, players=[p1, p2], total_players=2) num_simulations = 10000 simulation_result=simulator.simulate(n=num_simulations, n_jobs=1) print(simulation_result.probability_of(pp.Probability.PlayerWins(p1))) break except pyautogui.ImageNotFoundException: print("No KINGS") aces() def aces(): while 1: try: pyautogui.locateOnScreen('AH.png', confidence=0.9) card_one = "ah" card_two = "ad" print("ACES!") p1 = pp.Player('Artur', pp.Card.of(card_one, card_two)) p2 = pp.Player('Opponent', pp.Card.of()) # We don't know the opponent's cards, so we leave that empty community_cards = pp.Card.of("2h", "qh", "4h", "10c", "6c") print(p1) print(f'Community cards: {community_cards}') simulator = pp.PokerRound.PokerRoundSimulator(community_cards=community_cards, players=[p1, p2], total_players=2) num_simulations = 10000 simulation_result=simulator.simulate(n=num_simulations, n_jobs=1) print(simulation_result.probability_of(pp.Probability.PlayerWins(p1))) break except pyautogui.ImageNotFoundException: print("No ACES") kings_search() aces()
问题分析
- 无限递归导致无法终止:
kings_search和aces互相调用,即使检测到目标break了当前循环,之前递归的层级还在继续运行,程序无法真正退出。 - 无间隔检测导致延迟高:
pyautogui.locateOnScreen是耗时操作,循环里不停调用且没有间隔,CPU占用过高,导致输出延迟。 - 代码冗余:两个检测函数逻辑几乎一致,重复代码太多。
优化后的代码
import pied_poker as pp import pyautogui import time np.random.seed(420) def calculate_win_probability(card_one, card_two, label): """提取胜率计算的公共逻辑""" print(f"{label}!") p1 = pp.Player('Artur', pp.Card.of(card_one, card_two)) p2 = pp.Player('Opponent', pp.Card.of()) community_cards = pp.Card.of("2h", "qh", "4h", "10c", "6c") print(p1) print(f'Community cards: {community_cards}') simulator = pp.PokerRound.PokerRoundSimulator( community_cards=community_cards, players=[p1, p2], total_players=2 ) num_simulations = 10000 simulation_result = simulator.simulate(n=num_simulations, n_jobs=1) print(simulation_result.probability_of(pp.Probability.PlayerWins(p1))) def main(): while True: # 先检测红桃A try: pyautogui.locateOnScreen('AH.png', confidence=0.9) calculate_win_probability("ah", "ad", "ACES") return # 检测到目标后直接退出程序 except pyautogui.ImageNotFoundException: print("No ACES") # 再检测红桃K try: pyautogui.locateOnScreen('KH.png', confidence=0.9) calculate_win_probability("kh", "kd", "KINGS") return # 检测到目标后直接退出程序 except pyautogui.ImageNotFoundException: print("No KINGS") # 添加检测间隔,降低CPU占用 time.sleep(0.5) if __name__ == "__main__": main()
优化说明
- 合并检测逻辑:用单一循环同时检查红桃A和红桃K,去掉递归调用,解决无法终止的问题。
- 添加时间间隔:每次检测循环后暂停0.5秒,大幅降低CPU使用率,解决输出延迟问题。
- 提取公共函数:把胜率计算的重复逻辑抽成
calculate_win_probability函数,减少冗余代码,提升可维护性。 - 明确终止条件:检测到目标后直接
return退出主函数,程序立即终止。
内容的提问来源于stack exchange,提问作者Artur Petrun
相关产品推荐
相关产品推荐

