gpt4 book ai didi

C - 扫雷 AI 不点击图 block

转载 作者:行者123 更新时间:2023-11-30 17:29:33 26 4
gpt4 key购买 nike

这款游戏是扫雷。我试图实现的人工智能将采用已经在计算机上运行的扫雷游戏实例(本例为 Windows 7),获取窗口的矩形尺寸,计算窗口的位置,将其推送到前台在屏幕上,单击左上角的方 block ,然后通过奇特的算法来决定哪个方 block 是地雷,哪个方 block 是空的。

最近,只有在实现 MessageBox 后,我才能正确处理窗口和光标。在单击第一个图 block 之前。

有了消息框,程序会将扫雷窗口推到最前面,生成消息框,点击消息框上的回车按钮后,程序会将光标定位到正确的左上角方 block 上然后停止。在消息框后面的代码中,有一个注释掉的部分,当取消注释时,它会迭代整个扫雷窗口并将其标记为地雷(标志!) - 这告诉我它确实注册了 ClickTile对于地雷正确 - 但不明确区域。此后,程序应该单击左上角的第一个图 block 。所发生的只是鼠标闪烁。

正确的行为是将扫雷窗口推到最前面,生成消息框,单击消息框后,应该单击游戏内左上角的方 block 。

问题是,为什么不注册 LEFTMOUSEDOWN并且只有RIGHTMOUSEDOWNClickTile

UiInfo.h

#ifndef UiInfo_
#define UiInfo_
#include <Windows.h>

struct UiInfo {
float scale;
POINT start;
int tile_size;
};

extern struct UiInfo * ui_info;

void UiInfo_initialize(struct UiInfo * ui_info,
float scale,
POINT start,
int tile_size);
#endif

UiInfo.c

#include "UiInfo.h"

void UiInfo_initialize(struct UiInfo * ui_info,
float scale,
POINT start,
int tile_size) {

ui_info->scale = scale;
ui_info->start = start;
ui_info->tile_size = tile_size;
}

main.c

void ClickTile(int is_mine, int x, int y) {
INPUT input = {0};

int xpos = (int)(ui_info->start.x + ui_info->tile_size * x);
int ypos = (int)(ui_info->start.y + ui_info->tile_size * y);

SetCursorPos(xpos, ypos);

input.type = INPUT_MOUSE;
if(is_mine) {
input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
}
else {
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
}

SendInput(1, &input, sizeof(INPUT));

ZeroMemory(&input, sizeof(INPUT));

input.type = INPUT_MOUSE;
if(is_mine) {
input.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
}
else {
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
}

SendInput(1, &input, sizeof(INPUT));
}

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) {

float scale;
POINT start;
RECT rect;
int size;
int x,y;
HWND hwnd_minesweeper = FindWindow(NULL, "Minesweeper");

GetWindowRect(hwnd_minesweeper, &rect);

scale = ((float)(rect.right - rect.left)) / ((float)(74 + 18 * 30));

// the point start is located at the center of the tile in the top left
// corner of the minesweeper map

start.x = ((long)scale) * (38 + 9) + rect.left;
start.y = rect.bottom - ((long)scale) * (38 + 15*18 + 9);

size = (int)scale * 18;

ui_info = (struct UiInfo *)malloc(sizeof(struct UiInfo));
UiInfo_initialize(ui_info, scale, start, size);

SetForegroundWindow(hwnd_minesweeper);


MessageBox(NULL, "A", "B", MB_OK);

/*for(y = 0; y < 16; y++) {
for(x = 0; x < 30; x++) {
Sleep(10);
ClickTile(1,x,y);
}
}*/

//Click the mine in the top left corner to start the game
ClickTile(0, 0, 0);

return 0;
}

最佳答案

我会进行三种猜测。

猜数字 1

您需要使用计时器来让您的鼠标移动和鼠标点击有时间生效。这涉及在应用程序启动时启动计时器,然后实现一个状态机,在计时器触发时生成新的鼠标事件,例如

// start the timer in some initialization function
SetTimer( 75, 5, NULL );

// handler function to update the overall state
void CMainFrame::OnTimer(UINT nIDEvent)
{
switch ( m_State )
{
case STATE_IDLE: // do nothing until the user tells us to start
case STATE_DONE: // do nothing after the game is finished
break;

case STATE_START: // the first click to get things started
mouse_event( MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, m_Square[1][1].mousex, m_Square[1][1].mousey, 0, 0 );
mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
mouse_event( MOUSEEVENTF_LEFTUP , 0, 0, 0, 0 );
m_State = STATE_MOVING;
break;

case STATE_MOVING: // all the fun happens here
if ( !MakeAMove() )
{
m_State = STATE_DONE;
Invalidate();
}
break;
}

CFrameWnd::OnTimer(nIDEvent);
}

猜数字2

无论屏幕分辨率如何,鼠标坐标系均为 65536 x 65536。因此,您需要缩放鼠标坐标以转换为像素位置。这是计算比例因子的一种方法

HDC hdc = ::GetDC( NULL );
CDC *dc = CDC::FromHandle( hdc );
CWnd *wnd = dc->GetWindow();
wnd->GetClientRect( &rect );
xscale = 65535.0 / (double)rect.right;
yscale = 65535.0 / (double)rect.bottom;

猜数字3

在生成鼠标点击事件之前,您需要将鼠标移动到正确的屏幕坐标,例如

// the following code goes in some initialization function that knows the location of the minesweeper window
// note that screenx and screeny are the pixel coordinates of the center point of each square and these
// are converted to mouse coordinates for each square
for ( y = 1; y <= m_MaxY; y++ )
for ( x = 1; x <= m_MaxX; x++ )
{
m_Square[y][x].mousex = (int)(m_Square[y][x].screenx * xscale + 0.5);
m_Square[y][x].mousey = (int)(m_Square[y][x].screeny * yscale + 0.5);
}

// this code generates a left click in a given square
mouse_event( MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, m_Square[y][x].mousex, m_Square[y][x].mousey, 0, 0 );
mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
mouse_event( MOUSEEVENTF_LEFTUP , 0, 0, 0, 0 );

关于C - 扫雷 AI 不点击图 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25585772/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com