Что нового

Прохождение Сапёра за 60 Секунд

Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
SyDr [?]
В первом видео - это просто чтение из памяти процесса значений и клики в нужны местах
Нет.

Вот скрипт (у меня отрабатывает за 18 секунд проф. режим)...

Minesweeper helper & solver.au3
Код:
#Region Header

; Name...........:	Minesweeper helper/solver
; Description....:	For each field in the Windows Minesweeper game shows a tooltip with hint about mine (is there a mine or not)
; Author.........:	G.Sandler (CreatoR), www.autoit-script.ru
; Modified.......:	
; Remarks........:	Tested only on WinXP SP3.
; Link...........:	
; ===============================================================================================================

#EndRegion Header

#Region Variable & Constants

Global $bAutoSolve 					= True

Global $hWinMine
Global $hDesktop 					= WinGetHandle("[CLASS:Progman]")
Global $bCheated 					= False
Global $bHoverMark 					= False

Global $iWinMine_FieldSize 			= 16
Global $iWinMine_FirstFieldTop 		= 110
Global $nWinMine_FieldColor 		= 0xC0C0C0

Global $sWinMine_Beginner_Level 	= "Beginner"
Global $sWinMine_Intermediate_Level = "Intermediate"
Global $sWinMine_Expert_Level 		= "Expert"

Global $sWinMine_Level 				= $sWinMine_Expert_Level

Global $iWinMine_Rows 				= 9
Global $iWinMine_Columns 			= 9

Global Const $sWinMine_Exe 			= "winmine.exe"

#EndRegion Variable & Constants

#Region Startup & Options

Switch $sWinMine_Level
	Case $sWinMine_Beginner_Level
		$iWinMine_Rows = 9
		$iWinMine_Columns = 9
	Case $sWinMine_Intermediate_Level
		$iWinMine_Rows = 16
		$iWinMine_Columns = 16
	Case $sWinMine_Expert_Level
		$iWinMine_Rows = 16
		$iWinMine_Columns = 30
EndSwitch

HotKeySet("{ESC}", "_Quit")

Opt("PixelCoordMode", 0)
Opt("MouseCoordMode", 0)

If Not ProcessExists($sWinMine_Exe) Then
	Run($sWinMine_Exe)
	
	While Not $hWinMine
		$hWinMine = _ProcessGetWindow($sWinMine_Exe, 1, 1)
		Sleep(10)
	WEnd
	
	;ControlClick("[class:TfrmuvMainForm]", "", "TBitBtn6")
EndIf

$hWinMine = _ProcessGetWindow($sWinMine_Exe, 1, 1)
If @error Then Exit

#EndRegion Startup & Options

#Region Main

_MineSweeper_Cheat()

If $bAutoSolve Then
	_MineSweeper_Solve()
	Exit
EndIf

While WinExists($hWinMine)
	Sleep(10)
	
	If _WinGetHoveredHandle() = $hWinMine Then
		$bHoverMark = True
		$bFieldIsMine = _MineSweeper_FieldIsMine()
		
		If $bFieldIsMine Then
			ToolTip("!!! Mined !!!", Default, Default, "Attention!!!", 2, 4)
		Else
			ToolTip("NOT Mined!", Default, Default, "OK", 1, 4)
		EndIf
	ElseIf $bHoverMark And Not $bAutoSolve Then
		$bHoverMark = False
		ToolTip("")
	EndIf
WEnd

#EndRegion Main

#Region Program functions

Func _MineSweeper_Cheat()
	SendKeepActive($hWinMine)
	Send("xyzzy")
	Send("{LShift}")
EndFunc

