Soofft91
Новичок
- Сообщения
- 1
- Репутация
- 0
Здравствуйте.
Прошло всего пару дней как я узнал об AutoIt, поэтому заранее извиняюсь если мой вопрос очень глупый и банальный.
Бот прекрасно работает когда окно расположено в левом углу монитора, стоит его немного сдвинуть как бот начинает кликать мимо поля. Могу предположить что проблема с точкой отсчёта координат (на 2 и/или 3 этапе работы), но самостоятельно уже 2-ое суток не могу исправить.
Демонстрация: youtube[точка]com/watch?v=AKa3YeVXm3k
Весь код бота:
1 этап работы: С помощью функции _ImageSearch() нахожу край игрового поля и для проверки верного нахождения отправляю туда курсор, на видео видно что положение поля всегда определяется верно. Также позиция поля попадает в окно программы.
2 этап работы: делаю снимок экрана и проверяю цвета каждого квадрата. Заношу цвета в массив.
3 этап работы: поиск 3-х идущих подряд квадрата с одинаковым цветом и клик по первому из них.
Прошло всего пару дней как я узнал об AutoIt, поэтому заранее извиняюсь если мой вопрос очень глупый и банальный.
Бот прекрасно работает когда окно расположено в левом углу монитора, стоит его немного сдвинуть как бот начинает кликать мимо поля. Могу предположить что проблема с точкой отсчёта координат (на 2 и/или 3 этапе работы), но самостоятельно уже 2-ое суток не могу исправить.
Демонстрация: youtube[точка]com/watch?v=AKa3YeVXm3k
Весь код бота:
Код:
#Include <WinAPIEx.au3>
#include <GUIConstantsEx.au3>
;~ #include <Array.au3> ; для _ArrayDisplay.
#Include <ImageSearch.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIStatusBar.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
HotKeySet("{F2}", "start")
HotKeySet("{F3}", "Pause")
HotKeySet("{F4}", "end")
;~ Local $startPole[2]
;~ Local $startPole = [85, 339]
;~ Local $endPole = [485, 700]
Global $posX = 0
Global $posY = 0
Global $status = 0
$iNumCols = 10
$iNumRows = 9
Dim $aiField[9][10]
;~ Global $wPole = $endPole[0]-$startPole[1]
;~ Global $hPole = $endPole[1]-$startPole[1]
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 171, 364, -1, -1)
$Label1 = GUICtrlCreateLabel("Позиция окна", 6, 16, 75, 17)
$Input1 = GUICtrlCreateInput("", 96, 8, 65, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_CENTER))
GUICtrlSetState(-1, $GUI_DISABLE)
$Label2 = GUICtrlCreateLabel("Клик по коорд.", 6, 46, 80, 17)
$Input2 = GUICtrlCreateInput("", 96, 40, 65, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_CENTER))
GUICtrlSetState(-1, $GUI_DISABLE)
$Button1 = GUICtrlCreateButton("Старт!", 16, 72, 131, 33)
$Group1 = GUICtrlCreateGroup("", 8, 112, 153, 9)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Label3 = GUICtrlCreateLabel("1 2 3 4 5 6 7 8 9 0", 8, 128, 147, 225)
$status = _GUICtrlStatusBar_Create($Form1)
_GUICtrlStatusBar_SetText($status, "Ожидание запуска...")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
Func end()
Exit 0
EndFunc
; Координаты поля
Func searchPole()
local $search = _ImageSearch('pic.png', 0, $posX, $posY, 0x15)
If $search = 1 Then
$posX += 20
$posY += 20
MouseClick("left", $posX, $posY, 1)
Else
MsgBox(0,"Not Found", "Corner template wasn't found")
Return False
EndIf
EndFunc
Func Div($iValue1, $iValue2) ;there is no standard div function, so i implemented mine
Return ($iValue1 - Mod($iValue1, $iValue2)) / $iValue2
EndFunc
Func _GetCheckColor($iPixelColor) ;get cell color from color of inner pixel
Local $Red = Div($iPixelColor, 0x10000)
Local $Green = Mod(Div($iPixelColor, 0x100), 0x100)
Local $Blue = Mod($iPixelColor, 0x100)
Local $d = 0x10 ;const for imprecision
;some magic numbers, obtained from experiments
Select
Case $Red > 0x90 - $d And $Green < 0x70 + $d And $Blue < 0x70 + $d
Return 1 ;red
Case $Red < 0x50 + $d And $Green > 0x90 - $d And $Blue < 0x50 + $d
Return 2 ;green
Case $Red < 0x50 + $d And $Green < 0x70 + $d And $Blue > 0x90 - $d
Return 3 ;blue
Case $Red > 0xA0 - $d And $Green > 0xA0 - $d And $Blue < 0x30 + $d
Return 4 ;yellow
Case $Red > 0x70 - $d And $Green < 0x70 + $d And $Blue > 0x90 - $d
Return 5 ;purple
Case Else
Return 0 ;indefinite color
EndSelect
EndFunc
;~ WinActivate("Diamond Dash на Facebook - Google Chrome")
Func click($iX, $iY)
MouseClick("left", $iX, $iY, 1)
EndFunc
Func getColors()
;~ $Timer = TimerInit()
Local $hWnd = WinGetHandle("[ACTIVE]")
;~ Local $hWnd = WinGetHandle("Diamond Dash на Facebook - Google Chrome")
Local $Size = WinGetClientSize($hWnd)
Local $hDC = _WinAPI_GetDC($hWnd)
Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $Size[0], $Size[1])
Local $hSv = _WinAPI_SelectObject($hMemDC, $hBitmap)
_WinAPI_BitBlt($hMemDC, 0, 0, $Size[0], $Size[1], $hDC, 0, 0, "0x00CC0020")
_WinAPI_SelectObject($hMemDC, $hSv)
_WinAPI_DeleteDC($hMemDC)
_WinAPI_ReleaseDC($hWnd, $hDC)
Local $L = $Size[0] * $Size[1]
Local $tBits = DllStructCreate('dword[' & $L & ']')
_WinAPI_GetBitmapBits($hBitmap, 4 * $L, DllStructGetPtr($tBits))
For $iCol = 0 To $iNumCols - 1
Local $fOverExplosion = False
For $iRow = $iNumRows - 1 to 0 Step -1
;explosion checkout
Local $iX = $posX + ($iCol * 40) + 14
Local $iY = $posY + ($iRow * 40) + 4
Local $iPixelColor = Mod(DllStructGetData($tBits, 1, $iY * $Size[0] + $iX), 0x1000000)
;~ If _IsWhite($iPixelColor) Then
;~ $fOverExplosion = True
;~ EndIf
If $fOverExplosion Then
$aiField[$iRow][$iCol] = 0
Else
;cell color probe
;~ $iX = $iCornerX + ($iCol * 40) + $iDeltaX
;~ $iY = $iCornerY + ($iRow * 40) + $iDeltaY
$iX = $posX + ($iCol * 40) + 14
$iY = $posY + ($iRow * 40) + 4
$iPixelColor = Mod(DllStructGetData($tBits, 1, $iY * $Size[0] + $iX), 0x1000000)
$aiField[$iRow][$iCol] = _GetCheckColor($iPixelColor)
If _GetCheckColor($iPixelColor) == 0 Then
;~ ConsoleWrite($iX&"x"&$iY&" - алмаз"&@CR)
EndIf
EndIf
Next
Next
_WinAPI_DeleteObject($hBitmap)
_WinAPI_DeleteObject($hMemDC)
_WinAPI_DeleteObject($tBits)
;~ _ArrayDisplay($aiField, 'С указанием строки и колонки в ячейках')
;~ $iDiff = TimerDiff($Timer)
;~ ConsoleWrite($iDiff / 1000&@CR)
EndFunc
Func _DfsSearch($boxColor, $iX, $iY)
$t1 = 1
;~ ConsoleWrite($iX&"x"&$iY&" ")
;~ ConsoleWrite($aiField[$iX][$iY]&" ")
If $iX <> 0 And $boxColor == $aiField[$iX-1][$iY] Then ; Проверка от текущей точки (ВВЕРХ -1)
$t1 = $t1 + 1
If $iY <> 0 And $boxColor == $aiField[$iX-1][$iY-1] Then ; (ВВЕРХ -1, ВЛЕВО -1)
$t1 = $t1 + 1
EndIf
If $iX >= 2 And $boxColor == $aiField[$iX-2][$iY] Then ; (ВВЕРХ -2)
$t1 = $t1 + 1
EndIf
If $iY <= 8 And $iX <> 0 And $boxColor == $aiField[$iX-1][$iY+1] Then ; (ВВЕРХ -1, ВПРАВО +1)
$t1 = $t1 + 1
EndIf
EndIf
If $iY <= 8 And $boxColor == $aiField[$iX][$iY+1] Then ; Проверка от текущей точки (ВПРАВО +1)
$t1 = $t1 + 1
If $iX <> 0 And $boxColor == $aiField[$iX-1][$iY+1] Then ; ( ВПРАВО +1, ВВЕРХ -1)
$t1 = $t1 + 1
EndIf
If $iY <= 7 And $boxColor == $aiField[$iX][$iY+2] Then ; ( ВПРАВО +2)
$t1 = $t1 + 1
EndIf
If $iX <> 8 And $boxColor == $aiField[$iX+1][$iY+1] Then ; ( ВПРАВО +1, ВНИЗ -1)
$t1 = $t1 + 1
EndIf
EndIf
Return $t1
EndFunc
; Поиск в глубину
Func startSearch()
getColors()
;~ _ArrayDisplay($aiField, 'С указанием строки и колонки в ячейках')
;~ $Timer2 = TimerInit()
For $i = 0 to Ubound($aiField) - 1
$numArray = 8 - $i
For $iv = 0 to 9
$sovpad = 0 ; Сбрасывание счётчика совпадений
$boxColor = $aiField[$numArray][$iv] ; Переменная с текущим цветом
If $boxColor <> 0 Then
$sovpad = _DfsSearch($boxColor, $numArray, $iv)
EndIf
; Действие если найдено больше 3-х совпадений
If $sovpad >= 3 Then
$iX = $posX + ($iv * 40) + 20
$iY = $posY + ($numArray * 40) + 20
MouseClick("left", $iX, $iY, 1)
ConsoleWrite($iX&"x"&$iY&@CR)
;~ MouseMove($iX, $iY, 1)
;~ ConsoleWrite($numArray&"x"&$iv&":"&$sovpad&" ") ; Вывод позиции для клика и кол-во совпадений
;~ $iDiff2 = TimerDiff($Timer2)
;~ ConsoleWrite($iDiff2 / 1000&@CR)
;~ Sleep(2000)
;~ startSearch()
Return False
EndIf
Next
Next
EndFunc
Func Pause()
$status = 0
_GUICtrlStatusBar_SetText($status, "Пауза")
EndFunc
;~ startSearch()
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
_GUICtrlStatusBar_SetText($status, "Работает")
start()
EndSwitch
if $status = 1 Then
Sleep(100)
startSearch()
EndIf
WEnd
Func start()
searchPole()
$status = 1
GUICtrlSetData($Input1, $posX&" x "&$posY)
#CS
While 2
Sleep(1000)
GUICtrlSetData($label3, $text)
WEnd
#CE
EndFunc
1 этап работы: С помощью функции _ImageSearch() нахожу край игрового поля и для проверки верного нахождения отправляю туда курсор, на видео видно что положение поля всегда определяется верно. Также позиция поля попадает в окно программы.
2 этап работы: делаю снимок экрана и проверяю цвета каждого квадрата. Заношу цвета в массив.
3 этап работы: поиск 3-х идущих подряд квадрата с одинаковым цветом и клик по первому из них.