Что нового

Не обнуляются локальные переменные при повторном вызове функции

Andeangl

Новичок
Сообщения
62
Репутация
4
Доброго времени суток!

Пишу бота для игры Легенда: Наследие Драконов, столкнулся с проблемой: скрипт срабатывает 3-4 раза, а затем сообщает о переполнении массива. Такое ощущение, что совершенно не очищаются локальные переменные при повторном вызове функции. Пробовал чистить их принудительно, но как-то не выходит.

Возможно, я просто что-то делаю не так, после JS код AutoIt какой-то непривычный =))

Код:
; 0. Проверить активность клиента игры, при необходимости запустить
; 1. Определить границы игровых окон
;		- координаты поля охоты
; 		- кнопок с эликсирами
;		- координаты полоски здоровья
;		- координаты быстрых карманов + открыть быстрые карманы
;	 Задать координаты кнопок
;		- рюкзак
;		- охота
;		- локация
; 2. Определить
;		- управляющие цвета
;	 Задать
;		- таймауты задержки
;		- перерывов
; 3. Написать функцию поиска и сбора ресурса по цвету
; 4. Написать функцию поиска кнопки "отмена"
; 5. Написать функцию боя
;		- Функция поиска монстра по цвету
;		- функция проверки найденного монстра по цвету и тексту подписи, и атаки в случае успеха
;		- функция боя с триггерами:
;			:: Победа при уничтожении монстра (как только цвет полоски ХП монстра уйдёт в ноль)
;			:: Победа при появлении всплывающего окна с надписью "Победа"
;			:: Поражение при появлении надписи "Выйти из боя"
;			:: Поражение при обнулении собственного ХП (и обновление страницы)
;			:: Поражение при появлении всплывающего окна "Поражение"
; 6. Написать функцию перемещения по локациям с помощью компаса
; 7. Написать функцию перемещения по локациям без компаса


Dim $_huntZone[4] = [200, 250, 1720, 975], $search_colors[3] = [0xBD320D, 0x5D271A, 0x904D4D]

Dim $bot_mirnii = 0x00FF00, $bot_passivnii = 0x66FF00, $bot_passivnii_2 = 0x99FF00, $bot_spokoyii = 0xFFFF00, $bot_razdrajennii = 0xFF9900, $bot_agressivnii = 0xFF0000, $bot_agressivnii_2 = 0xFF4D00, $colors_bot_type[7] = [$bot_mirnii, $bot_passivnii, $bot_passivnii_2, $bot_spokoyii, $bot_razdrajennii, $bot_agressivnii, $bot_agressivnii_2 ]

Global $Paused, $temp[2] = [0, 0]

HotKeySet("{PAUSE}", "TogglePause")
HotKeySet('{Esc}', '_Exit')

Sleep(3000)

While 1
	Local $string = "Координаты: " & @CR, $i = 0
	Sleep(100)
	;MouseMove(Random(0, 1920), Random(0, 768))
	$search_result = searchAllPixels($_huntZone, $search_colors, 3)

;	Проход по всем координатам в массиве
;	While IsNumber($search_result[$i][0])
;		MouseMove($search_result[$i][0], $search_result[$i][1])
;		MouseClick("left", $search_result[$i][0], $search_result[$i][1], 1)
;		Sleep(100)
;		$i += 1
;	WEnd

	Local $stop_colors[2] = [$bot_mirnii, $bot_agressivnii]

	$search_result = checkBotCurrent($search_result, $stop_colors, 20, 30, 15, 0, 5)
	$search_result = $search_result[1]

	While IsNumber($search_result[$i][0])
		MouseMove($search_result[$i][0], $search_result[$i][1])
		MouseClick("left", $search_result[$i][0], $search_result[$i][1], 1)
		Sleep(100)
		$i += 1
	WEnd

;	Вывод списка координат и цветов
;	While $search_result[$i][0]
;		$string &= $search_result[$i][0]
;		$string &= ":"
;		$string &= $search_result[$i][1]
;		$string &= " - color: 0x"
;		$string &= StringFormat("%X", $search_result[$i][2])
;		$string &= @CR
;
;		$i += 1
;	WEnd