Func _MineSweeper_Solve()
	Local $aWinMinePos = WinGetPos($hWinMine)
	Local $aFieldPos
	
	For $iRow = 0 To $iWinMine_Rows - 1
		For $iColumn = 0 To $iWinMine_Columns
			$aFieldPos = PixelSearch($iColumn * $iWinMine_FieldSize, $iWinMine_FirstFieldTop + ($iRow * $iWinMine_FieldSize), _
				$aWinMinePos[2], $aWinMinePos[3], $nWinMine_FieldColor, 0, 2, $hWinMine)
			
			If Not @error Then
				;First field
				If $iRow + $iColumn = 0 Then
					MouseClick("Primary", $aFieldPos[0]+10, $aFieldPos[1], 1, 0)
					Sleep(500)
					ContinueLoop
				EndIf
				
				MouseMove($aFieldPos[0], $aFieldPos[1], 1)
				
				If _MineSweeper_FieldIsMine() Then
					;MouseClick("Secondary", $aFieldPos[0], $aFieldPos[1], 1, 1)
				Else
					MouseClick("Primary", $aFieldPos[0], $aFieldPos[1], 1, 1)
				EndIf
				
				If ($iRow + $iColumn) >= ($iWinMine_Rows + $iWinMine_Columns) Then
					ExitLoop 2
				EndIf
			EndIf
		Next
	Next
EndFunc

Func _MineSweeper_FieldIsMine()
	Return (PixelGetColor(0, 0, $hDesktop) <> 0xFFFFFF)
EndFunc

Func _ProcessGetWindow($iPID, $iRet = -1, $iRetVisibleOnly = 0)
	Local $aWinList = WinList(), $aRet[2]
	
	If IsString($iPID) Then
		$iPID = ProcessExists($iPID)
	EndIf
	
	For $i = 1 To UBound($aWinList)-1
		If (($iRetVisibleOnly And BitAND(WinGetState($aWinList[$i][1]), 2)) Or Not $iRetVisibleOnly) And WinGetProcess($aWinList[$i][1]) = $iPID Then
			$aRet[0] = $aWinList[$i][0] ;Title
			$aRet[1] = $aWinList[$i][1] ;WinHandle
			
			If $iRet = 0 Then
				Return $aRet[0]
			EndIf
			
			If $iRet = 1 Then
				Return $aRet[1]
			EndIf
			
			Return $aRet
		EndIf
	Next
	
	Return SetError(1, 0, $aRet)
EndFunc

Func _WinGetHoveredHandle()
	Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1)
	Local $Ret = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))
	
	Opt("MouseCoordMode", $iOld_Opt_MCM)
	
	Return HWnd($Ret[0])
EndFunc

Func _Quit()
	Exit
EndFunc

#EndRegion Program functions


Если $bAutoSolve = False, скрипт работает как помощник, показывает под курсором нахождение мины.
$sWinMine_Level указывает режим игры - обязательно нужно установить на выбранный режим.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Sky-WaLkeR [?]
Работает только на XP
У меня часто “спотыкается” на мине, или доходить до конца оставляя нераскрытые поля (где мин нет).
 

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
Увидеть бы скрипт, где чисто алгоритмом всё сделано :smile:
 

Viktor217

Осваивающий
Сообщения
233
Репутация
31
CreatoR, http://autoit-script.ru/index.php?topic=3920.msg28832#msg28832 в этом варианте у меня только по первой клеточке щёлкается...
XP sp3
 

SyDr

Сидра
Сообщения
651
Репутация
158
Никто не подскажет, какие клетки надо открывать в таких ситуациях и почему?
http://www.dropmocks.com/mQMdl
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
SyDr [?]
Никто не подскажет, какие клетки надо открывать в таких ситуациях и почему?
Почему, долго писать ;D
В слепую по картинке (без вскрытия клеток) тяжеловато дать полный ответ :(
Но пара (помечена красным) точно есть! :smile:
P.S. Кстати, появилась идея! Написать скрипт, который в тяжелых ситуациях мог бы снять дамп и записать, к примеру, в файл. Потом запускаем игру, читаем дамп из файла, и воспроизводим ситуацию на другом компьютере! ;)
Таким образом, можно было бы сейчас решить вашу задачу ;D
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
kzru_hunter [?]
Увидеть бы скрипт, где чисто алгоритмом всё сделано
Наврядли такой есть.

Sky-WaLkeR [?]
Работает только на XP. Профи за 7 секунд. запускаем прогу и жмем Ctrl+Alt+ноль
Модифицированная версия, проходит за 4 секунды проф. уровень:

Код:
#include <WinAPI.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>

Global Const $pMine_sData = 0x1005330
Global Const $pMines = 0x1005340
Global Const $iField_Size = 16

Global $bWinMine_HoverMark = False
Global $bWinMine_Cheated = False
Global $bWinMine_EnableHelper = False

