zoukankan      html  css  js  c++  java
  • python实战教程之自动扫雷

    1.找到游戏窗口与坐标

    #扫雷游戏窗口
    class_name = "TMain"
    title_name = "Minesweeper Arbiter "
    hwnd = win32gui.FindWindow(class_name, title_name)

    #窗口坐标
    left = 0
    top = 0
    right = 0
    bottom = 0

    if hwnd:
    print("找到窗口")
    left, top, right, bottom = win32gui.GetWindowRect(hwnd)
    #win32gui.SetForegroundWindow(hwnd)
    print("窗口坐标:")
    print(str(left)+' '+str(right)+' '+str(top)+' '+str(bottom))
    else:
    print("未找到窗口")
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    2.锁定并抓取雷区图像

    #锁定雷区坐标#去除周围功能按钮以及多余的界面#具体的像素值是通过QQ的截图来判断的
    left += 15
    top += 101
    right -= 15
    bottom -= 42

    #抓取雷区图像
    rect = (left, top, right, bottom)
    img = ImageGrab.grab().crop(rect)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    3.各图像的RGBA值

    #数字1-8 周围雷数
    #0 未被打开
    #ed 被打开 空白
    #hongqi 红旗
    #boom 普通雷#boom_red 踩中的雷
    rgba_ed = [(225, (192, 192, 192)), (31, (128, 128, 128))]
    rgba_hongqi = [(54, (255, 255, 255)), (17, (255, 0, 0)), (109, (192, 192, 192)), (54, (128, 128, 128)), (22, (0, 0, 0))]
    rgba_0 = [(54, (255, 255, 255)), (148, (192, 192, 192)), (54, (128, 128, 128))]
    rgba_1 = [(185, (192, 192, 192)), (31, (128, 128, 128)), (40, (0, 0, 255))]
    rgba_2 = [(160, (192, 192, 192)), (31, (128, 128, 128)), (65, (0, 128, 0))]
    rgba_3 = [(62, (255, 0, 0)), (163, (192, 192, 192)), (31, (128, 128, 128))]
    rgba_4 = [(169, (192, 192, 192)), (31, (128, 128, 128)), (56, (0, 0, 128))]
    rgba_5 = [(70, (128, 0, 0)), (155, (192, 192, 192)), (31, (128, 128, 128))]
    rgba_6 = [(153, (192, 192, 192)), (31, (128, 128, 128)), (72, (0, 128, 128))]
    rgba_8 = [(149, (192, 192, 192)), (107, (128, 128, 128))]
    rgba_boom = [(4, (255, 255, 255)), (144, (192, 192, 192)), (31, (128, 128, 128)), (77, (0, 0, 0))]
    rgba_boom_red = [(4, (255, 255, 255)), (144, (255, 0, 0)), (31, (128, 128, 128)), (77, (0, 0, 0))]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    4.扫描雷区图像保存至一个二维数组map

    #扫描雷区图像
    def showmap():
    img = ImageGrab.grab().crop(rect)
    for y in range(blocks_y):
    for x in range(blocks_x):
    this_image = img.crop((x * block_width, y * block_height, (x + 1) * block_width, (y + 1) * block_height))
    if this_image.getcolors() == rgba_0:
    map[y][x] = 0
    elif this_image.getcolors() == rgba_1:
    map[y][x] = 1
    elif this_image.getcolors() == rgba_2:
    map[y][x] = 2
    elif this_image.getcolors() == rgba_3:
    map[y][x] = 3
    elif this_image.getcolors() == rgba_4:
    map[y][x] = 4
    elif this_image.getcolors() == rgba_5:
    map[y][x] = 5
    elif this_image.getcolors() == rgba_6:
    map[y][x] = 6
    elif this_image.getcolors() == rgba_8:
    map[y][x] = 8
    elif this_image.getcolors() == rgba_ed:
    map[y][x] = -1
    elif this_image.getcolors() == rgba_hongqi:
    map[y][x] = -4
    elif this_image.getcolors() == rgba_boom or this_image.getcolors() == rgba_boom_red:
    global gameover
    gameover = 1
    break
    #sys.exit(0)
    else:
    print("无法识别图像")
    print("坐标")
    print((y,x))
    print("颜色")
    print(this_image.getcolors())
    sys.exit(0)
    #print(map)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    5.扫雷算法
    这里我采用的最基础的算法

    1.首先点出一个点

    2.扫描所有数字,如果周围空白+插旗==数字,则空白均有雷,右键点击空白插旗

    3.扫描所有数字,如果周围插旗==数字,则空白均没有雷,左键点击空白

    4.循环2、3,如果没有符合条件的,则随机点击一个白块

    def banner():
    showmap()
    for y in range(blocks_y):
    for x in range(blocks_x):
    if 1 <= map[y][x] and map[y][x] <= 5:
    boom_number = map[y][x]
    block_white = 0
    block_qi = 0
    for yy in range(y-1,y+2):
    for xx in range(x-1,x+2):
    if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:
    if not (yy == y and xx == x):if map[yy][xx] == 0:
    block_white += 1
    elif map[yy][xx] == -4:
    block_qi += 1if boom_number == block_white + block_qi:for yy in range(y - 1, y + 2):
    for xx in range(x - 1, x + 2):
    if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:
    if not (yy == y and xx == x):
    if map[yy][xx] == 0:
    win32api.SetCursorPos([left+xx*block_width, top+yy*block_height])
    win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)
    win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0)
    showmap()

    #点击白块
    def dig():
    showmap()
    iscluck = 0
    for y in range(blocks_y):
    for x in range(blocks_x):
    if 1 <= map[y][x] and map[y][x] <= 5:
    boom_number = map[y][x]
    block_white = 0
    block_qi = 0
    for yy in range(y - 1, y + 2):
    for xx in range(x - 1, x + 2):
    if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:
    if not (yy == y and xx == x):
    if map[yy][xx] == 0:
    block_white += 1
    elif map[yy][xx] == -4:
    block_qi += 1if boom_number == block_qi and block_white > 0:for yy in range(y - 1, y + 2):
    for xx in range(x - 1, x + 2):
    if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:
    if not(yy == y and xx == x):
    if map[yy][xx] == 0:
    win32api.SetCursorPos([left + xx * block_width, top + yy * block_height])
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
    iscluck = 1
    if iscluck == 0:
    luck()

    #随机点击
    def luck():
    fl = 1
    while(fl):
    random_x = random.randint(0, blocks_x - 1)
    random_y = random.randint(0, blocks_y - 1)
    if(map[random_y][random_x] == 0):
    win32api.SetCursorPos([left + random_x * block_width, top + random_y * block_height])
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
    fl = 0

    def gogo(): win32api.SetCursorPos([left, top]) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) showmap() global gameover while(1): if(gameover == 0): banner() banner() dig() else: gameover = 0 win32api.keybd_event(113, 0, 0, 0) win32api.SetCursorPos([left, top]) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) showmap()
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    这个算法在初级和中级通过率都不错,但是在高级成功率惨不忍睹,主要是没有考虑逻辑组合以及白块是雷的概率问题,可以对这两个点进行改进,提高成功率

  • 相关阅读:
    网站安全编程 黑客入侵 脚本黑客 高级语法入侵 C/C++ C# PHP JSP 编程
    【算法导论】贪心算法,递归算法,动态规划算法总结
    cocoa2dx tiled map添加tile翻转功能
    8月30日上海ORACLE大会演讲PPT下载
    【算法导论】双调欧几里得旅行商问题
    Codeforces Round #501 (Div. 3) B. Obtaining the String (思维,字符串)
    Codeforces Round #498 (Div. 3) D. Two Strings Swaps (思维)
    Educational Codeforces Round 89 (Rated for Div. 2) B. Shuffle (数学,区间)
    洛谷 P1379 八数码难题 (BFS)
    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords (贪心)
  • 原文地址:https://www.cnblogs.com/ly570/p/11044526.html
Copyright © 2011-2022 走看看