;	MsgBox(0, "Result", $string)



;	Local $bad_bots[1] = [$bot_agressivnii]

;	For $i = 0 To UBound($
;	Local $color = PixelGetColor($temp[0], $temp[1])
;	Local $message = "It's working!" & @CR & "Coord:" & $temp[0] & ":" & $temp[1] & @CR & "Color: 0x" & StringFormat("%X", $color) & @CR & checkBotCurrent($temp[0], $temp[1], $bad_bots, 25)
;	MouseMove($temp[0], $temp[1])
;	MsgBox(0, "Wow!", $message)
WEnd

Func searchHuntZone()
	Local $huntZoneLocal[4] = [200, 250, 1720, 975]

	return $huntZoneLocal
EndFunc

; -----------------
Func checkHuntWindow()
	Local $check

	; Ищем фиолетовый или красный пиксель кнопок отключения ресурсов
	$check = searchPixel(0, 0, @DesktopWidth, @DesktopHeight, [0xD52EDC, 0xCE0405])

	If $check[0] <> -1 Then
		checkSquare($check[0], $check[1], 10)
	EndIf
EndFunc

; Функция проверяет координаты найденного монстра и отделяет подходящие от неподходящих, по цвету пикселей, окружающих бота. Возвращает массив, хранящий 2 массива - "хороших" и "опасных" координат
Func checkBotCurrent($data_coords, $stop_colors, $limit_x = 20, $limit_y = 20, $drift_y = 0, $drift_x = 0, $deviation = 0)
	Local $good_coords[UBound($data_coords, 1) - 1][2], $good_coords_count = 0
	Local $danger_coords[UBound($data_coords, 1) - 1][2], $danger_coords_count = 0
	Local $dangers_count = 0
	Local $all_result[2]

	; Пока не закончатся координаты
	For $i = 0 To UBound($data_coords, 1) - 1
		; Создаём квадрат вокруг найденного пикселя, для проверки на наличие рядом стоп-цветов (к примеру, мобов другого типа). Можно также задать смещение по x & y, а также размеры квадрата
		Local $check_square = getSquare($data_coords[$i][0] + $drift_x, $data_coords[$i][1] + $drift_y, $limit_x, $limit_y)

		; Обнуляем счётчик "опасности" координат перед началом проверки
		$dangers_count = 0

		; Пока не закончатся стоп-цвета
		For $j = 0 To UBound($stop_colors, 1) - 1
			; Ищем пиксель заданного цвета (с погрешностью)
			PixelSearch ( $check_square[0], $check_square[1], $check_square[2], $check_square[3], $stop_colors[$j], $deviation)

			; Если нашли пиксель со стоп-цветом, повышаем "опасность" координат
			If Not @error Then
				$dangers_count += 1
			EndIf
		Next

		; Если у координат "опасность" = 0, записываем их в "хороший" массив
		If $dangers_count < 1 Then
			$good_coords[$good_coords_count][0] = $data_coords[$i][0]
			$good_coords[$good_coords_count][1] = $data_coords[$i][1]
			$good_coords_count += 1

		; Иначе записываем в "опасный" массив
		Else
			$danger_coords[$danger_coords_count][0] = $data_coords[$i][0]
			$danger_coords[$danger_coords_count][1] = $data_coords[$i][1]
			$danger_coords_count += 1
		EndIf
	Next

	; Результаты записываем в общий массив для возврата пользователю
	$all_result[0] = clearArray($good_coords)
	$all_result[1] = clearArray($danger_coords)

	$good_coords_count = 0
	$danger_coords_count = 0
	$dangers_count = 0

	Return $all_result
EndFunc

Func checkBotFree($coord_x, $coord_y, $stop_colors)

EndFunc

Func checkBotType($coord_x, $coord_y, $type)

EndFunc


Func searchAllPixels($zone, $search_colors, $deviation = 15)
	Local $data_coords[100][3], $result, $result_count = 0, $no_result[2] = [-1, -1]

	$data_coords[0][0] = -1
	$data_coords[0][1] = -1

	; В цикле заполняем для каждого из допустимых цветов массив координат
	For $i  = 0 To UBound($search_colors, 1) - 1
		; В цикле заполняем для конкретного цвета массив координат
		While $zone[1] < $zone[3]
			; Выполняем поиск цвета указанной зоне, с определённым допуском оттенков
			$result = PixelSearch ( $zone[0], $zone[1], $zone[2], $zone[3], $search_colors[$i], $deviation)

			; Если находится искомый пиксель
			If Not @error Then
				; Записываем его координаты в массив
				$data_coords[$result_count][0] = $result[0]
				$data_coords[$result_count][1] = $result[1]
				$data_coords[$result_count][2] = $search_colors[$i]
				; Увеличиваем счётчик кол-ва записей в массиве
				$result_count += 1
				; Сдвигаем зону поиска вниз
				$zone[1] = $result[1] + 1
				; Обнуляем массив координат
				$result[0] = -1
				$result[1] = -1

				If $result_count > 98 Then
					ReDim $data_coords[UBound($data_coords, 1) *2]
				EndIf
			; Если искомые пиксели кончились, заканчиваем цикл
			Else
				ExitLoop
			EndIf
		WEnd
	Next

	; Зачищаем переменную-счётчик, а то ощущение, что она нифига не локальная.
	$result_count = 0

	; Если нашлись искомые пиксели, возвращаем массив с координатами (предварительно очистив его от пустых строчек)
	If $data_coords[0][0] <> -1 Then
		Return clearArray($data_coords)

	; Если ничего не нашлось, возвращаем False
	Else
		Return False
	EndIf
EndFunc

Func clearArray( $arr )
	Local $j = 0

	; Чистим результирующий массив от мусора
	While IsNumber($arr[$j][0])
		$j += 1
	WEnd

	Local $clear_arr[$j] = $arr

	Return $clear_arr
EndFunc

Func getSquare ($coord_x, $coord_y, $limit_x = 25, $limit_y = 25)
	Local $coord_square[4]

	$coord_square[0] = $coord_x - $limit_x
	$coord_square[1] = $coord_y - $limit_y
	$coord_square[2] = $coord_x + $limit_x
	$coord_square[3] = $coord_y + $limit_y

	Return $coord_square
EndFunc

; Проверка наличия пикселей в заданном квадрате: координаты x & y, цвета для проверки, допустимая погрешность цвета, расстояние для задания области поиска
Func checkSquare ($coord_x, $coord_y, $check_colors, $deviation, $limit)
	Local $coord_square = getSquare($coord_x, $coord_y, $limit)
	Return searchPixel( $coord_square , $check_colors, $deviation )
EndFunc


Func _Exit()
	Local $exit
	$exit = MsgBox(1, "Отключение", "Завершить работу скрипта?", 10)

	If $exit == 1 Then
		Exit
	EndIf
EndFunc

Func TogglePause()
    $Paused = Not $Paused
    While $Paused
        Sleep(10)
        ToolTip('Скрипт приостановлен')
    WEnd
    ToolTip("")
EndFunc


Выше код скрипта (промежуточный), ниже - изображение, которое нужно открыть на полный экран и запустить бота. Он будет кликать по монстрам, примерно на 3-4 круге выскочит ошибка.

Ссылка на изображение для поиска: https://yadi.sk/i/kB-ps67L9iOHJg
 

sngr

AutoIT Гуру
Сообщения
985
Репутация
392
Global - объявление глобальных переменных, т.е. эти переменные действительны в любое время и в любом месте кода, в том числе и в функциях. Сохраняются на все время работы кода или до тех пор, пока вы сами их не уничтожите.

Local - объявление локальных переменных. Используется только внутри функций. Такие переменные действительны только внутри той функции, в которой были объявлены, и будут автоматически уничтожены после выхода из этой функции.

Если Local стоит не внутри функции, а в теле основного кода, то это эквивалентно Global, но является плохим стилем написания кода.

Dim - объявление массива. Т.к. массивы могут быть объявлены с помощью Global и Local, то, чтобы избежать путаницы, не рекомендуется использовать Dim там, где можно обойтись без этого.

ReDim - Изменение длины ранее созданного массива. При этом данные, которые находились в массиве сохраняются (если, конечно, длина массива увеличивается, а не уменьшается).
 
Верх