Global $aExtrnlBtn_Ctrls[1][5], $aExtrnlBtn_OldParentPos = -1, $sExtrnlBtn_MainTitle
Global $nSolve_Bttn, $nHelper_Bttn

Global $iBytesRead, $hWinMine_Wnd, $iWinMine_Proc
Global $hDesktop = WinGetHandle("[CLASS:Progman]")
Global $iWinMine_PID = ProcessExists("winmine.exe")

If Not $iWinMine_PID Then
	$iWinMine_PID = Run("winmine.exe") ;run it
EndIf

$hWinMine_Wnd = _ProcessWaitWindow($iWinMine_PID, 1, 5)
$nSolve_Bttn = _ExternalButton_Create("S", "Solve (CTRL + SHIFT + S)", "_WinMine_Solve", 20, 18, 110, 27, $hWinMine_Wnd)
$nHelper_Bttn = _ExternalButton_Create("eH", "Enable Helper (CTRL + SHIFT + H)", "_WinMine_Helper", 20, 18, 140, 27, $hWinMine_Wnd)
AdlibRegister("_ExternalButton_Follow", 1)
WinActivate($hWinMine_Wnd)

$iWinMine_Proc = _WinAPI_OpenProcess(0x1F0FFF, 1, $iWinMine_PID, True) ;open it
$sExtrnlBtn_MainTitle = $hWinMine_Wnd

Opt("MouseCoordMode", 0)
Opt("MouseClickDelay", 0)
Opt("MouseClickDownDelay", 0)
Opt("GUICloseOnESC", 0)
Opt("GUIOnEventMode", 1)
Opt("WinWaitDelay", 0)

HotKeySet('^+s', '_WinMine_Solve')
HotKeySet('^+e', '_WinMine_Exit')
HotKeySet('^+h', '_WinMine_Helper')

While ProcessExists($iWinMine_PID)
	Sleep(10)
	
	If $bWinMine_EnableHelper Then
		If Not $bWinMine_Cheated Then
			$bWinMine_Cheated = True
			
			_WinMine_Cheat()
			_ExternalButton_Fix()
		EndIf
		
		If WinExists($hWinMine_Wnd) Then
			If _WinHovered($hWinMine_Wnd) Then
				$bWinMine_HoverMark = True
				
				If _WinMine_FieldIsMine() Then
					ToolTip("!!! Mined !!!", Default, Default, "Attention!!!", 2, 4)
				Else
					ToolTip("NOT Mined!", Default, Default, "OK", 1, 4)
				EndIf
			ElseIf $bWinMine_HoverMark Then
				$bWinMine_HoverMark = False
				ToolTip("")
			EndIf
		EndIf
	EndIf
WEnd

Func _WinMine_Exit()
	Exit ProcessClose($iWinMine_PID)
EndFunc

Func _WinMine_IsMine($iX, $iY)
	Local $stBuffer, $nMine
	
	$stBuffer = DllStructCreate("ubyte mine")
	_WinAPI_ReadProcessMemory($iWinMine_Proc, $pMines + (($iField_Size * 2) * ($iY + 1)) + ($iX + 1), DllStructGetPtr($stBuffer), DllStructGetSize($stBuffer), $iBytesRead)
	
	$nMine = DllStructGetData($stBuffer, "mine")
	
	If $nMine = 0x40 Then
		Return -1
	ElseIf $nMine = 0x0F Then
		Return 0
	ElseIf $nMine = 0x8f Then
		Return 1
	EndIf
EndFunc

Func _WinMine_FieldIsMine()
	Return (PixelGetColor(0, 0, $hDesktop) <> 0xFFFFFF)
EndFunc

