Game Development 9 min read

Python Automated Minesweeper Bot Using Win32 API and Image Recognition

This article explains how to build a Python bot that automatically plays Minesweeper by locating the game window, capturing and analyzing the board image with RGBA values, and simulating mouse clicks using win32api, providing step‑by‑step code and a basic solving algorithm.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Python Automated Minesweeper Bot Using Win32 API and Image Recognition

Automatic Minesweeper bots can be implemented in two ways: reading memory data or analyzing screenshots; this guide uses the latter.

1. Preparation

1.1 Minesweeper game – download a Windows 10 compatible version from http://www.saolei.net/BBS/.

1.2 Python 3 – the example uses Python 3.6.1.

1.3 Required third‑party libraries – win32api, win32gui, win32con, Pillow, numpy, opencv (install via pip install --upgrade package_name ).

2. Key Code Components

2.1 Find game window and coordinates

<code>#扫雷游戏窗口
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)
    print('窗口坐标:')
    print(str(left)+' '+str(right)+' '+str(top)+' '+str(bottom))
else:
    print('未找到窗口')</code>

2.2 Capture and crop the minefield image

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

#抓取雷区图像
rect = (left, top, right, bottom)
img = ImageGrab.grab().crop(rect)</code>

2.3 Define RGBA values for each tile type

<code>#数字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))]
... (other rgba definitions) ...
</code>

2.4 Scan the minefield image into a 2‑D array

<code>#扫描雷区图像
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_boom or this_image.getcolors() == rgba_boom_red:
                global gameover
                gameover = 1
                break
            else:
                print('无法识别图像')
                print('坐标')
                print((y,x))
                print('颜色')
                print(this_image.getcolors())
                sys.exit(0)</code>

2.5 Basic Minesweeper solving algorithm

The algorithm repeatedly:

Clicks a random tile to start.

For each numbered tile, if the count of adjacent unknown squares plus flagged squares equals the number, it flags all unknown squares.

If the count of flagged squares equals the number, it clicks all remaining unknown squares.

If no progress is made, it clicks a random safe square.

Key functions implementing this logic are banner() (flagging), dig() (clicking safe squares), and luck() (random click when stuck).

2.6 Main loop

<code>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(True):
        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()</code>

The author notes that while this basic approach works well on beginner and intermediate levels, it fails on advanced levels due to lack of logical combination analysis and probability handling, suggesting future improvements.

algorithmimage processingMinesweeperwin32api
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.