Func _WinMine_Solve()
	Local $stData, $iMines, $iColumns, $iRows
	
	$bWinMine_EnableHelper = False
	
	For $i = 1 To $aExtrnlBtn_Ctrls[0][0]
		GUICtrlSetState($aExtrnlBtn_Ctrls[$i][2], $GUI_DISABLE)
	Next
	
	_ExternalButton_Fix()
	
	$stData = DllStructCreate("dword mines;dword width;dword height")
	_WinAPI_ReadProcessMemory($iWinMine_Proc, $pMine_sData, DllStructGetPtr($stData), DllStructGetSize($stData), $iBytesRead) ;Get widht, height and number of mines :)
	
	$iMines = DllStructGetData($stData, "mines")
	$iColumns = DllStructGetData($stData, "width")
	$iRows = DllStructGetData($stData, "height")
	
	ConsoleWrite(StringFormat("%i Mines in a %i by %i grid\n", $iMines, $iColumns, $iRows))
	
	_ExternalButton_Follow()
	WinActivate($hWinMine_Wnd)
	
	For $iRow = 0 To $iRows - 1
		For $iColumn = 0 To $iColumns - 1
			Switch _WinMine_IsMine($iColumn, $iRow)
				;Case -1 ;Already open
					;ContinueLoop
				Case 0 ;Safe to click on
					ControlClick($hWinMine_Wnd, "", "", "Primary", 1, 20 + ($iColumn * $iField_Size), ($iField_Size * $iRow) + 60)
				;Case 1 ;MINE!!!!
					;ControlClick($hWinMine_Wnd, "", "", "Secondary", 1, 20 + ($iColumn * $iField_Size), ($iField_Size * $iRow) + 60)
			EndSwitch
			
			;Sleep(25) ;Looks cool :P
		Next
	Next
	
	For $i = 1 To $aExtrnlBtn_Ctrls[0][0]
		GUICtrlSetState($aExtrnlBtn_Ctrls[$i][2], $GUI_ENABLE)
	Next
EndFunc

Func _WinMine_Helper()
	$bWinMine_EnableHelper = Not $bWinMine_EnableHelper
	_ExternalButton_Fix()
	
	If $bWinMine_EnableHelper Then
		GUICtrlSetData($nHelper_Bttn, "dH")
		GUICtrlSetTip($nHelper_Bttn, "Disable Helper (CTRL + SHIFT + H)")
	Else
		GUICtrlSetData($nHelper_Bttn, "eH")
		GUICtrlSetTip($nHelper_Bttn, "Enable Helper (CTRL + SHIFT + H)")
	EndIf
	
	ToolTip("")
EndFunc

Func _WinMine_Cheat()
	SendKeepActive($hWinMine_Wnd)
	Send("xyzzy")
	Send("{LShift}")
EndFunc

Func _WinHovered($hWnd)
	Local $iOpt_MCM = Opt("MouseCoordMode", 1)
	Local $aRet = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))
	
	Opt("MouseCoordMode", $iOpt_MCM)
	
	Return (HWnd($aRet[0]) = $hWnd)
EndFunc

Func _ProcessWaitWindow($iPID, $iVisibleOnly = 0, $iWait = 0)
	Local $hRet = -1, $iErr = 0, $iTimer = TimerInit(), $iOpt_WWD = Opt("WinWaitDelay", 1), $aWinList
	
	If IsString($iPID) Then
		$iPID = ProcessExists($iPID)
	EndIf
	
	If $iWait > 0 Then
		$iWait *= 1000
	EndIf
	
	While 1
		$aWinList = WinList()
		
		For $i = 1 To UBound($aWinList)-1
			If (($iVisibleOnly And BitAND(WinGetState($aWinList[$i][1]), 2)) Or Not $iVisibleOnly) And WinGetProcess($aWinList[$i][1]) = $iPID Then
				$hRet = $aWinList[$i][1] ;WinHandle
				ExitLoop 2
			EndIf
		Next
		
		If $iWait > 0 And TimerDiff($iTimer) >= $iWait Then
			$iErr = 1
			ExitLoop
		EndIf
		
		Sleep(10)
	WEnd
	
	Opt("WinWaitDelay", $iOpt_WWD)
	Return SetError($iErr, 0, $hRet)
EndFunc

Func _ExternalButton_Create($sBttnTxt, $sBttnTip, $sBttnFnc, $iBttnWidth, $iBttnHeight, $iFloatLeft, $iFloatTop, $hParent)
	Local $hButton_GUI, $nButton
	
	$hButton_GUI = GUICreate("", $iBttnWidth, $iBttnHeight, -1, -1, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
	$nButton = GUICtrlCreateButton($sBttnTxt, 0, 0, $iBttnWidth, $iBttnHeight)
	GUICtrlSetTip($nButton, $sBttnTip)
	
	GUICtrlSetOnEvent(-1, $sBttnFnc)
	GUISetState(@SW_SHOW, $hButton_GUI)
	
	$aExtrnlBtn_Ctrls[0][0] += 1
	ReDim $aExtrnlBtn_Ctrls[$aExtrnlBtn_Ctrls[0][0]+1][5]
	
	$aExtrnlBtn_Ctrls[$aExtrnlBtn_Ctrls[0][0]][0] = $hParent
	$aExtrnlBtn_Ctrls[$aExtrnlBtn_Ctrls[0][0]][1] = $hButton_GUI
	$aExtrnlBtn_Ctrls[$aExtrnlBtn_Ctrls[0][0]][2] = $nButton
	$aExtrnlBtn_Ctrls[$aExtrnlBtn_Ctrls[0][0]][3] = $iFloatLeft
	$aExtrnlBtn_Ctrls[$aExtrnlBtn_Ctrls[0][0]][4] = $iFloatTop
	
	Return $nButton
EndFunc

Func _ExternalButton_Follow()
	Local $hParent, $hButton_GUI, $nButton, $iFloatLeft, $iFloatTop, $aParentPos, $aParentClientSize, $iBorder_Size, $iX, $iY
	
	For $i = 1 To $aExtrnlBtn_Ctrls[0][0]
		$hParent = $aExtrnlBtn_Ctrls[$i][0]
		$hButton_GUI = $aExtrnlBtn_Ctrls[$i][1]
		$nButton = $aExtrnlBtn_Ctrls[$i][2]
		$iFloatLeft = $aExtrnlBtn_Ctrls[$i][3]
		$iFloatTop = $aExtrnlBtn_Ctrls[$i][4]
		
		If $hParent <> -1 And Not WinExists($hParent) Then
			GUISetState(@SW_HIDE, $hButton_GUI)
			$hParent = -1
		ElseIf $hParent = -1 And WinExists($sExtrnlBtn_MainTitle) Then
			GUISetState(@SW_SHOW, $hButton_GUI)
			$hParent = WinGetHandle($sExtrnlBtn_MainTitle)
		ElseIf $hParent = -1 Then
			ContinueLoop
		EndIf
		
		$aParentPos = WinGetPos($hParent)
		
		If @error Or Not IsArray($aParentPos) Then
			ContinueLoop
		EndIf
		
		$aParentClientSize = WinGetClientSize($hParent)
		
		If Not WinActive($hParent) And Not WinActive($hButton_GUI) Then
			$aParentPos[0] = -3200
			$aParentPos[1] = -3200
		EndIf
		
		If $i > 1 Or ($aExtrnlBtn_OldParentPos = -1 Or $aExtrnlBtn_OldParentPos[0] <> $aParentPos[0] Or $aExtrnlBtn_OldParentPos[1] <> $aParentPos[1] Or _
			$aExtrnlBtn_OldParentPos[2] <> $aParentPos[2]) Then
			
			$aExtrnlBtn_OldParentPos = $aParentPos
			
			$iBorder_Size = ($aParentPos[2] - $aParentClientSize[0]) / 2
			
			$iX = $aParentPos[0] + $iFloatLeft
			$iY = $aParentPos[1] + $iBorder_Size + $iFloatTop
			
			WinMove($hButton_GUI, "", $iX, $iY)
		EndIf
	Next
EndFunc

;???
Func _ExternalButton_Fix()
	$aExtrnlBtn_OldParentPos = -1
	WinActivate($hWinMine_Wnd)
EndFunc
 

SyDr

Сидра
Сообщения
651
Репутация
158
Garrett [?]
P.S. Кстати, появилась идея! Написать скрипт, который в тяжелых ситуациях мог бы снять дамп и записать, к примеру, в файл. Потом запускаем игру, читаем дамп из файла, и воспроизводим ситуацию на другом компьютере!
Для Mines можно загружать конкретные раскладки (в menu Random Seed...)

Почему, долго писать
Ну тут вроде не долго писать: если мина есть в средней неотемеченной клеточке, то тогда её нет сверху и снизу от неё (1 и 3). Но в этом случае не будет хватать мин для 2. А это значит, что в средней клеточке мины нет.
Другими словами, это уже идёт перебор. Вот только реализовывать его не очень хочется.

CreatoR [?]
Это реплей от скрипта :smile: Написал скрипт, который повторяет клики мышью в указанных координатах.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
SyDr [?]
Написал скрипт, который повторяет клики мышью в указанных координатах
Ну так всё равно нужно заранее знать где кликать, а это значит что использовался чит :blum:
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
SyDr [?]
Для Mines можно загружать конкретные раскладки (в menu Random Seed...)
У меня в Win XP нет такого пункта в меню, к тому же "Random Seed" это случайное распределение мин, я же предложил создать своеобразный "Save game" для сапёра! :smile:
К примеру, вы сейчас смогли бы выложить свой save.txt на форум, а любой желающий смог бы его скачать и восстановить ситуацию у себя.
 

SyDr

Сидра
Сообщения
651
Репутация
158
Нет, в Win 7 - жуткий сапёр со свистоперделками.

http://portableapps.com/apps/games/puzzle_collection_portable
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
[?]
Модифицированная версия, проходит за 4 секунды проф. уровень
А если добавить в начало скрипта
Код:
Opt("MouseClickDelay", 0)
Opt("MouseClickDownDelay", 0)

то проходит за 1 секунду!

P.S
Кстати это дело не документировано, опций MouseClick* действуют для Mouse* функций, нигде не написано про ControlClick.

SyDr [?]
в Win 7 - жуткий сапёр со свистоперделками
Ну тогда это немного не то, тут речь про виндовский Сапёр (WinMine).
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
dwerf [?]
Память не читал, окна не правил, в работающий процесс нестандартными методами не вмешивался.
Через реестр? :whistle:
 

NoMad73rus

Продвинутый
Сообщения
124
Репутация
80
kzru_hunter сказал(а):
Увидеть бы скрипт, где чисто алгоритмом всё сделано :smile:
А вот мой чистый алгоритм, правда не дописал - плюнул
Код:
; ss_bot ver 0.0
;~ #NoTrayIcon
#include <Array.au3>

If Not ProcessExists("winmine.exe") Then
	Run("winmine.exe")
EndIf

Opt("MouseCoordMode", 2)
Opt ("PixelCoordMode", 2)

Global Const $titl = "Сапер"
Global Const $klass = "Сапер"
Global $sh, $vs
$wp = WinGetPos($titl)
Select
	Case $wp[2] = 170
		Global $sh =9			;ширина поля
		Global $vs = 9			;высота поля
		$xx = 75
	Case $wp[2] = 282
		Global $sh =16			;ширина поля
		Global $vs = 16			;высота поля
		$xx = 130
	Case $wp[2] = 336
		Global $sh =30			;ширина поля
		Global $vs = 16			;высота поля
		$xx = 243
	Case Else
		Exit
EndSelect

Global Const $sh1 = $sh-1
Global Const $vs1 = $vs-1
Global $st_pos[2] = [20,62]		;координаты верхней левой клетки
Global $step = 16				;размер клеток
Global $map[$vs][$sh]
_reset()
;~ _ArrayDisplay($map)

HotKeySet("^+!s", "_exit")
HotKeySet("^+!ы", "_exit")

	WinActivate($titl)
	WinWaitActive($titl)
	$chs = PixelChecksum($xx, 18, $xx+20, 34)
While 1
	_skan()
;~ 	_ArrayDisplay($map)
;~ 	WinActivate($titl)
;~ 	WinWaitActive($titl)
	_work()
;~ 	_ArrayDisplay($map)
;~ 	Sleep(50)
	If $chs <> PixelChecksum($xx, 18, $xx+20, 34) Then
		Do
			WinActivate("", "Вы стали чем")
			Sleep(Random(500,2000))
			WinActivate("", "Вы стали чем")
			Send("{ENTER}")
			WinActivate("Чемпионы")
			Sleep(500)
			Send("{ENTER}")
			MouseClick("left", $xx+10, 26, 1, 0)
			Sleep(500)
		Until $chs = PixelChecksum($xx, 18, $xx+20, 34)
		_reset()
	EndIf
WEnd

Func _skan()
	For $stolb = 0 To $sh1
		For $strok = 0 To $vs1
			If $map[$strok][$stolb] = 0 Then
;~ 				_click($stolb, $strok)
				_detekt($stolb, $strok, 1)
			EndIf
		Next
	Next
EndFunc



Func _click($x, $y)
	MouseClick("left", $st_pos[0]+$x*$step, $st_pos[1]+$y*$step, 1, 0)
EndFunc
Func _rclick($x, $y)
	MouseClick("right", $st_pos[0]+$x*$step, $st_pos[1]+$y*$step, 1, 0)
EndFunc

Func _detekt($x, $y, $save=0)
	If $map[$y][$x] <> 0 Then Return $map[$y][$x]
	$r_x = $x*$step+$st_pos[0]
	$r_y = $y*$step+$st_pos[1]
	$ya = -8
	For $is = $r_x-8 To $r_x+5
		$color = PixelGetColor($is, $r_y)
;~ 		ConsoleWrite("0x"&hex($color, 6)&@CRLF)
		Select
			Case $color = 0xFFFFFF
				$ya = 0
				ExitLoop
			Case $color = 0x0000FF
				$ya = 1
				ExitLoop
			Case $color = 0x008000
				$ya = 2
				ExitLoop
			Case $color = 0xFF0000
				$ya = 3
				ExitLoop
			Case $color = 0x000080
				$ya = 4
				ExitLoop
			Case $color = 0x800000
				$ya = 5
				ExitLoop
			Case $color = 0x008080
				$ya = 6
				ExitLoop
			Case $color = 0x000000
				$ya = 7
				ExitLoop
;~ 			Case Else
;~ 				$ya = -8
;~ 				ExitLoop
		EndSelect
	Next
	If $save = 1 Then $map[$y][$x]=$ya
	Return $ya
EndFunc

Func _work()
	$kkl = 0
	For $stolb = 0 To $sh1
		For $strok = 0 To $vs1
;~ 			If $map[$strok][$stolb] <> 0 Then
				$kkl+=_obhod($stolb, $strok)
;~ 			EndIf
		Next
	Next
	If $kkl = 0 Then
		$x = Random(0, $sh1,1)
		$y = Random(0, $vs1,1)
		If $map[$y][$x] = 0 Then _click($x,$y)
	EndIf
EndFunc

Func _obhod($x, $y)
	If $map[$y][$x] < 1 Then Return
	$kkl = 0
	$kl = 0
	$min = 0
	For $hor = -1 To 1
		For $ver = -1 To 1
			$xp = $x+$hor
			$yp = $y+$ver
			If $xp<0 Or $yp<0 or $xp>$sh1 or $yp>$vs1 or ($xp=$x and $yp = $y) Then ContinueLoop
			If $map[$yp][$xp] = 0 Then $kl+=1
			If $map[$yp][$xp] = -1 Then $min+=1
		Next
	Next
;~ 	ConsoleWrite($kl&@CRLF)
	If $kl+$min = $map[$y][$x] Then
		For $hor = -1 To 1
			For $ver = -1 To 1
				$xp = $x+$hor
				$yp = $y+$ver
				If $xp<0 Or $yp<0 or $xp>$sh1 or $yp>$vs1 or ($xp=$x and $yp = $y) Then ContinueLoop
				If $map[$yp][$xp] = 0 Then
					$map[$yp][$xp] = -1
					_rclick($xp, $yp)
				EndIf
			Next
		Next
	EndIf
	If $min = $map[$y][$x] Then
		For $hor = -1 To 1
			For $ver = -1 To 1
				$xp1 = $x+$hor
				$yp1 = $y+$ver
				If $xp1<0 Or $yp1<0 or $xp1>$sh1 or $yp1>$vs1 or ($xp1=$x and $yp1=$y) Then ContinueLoop
				If $map[$yp1][$xp1] = 0 Then
					_click($xp1,$yp1)
					$kkl+=1
				EndIf
			Next
		Next
	EndIf
	Return $kkl
EndFunc
Func _reset()
	For $i_2 = 0 To $sh1
		For $i_1 = 0 To $vs1
			$map[$i_1][$i_2]=0
		Next
	Next
EndFunc
Func _exit()
	Exit
EndFunc
 

elik

Новичок
Сообщения
1
Репутация
0
CreatoR [?]
dwerf [?]Цитата
Память не читал, окна не правил, в работающий процесс нестандартными методами не вмешивался.
Через реестр?
whistle.gif

Через две кнопки мыши + Esc
 
Верх