Что нового

Pathing Bot. Волновой алгоритм перемещения в ммо играх.

yukuru

Влюбленный Бродячий Кот
Сообщения
48
Репутация
4
Бельфигор. Вы гениальны. спасибо.

вопрос. какие альтернативные методы есть для ускорения. ибо действительо несколько долго.

И просьба. Можете ли вы переделать код, такЪ что бы он выводил несколько вариантов движения. например Самый короткий и самый длинный. или, что бы путь проходил через Определенную точку.
тоесть не только старт и финиш, а Контрольная ТОЧКА еще.

сможете? был бы признателен.
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Я в комсомольске на амуре в командировке на несколько месяцев, у меня просто не будет времени на это. Оптимизация - дискретизация, сначала находить путь через более большие квадраты а потом через них уже искать путь. Для вейпоинта просто модифицируй текущий алгоритм или же просто задавай два пути, из пункта а в пункт б и из пункта б в пункт с.
 

yukuru

Влюбленный Бродячий Кот
Сообщения
48
Репутация
4
Код:
Global $Form1 = GUICreate("Path Finder v0.2 be Belfigor", 1200, 800)

Global $Button1 = GUICtrlCreateButton("Start", 1100, 0, 75, 25)
Global $Button2 = GUICtrlCreateButton("Restart", 1100, 25, 75, 25)

Global $CellSize = 5
Global $Label[105][105]



проблема в том что он не выресовывает всЁ.
останавливается где на 90 у.....и х 10(до этого се нормально чертит)
в чм проблема еть варианты?...и главное зависает..
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
yukuru сказал(а):
проблема в том что он не выресовывает всЁ. останавливается где на 90 у.....и х 10(до этого се нормально чертит) в чм проблема еть варианты?...и главное зависает..
Где-то в этой теме кто-то писал что нашел баг связанный с тем что при каком-то условии скрипт перестает считать путь.
 

yukuru

Влюбленный Бродячий Кот
Сообщения
48
Репутация
4
нет. проблема что он не прорисовывает даже с смаого начала...когда только отрисовывает пустое поле.
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
yukuru сказал(а):
нет. проблема что он не прорисовывает даже с смаого начала...когда только отрисовывает пустое поле.
не знаю, у меня все рисовал :smile:
 

yukuru

Влюбленный Бродячий Кот
Сообщения
48
Репутация
4
прикладываю вложение.
у с 3х компов разной конфигурации запускал..ДУмал проблема.....везде одинаково.

практика показала. отрисвывает ровно 9790 кубиков и дальше зависает
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
А это, лимит контролов.
 

yukuru

Влюбленный Бродячий Кот
Сообщения
48
Репутация
4
и как с этим бороться? в идеале надо осздать поле 210 на 210
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Изменить код так, чтобы он использовал не контролы для прорисовки поля а что-нибудь другое.
 

alex_r

Новичок
Сообщения
4
Репутация
0
Недавно открыл для себя AutoIt, пытаюсь с ним разобраться. За что отвечает эта строка?

Case $nMsg = 3 To 6

Вроде бы ничего не делает, но если убрать, то скрипт перестает работать.
 

irvin12345

Новичок
Сообщения
30
Репутация
2
омг, это были контролы. И код, о мои глаза, не проще ли было реализовать весь этот тотальный перебор рекурсией?
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Это пример. А кто и как уже будет это реализовывать, от меня не зависит.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Очень важную тему поднял ТС.
Жалко только остановился на середине - ограничился примером.
Просто выкладываю скрипты, которые у меня получились при использовании алгоритма для реального бота.

1. Создание массива-карты.
Берём картинку-карту, затягиваем в GUI и создаём файл .au3, который потом затягиваем в скрипт бота по
Код:
#include <Map_b.au3>

Код:
#include <GDIP.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Math.au3>
#include <Color.au3>
#include <File.au3>
#include <Misc.au3> ;  добавил

_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\снимок.JPG')
$iWidth = _GDIPlus_ImageGetWidth($hImage)
$iHeight = _GDIPlus_ImageGetHeight($hImage)
$iBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($iBitmap)

Global $Form1 = GUICreate("Map Editor", 701, 801)
Global $Radio1 = GUICtrlCreateRadio("Не проходимый", 0, 0, 101, 17)
Global $Radio2 = GUICtrlCreateRadio("Проходимый", 105, 0, 89, 17)
Global $CellSize = 8
Global $Label[53][60]
Global $yMax = UBound($Label,2), $xMax = UBound($Label,1)
Global $GeoData[$xMax][$yMax]
$xMax -= 1
$yMax -= 1

For $y = 0 To $yMax Step 1
	For $x = 0 To $xMax Step 1
		$Label[$x][$y] = GUICtrlCreateLabel(99999, $x*$CellSize, $y*$CellSize+17, $CellSize, $CellSize, $WS_BORDER)
		$color = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, 33+$x*8, 55+$y*8),6)
		GUICtrlSetColor(-1, $color)
		GUICtrlSetBkColor(-1, $color)
		$RGBColor = _ColorGetRGB( $color )
		If $RGBColor[0] < 10 And $RGBColor[1] < 10 And $RGBColor[2] < 10 Then GUICtrlSetData($Label[$x][$y], 100000)
	Next
Next
Global $Button1 = GUICtrlCreateButton("Start", 615, 10, 75, 25)
Global $Button2 = GUICtrlCreateButton("Save map", 615, 40, 75, 25)
GUISetState(@SW_SHOW)

Dim $dll = DllOpen("user32.dll") ;  добавил
AutoItSetOption("MouseCoordMode", 2) ;  добавил

While 1
	Local $nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $nMsg = 3	 To 6
			;
		 Case $nMsg = $Label[0][0] To $Label[UBound($Label,1)-1][UBound($Label,2)-1]
            While _IsPressed("01", $dll) = 1 ;  добавил
                $pos = MouseGetPos() ;  добавил
                $x = Ceiling($pos[0]/$CellSize)-1 ;  добавил
                $y = Ceiling(($pos[1]-17)/$CellSize)-1 ;  добавил

                Select ; переделал
                    Case GUICtrlRead($radio1) = $GUI_CHECKED
                        GUICtrlSetData($Label[$x][$y], 100000)
                        GUICtrlSetBkColor($Label[$x][$y], 0x000000)
                    Case GUICtrlRead($radio2) = $GUI_CHECKED
                        GUICtrlSetData($Label[$x][$y], 99999)
                        GUICtrlSetBkColor($Label[$x][$y], 0xFFFFFF)
                EndSelect
            WEnd

		Case $Button2
				Local $temp ;сюда читаем текущее состоание поля которое проверяем.
				$sFile = @ScriptDir & "\map_b.au3"
				$file = FileOpen($sFile, 1)
				FileWriteLine($file, "Global $GeoData[" & $xMax+1 & "][" & $yMax+1 & "] = [ _" )
				For $x = 0 To $xMax
					FileWrite($file, "[")
					For $y = 0 To $yMax
						Local $temp = GUICtrlRead($Label[$x][$y])
						If $temp = 100000 Then $GeoData[$x][$y] = 100255 ;непроходимо
						If $temp = 99999 Then $GeoData[$x][$y] = 100254 ;проходимо
						If $temp = 3 Then $GeoData[$x][$y] = 100253 ;старт
						If $temp = 10004 Then $GeoData[$x][$y] = 0	 ;финиш
						FileWrite($file, $GeoData[$x][$y])
						If $y < $yMax Then FileWrite($file, ",")
					Next
					FileWrite($file, "]" )
					If $x < $xMax Then FileWriteLine($file, ", _")
				Next
				FileWriteLine($file, "]")
				FileClose($file)
	EndSwitch
WEnd

DllClose($dll) ;  добавил
В качестве примера я брал вот эту картинку.
http://autoit-script.ru/index.php?action=dlattach;topic=4375.0;attach=1568;image
Смещения в скрипте привязаны именно к ней
Код:
$color = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, 33+$x*8, 55+$y*8),6)


2. Редактор, он же тестовая среда. В него затягивается уже созданный массив карты. Карту можно редактировать и сохранить опять же в файл .au3
Функции поиска пути и движения по нему объеденены в одну.
Самое главное: функция GetGeoData полностью отвязана от GUI. В таком виде она готова к использованию в скрипте бота.
Почему её нельзя вынести в отдельную библиотеку? Потому что она использует функции реального бота - получения текущих координат Get_position и движение Go_to_point. Эти функции могут быть написаны только для конкретного случая. В этом примере стоят заглушки, работающие с GUI.
Код:
#include <GDIP.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Math.au3>
#Include <Array.au3>
#include <Misc.au3> ;  добавил

Global Const $stena = 100255, $prohod = 100254
Global $CurrentX, $CurrentY
#include <Map_b.au3>
Global $yMax = UBound($GeoData,2), $xMax = UBound($GeoData,1)
Global $Label[$xMax][$yMax]
$xMax -= 1
$yMax -= 1

Global $CellSize = 8
Global $Form1 = GUICreate("Map Editor", $xMax*$CellSize+120, $yMax*$CellSize+40)
Global $Radio1 = GUICtrlCreateRadio("Не проходимый", 0, 0, 101, 17)
Global $Radio2 = GUICtrlCreateRadio("Проходимый", 105, 0, 89, 17)
Global $Radio3 = GUICtrlCreateRadio("Старт", 195, 0, 53, 17)
Global $Radio4 = GUICtrlCreateRadio("Финиш", 252, 0, 59, 17)
Global $Radio5 = GUICtrlCreateRadio("Edit", 320, 0, 59, 17)

For $y = 0 To $yMax
	For $x = 0 To $xMax
		Switch $GeoData[$x][$y]
			Case $stena
				$color = 0x000000
			Case $prohod
				$color = 0xFFFFFF
			Case Else
				$color = 0x0000FF
		EndSwitch
		$Label[$x][$y] = GUICtrlCreateLabel(99999, $x*$CellSize, $y*$CellSize+17, $CellSize, $CellSize, $WS_BORDER)
		GUICtrlSetColor(-1, $color)
		GUICtrlSetBkColor(-1, $color)
	Next
Next
Global $Button1 = GUICtrlCreateButton("Start", $xMax*$CellSize+30, 20, 75, 25)
Global $Button2 = GUICtrlCreateButton("Save map", $xMax*$CellSize+30, 60, 75, 25)
GUISetState(@SW_SHOW)

Dim $dll = DllOpen("user32.dll") ;  добавил
AutoItSetOption("MouseCoordMode", 2) ;  добавил
$x_to_go = 0
$y_to_go = 0

While 1
	Local $nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $nMsg = 3	 To 6
			;
		Case $nMsg = $Label[0][0] To $Label[UBound($Label,1)-1][UBound($Label,2)-1]
           While _IsPressed("01", $dll) = 1 ;  добавил
                $pos = MouseGetPos() ;  добавил
                $x = Ceiling($pos[0]/$CellSize)-1 ;  добавил
                $y = Ceiling(($pos[1]-17)/$CellSize)-1 ;  добавил

                Select ; переделал
                    Case GUICtrlRead($radio1) = $GUI_CHECKED
                        GUICtrlSetData($Label[$x][$y], 100000)
                        GUICtrlSetBkColor($Label[$x][$y], 0x000000)
                        ;GUICtrlSetColor($Label[$x][$y], 0xFFFFFF)
                    Case GUICtrlRead($radio2) = $GUI_CHECKED
                        GUICtrlSetData($Label[$x][$y], 99999)
                        GUICtrlSetBkColor($Label[$x][$y], 0xFFFFFF)
                        ;GUICtrlSetColor($Label[$x][$y], 0xFFFFFF)
                    Case GUICtrlRead($radio3) = $GUI_CHECKED
						$CurrentX = $x
						$CurrentY = $y
                        GUICtrlSetData($Label[$x][$y], 3)
                        GUICtrlSetBkColor($Label[$x][$y], 0x00FF00)
                        ;GUICtrlSetColor($Label[$x][$y], 0x00FF00)
                    Case GUICtrlRead($radio4) = $GUI_CHECKED
						If $GeoData[$x][$y] = $prohod Then
							$point_to_go = $prohod
							$x_to_go = $x
							$y_to_go = $y
						Else
							$point_to_go = $GeoData[$x][$y]
						EndIf
                        GUICtrlSetData($Label[$x][$y], 10004)
                        GUICtrlSetBkColor($Label[$x][$y], 0xFF0000)
                        ;GUICtrlSetColor($Label[$x][$y], 0xFF0000)
                    Case GUICtrlRead($radio5) = $GUI_CHECKED
						$geopoint = InputBox("тип клетки","Введите новое значение клетки",$GeoData[$x][$y])
						If $geopoint <> "" Then
							$GeoData[$x][$y] = Number($geopoint)
							GUICtrlSetData($Label[$x][$y], 10004)
							GUICtrlSetBkColor($Label[$x][$y], 0x80FF80)
							;GUICtrlSetColor($Label[$x][$y], 0xFF0000)
						EndIf
                EndSelect
            WEnd


		Case $Button1
			GetGeoData($GeoData,$point_to_go,$x_to_go,$y_to_go)
		Case $Button2
				Local $temp ;сюда читаем текущее состоание поля которое проверяем.
				$sFile = @ScriptDir & "\map"&@MON&@MDAY&".au3"
				$file = FileOpen($sFile, 1)
				FileWriteLine($file, "Global $GeoData[" & $xMax+1 & "][" & $yMax+1 & "] = [ _" )
				For $x = 0 To $xMax
					FileWrite($file, "[")
					For $y = 0 To $yMax
						FileWrite($file, $GeoData[$x][$y])
						If $y < $yMax Then FileWrite($file, ",")
					Next
					FileWrite($file, "]" )
					If $x < $xMax Then FileWriteLine($file, ", _")
				Next
				FileWriteLine($file, "]")
				FileClose($file)
	EndSwitch
WEnd

DllClose($dll) ;  добавил


Func GetGeoData($GeoMap,$stop_type,$x_for_empty = $CurrentX, $y_for_empty = $CurrentY)
	Local $temp ;сюда читаем текущее состоание поля которое проверяем.
	Local $start = 0, $Ni = 0, $Nk = ($xMax+1)*($yMax+1)-1
	Local $position = Get_position()
	$GeoMap[$position[0]][$position[1]] = 100253
	If $stop_type = $prohod Then
		$GeoMap[$x_for_empty][$y_for_empty] = 0
	Else
		For $x = 0 To $xMax
			For $y = 0 To $yMax
				If $GeoMap[$x][$y] = $stop_type Then $GeoMap[$x][$y] = 0
			Next
		Next
	EndIf

	While $Ni < $Nk
		For $y = 0 To $yMax Step 1
			For $x = 0 To $xMax Step 1
				If $GeoMap[$x][$y] = $Ni Then
					For $i = -1 To 1
						If $x+$i<0 Then ContinueLoop
						If $x+$i>$xMax Then ContinueLoop
						For $j = -1 To 1
							If $y+$j<0 Then ContinueLoop
							If $y+$j>$yMax Then ContinueLoop
							If $GeoMap[$x+$i][$y+$j] = $prohod Then
								$GeoMap[$x+$i][$y+$j] = $Ni+1
								GUICtrlSetData($Label[$x+$i][$y+$j], "'")
								GUICtrlSetColor($Label[$x+$i][$y+$j], 0x000000)
							EndIf
							If $GeoMap[$x+$i][$y+$j] = 100253 Then
								ToolTip("путь построен",0,0)
								$CurrentX = $x + $i
								$CurrentY = $y + $j
								ExitLoop(5)
							EndIf
						Next
					Next
				EndIf
			Next
		Next
		$Ni = $Ni+1
		Sleep(100)
	WEnd
	If $Ni = $Nk Then
		ToolTip("путь не найден")
		SetError(1)
		Return 0
	EndIf

	Local $kletki[9]

	While 1

		$position = Get_position()
		$x = $position[0]
		$y = $position[1]

		For $i=0 To 8
			$kletki[$i] = $stena
		Next
		For $i = -1 To 1
			If $x+$i<0 Then ContinueLoop
			If $x+$i>$xMax Then ContinueLoop
			For $j = -1 To 1
				If $y+$j<0 Then ContinueLoop
				If $y+$j>$yMax Then ContinueLoop
				$kletki[4 + $j*3 + $i] = $GeoMap[$x+$i][$y+$j]
			Next
		Next
		Switch _ArrayMinIndex($kletki)
			Case 0
				Go_to_point($x-1,$y-1)
			Case 1
				Go_to_point($x,$y-1)
			Case 2
				Go_to_point($x+1,$y-1)
			Case 3
				Go_to_point($x-1,$y)
			Case 5
				Go_to_point($x+1,$y)
			Case 6
				Go_to_point($x-1,$y+1)
			Case 7
				Go_to_point($x,$y+1)
			Case 8
				Go_to_point($x+1,$y+1)
			Case Else
				ToolTip("Пришли",0,0)
				ExitLoop
		EndSwitch
	WEnd
EndFunc

Func Go_to_point($gX, $gY)
	; заглушка
	; функция перемещения на координаты $gX, $gY
	$CurrentX = $gX
	$CurrentY = $gY
	GUICtrlSetBkColor($Label[$gX][$gY], 0x00FF00)
	GUICtrlSetColor($Label[$X][$Y], 0x00FF00)
EndFunc

Func Get_position()
	; заглушка
	; функция определения текущих координат
	Local $Res[2] = [$CurrentX,	$CurrentY]
	Return $Res
EndFunc
Ещё обучил бота ходить по диагонали. :smile:
Как видите не заблудился
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Есть тема про какую-то игру, не помню точно, там вроде алгоритм применялся поиска пути. может даже и этот :smile:
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Я в одного своего бота прикрутил. Сейчас тестируется.
Там ещё прикол в том что помимо стенок и проходов я ставлю на карте объекты с другим кодом (у меня от 100300 и выше). И на карте у меня несколько однотипных объектов (то есть код клетки у них одинаковый). И когда нужно прийти к такому объекту на ремонт или дозаправку, то путь прокладывается к ближаёшему объекту - такой вот волновой алгоритм.
:smile:
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Вот так будет лучше работать, в случае попадания мимо поля.

Код:
#include <GDIP.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Math.au3>
#include <Color.au3>
#include <File.au3>
#include <Misc.au3> ;  добавил

_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\снимок.JPG')
$iWidth = _GDIPlus_ImageGetWidth($hImage)
$iHeight = _GDIPlus_ImageGetHeight($hImage)
$iBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($iBitmap)

Global $Form1 = GUICreate("Map Editor", 701, 801)
Global $Radio1 = GUICtrlCreateRadio("Не проходимый", 0, 0, 101, 17)
Global $Radio2 = GUICtrlCreateRadio("Проходимый", 105, 0, 89, 17)
Global $CellSize = 8
Global $Label[53][60]
Global $yMax = UBound($Label,2), $xMax = UBound($Label,1)
Global $GeoData[$xMax][$yMax]
$xMax -= 1
$yMax -= 1

For $y = 0 To $yMax Step 1
    For $x = 0 To $xMax Step 1
        $Label[$x][$y] = GUICtrlCreateLabel(99999, $x*$CellSize, $y*$CellSize+17, $CellSize, $CellSize, $WS_BORDER)
        $color = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, 33+$x*8, 55+$y*8),6)
        GUICtrlSetColor(-1, $color)
        GUICtrlSetBkColor(-1, $color)
        $RGBColor = _ColorGetRGB( $color )
        If $RGBColor[0] < 10 And $RGBColor[1] < 10 And $RGBColor[2] < 10 Then GUICtrlSetData($Label[$x][$y], 100000)
    Next
Next
Global $Button1 = GUICtrlCreateButton("Start", 615, 10, 75, 25)
Global $Button2 = GUICtrlCreateButton("Save map", 615, 40, 75, 25)
GUISetState(@SW_SHOW)

Dim $dll = DllOpen("user32.dll") ;  добавил
AutoItSetOption("MouseCoordMode", 2) ;  добавил

While 1
    Local $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $nMsg = 3   To 6
            ;
         Case $nMsg = $Label[0][0] To $Label[UBound($Label,1)-1][UBound($Label,2)-1]
            While _IsPressed("01", $dll) = 1 ;  добавил
                $pos = MouseGetPos() ;  добавил
                $x = Ceiling($pos[0]/$CellSize)-1 ;  добавил
                $y = Ceiling(($pos[1]-17)/$CellSize)-1 ;  добавил
				If $x > UBound($Label,1)-1 Or $x < 0 Then
					ExitLoop
				EndIf
				If $y > UBound($Label,2)-1 Or $y < 0 Then
					ExitLoop
				EndIf
                Select ; переделал
                    Case GUICtrlRead($radio1) = $GUI_CHECKED
                        GUICtrlSetData($Label[$x][$y], 100000)
                        GUICtrlSetBkColor($Label[$x][$y], 0x000000)
                    Case GUICtrlRead($radio2) = $GUI_CHECKED
                        GUICtrlSetData($Label[$x][$y], 99999)
                        GUICtrlSetBkColor($Label[$x][$y], 0xFFFFFF)
                EndSelect
            WEnd

        Case $Button2
                Local $temp ;сюда читаем текущее состоание поля которое проверяем.
                $sFile = @ScriptDir & "\map_b.au3"
                $file = FileOpen($sFile, 1)
                FileWriteLine($file, "Global $GeoData[" & $xMax+1 & "][" & $yMax+1 & "] = [ _" )
                For $x = 0 To $xMax
                    FileWrite($file, "[")
                    For $y = 0 To $yMax
                        Local $temp = GUICtrlRead($Label[$x][$y])
                        If $temp = 100000 Then $GeoData[$x][$y] = 100255 ;непроходимо
                        If $temp = 99999 Then $GeoData[$x][$y] = 100254 ;проходимо
                        If $temp = 3 Then $GeoData[$x][$y] = 100253 ;старт
                        If $temp = 10004 Then $GeoData[$x][$y] = 0   ;финиш
                        FileWrite($file, $GeoData[$x][$y])
                        If $y < $yMax Then FileWrite($file, ",")
                    Next
                    FileWrite($file, "]" )
                    If $x < $xMax Then FileWriteLine($file, ", _")
                Next
                FileWriteLine($file, "]")
                FileClose($file)
    EndSwitch
WEnd

DllClose($dll) ;  добавил
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Может кому пригодится... Переделал чуток код. Расширил поле. Сделал независимую функцию поиска пути. При такой схеме перестало тормозить, когда рисуешь карту.
Код:
#include <GDIP.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Math.au3>
#include <Color.au3>
#include <File.au3>
#include <Misc.au3>
#include <Array.au3>

If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)

Opt("GUIOnEventMode", 1)
Opt('MustDeclareVars', 1)
Opt("TrayIconHide", 0)
Opt("MouseCoordMode", 2)

Global $Label[80][80],$CellSize = 5, $Data = 1
Global $SaveMap,$LoadMap,$Color='0x000000',$yMax = UBound($Label,2), $xMax = UBound($Label,1),$GeoData[$xMax][$yMax]
Global $GUI,$Stena,$Prohod,$Start,$Finish,$bStart
$xMax -= 1
$yMax -= 1

GUI()
Func GUI()
Local $RGBColor
$GUI = GUICreate("Map Editor", 500, 420)
$Stena = GUICtrlCreateRadio("Стена", 0, 0, 101, 17)
$Prohod = GUICtrlCreateRadio("Проход", 105, 0, 89, 17)
$Start = GUICtrlCreateRadio("Старт", 210,0,100,17)
$Finish = GUICtrlCreateRadio("Финиш", 315,0,100,17)

$SaveMap=GUICtrlCreateButton("Save map",410,30,60)
GUICtrlSetOnEvent(-1, "SaveMap")
$bStart=GUICtrlCreateButton("Start",410,60,60)
GUICtrlSetOnEvent(-1, "Start")
$LoadMap=GUICtrlCreateButton("Load map",410,90,60)
GUICtrlSetOnEvent(-1, "LoadMap")
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN,"Mouse1")
GUISetOnEvent($GUI_EVENT_SECONDARYDOWN,"Mouse2")

_GDIPlus_Startup()
Local $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\map.JPG')
Local $iWidth = _GDIPlus_ImageGetWidth($hImage)
Local $iHeight = _GDIPlus_ImageGetHeight($hImage)
Local $iBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($iBitmap)

For $y = 0 To $yMax Step 1
    For $x = 0 To $xMax Step 1
        $Label[$x][$y] = GUICtrlCreateLabel(1, $x*$CellSize, $y*$CellSize+17, $CellSize, $CellSize, $WS_BORDER)
        $Color = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, 33+$x*7, 55+$y*7),6)
		GUICtrlSetData($Label[$x][$y], 0)	
        GUICtrlSetColor(-1, 0xFFFFFF)
        GUICtrlSetBkColor(-1, 0xFFFFFF)
    Next
Next

LoadMap() ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	GUISetOnEvent($GUI_EVENT_CLOSE, "GUIExit")
    GUISetState()
While 1
	Sleep(1000)
WEnd
EndFunc
Func GUIExit()
	Exit
EndFunc
Func Mouse1()
	Local $pos,$x,$y
	Do
        $pos = MouseGetPos()
		$x = Ceiling($pos[0]/$CellSize)-1
        $y = Ceiling(($pos[1]-17)/$CellSize)-1
		If $x > UBound($Label,1)-1 Or $x < 0 Then
			ExitLoop
		EndIf
		If $y > UBound($Label,2)-1 Or $y < 0 Then
			ExitLoop
		EndIf
        Select
            Case GUICtrlRead($Prohod) = $GUI_CHECKED
                GUICtrlSetData($Label[$x][$y], 0)			; Проход
                GUICtrlSetBkColor($Label[$x][$y], 0xFFFFFF)	; Проход
            Case GUICtrlRead($Stena) = $GUI_CHECKED
				GUICtrlSetData($Label[$x][$y], 1)			; Стена
                GUICtrlSetBkColor($Label[$x][$y], 0x000000)	; Стена
			Case GUICtrlRead($Start) = $GUI_CHECKED
                GUICtrlSetData($Label[$x][$y], 4)
                GUICtrlSetBkColor($Label[$x][$y], 0x00FF00)
			Case GUICtrlRead($Finish) = $GUI_CHECKED
                GUICtrlSetData($Label[$x][$y], 5)
                GUICtrlSetBkColor($Label[$x][$y], 0xFF0000)
        EndSelect
		Sleep(10)
	Until Not _IsPressed("01")
	ToolTip("")
EndFunc
Func Mouse2()
	Local $pos,$x,$y
	Do
        $pos = MouseGetPos()
		$x = Ceiling($pos[0]/$CellSize)-1
        $y = Ceiling(($pos[1]-17)/$CellSize)-1
		If $x > UBound($Label,1)-1 Or $x < 0 Then
			ExitLoop
		EndIf
		If $y > UBound($Label,2)-1 Or $y < 0 Then
			ExitLoop
		EndIf
		GUICtrlSetData($Label[$x][$y], 1)				; Стена
        GUICtrlSetBkColor($Label[$x][$y], 0x000000)		; Стена
		Sleep(10)
	Until Not _IsPressed("02")
	ToolTip("")
EndFunc
Func SaveMap()
	Local $txMax = UBound($Label,1)-1,$tyMax = UBound($Label,2)-1
	GUICtrlSetState($SaveMap, $GUI_DISABLE)
	Local $File = @ScriptDir & "\map_geodata.txt"
	FileDelete($File)
    For $x = 0 To $txMax
        For $y = 0 To $tyMax
            $GeoData[$x][$y] = GUICtrlRead($Label[$x][$y])
			ToolTip($GeoData[$x][$y])
			GUICtrlSetData($SaveMap,"  "&$x&"%  ")
        Next
    Next
	GUICtrlSetData($SaveMap,"  99%  ")
	_Array4File($File,$GeoData)
	GUICtrlSetState($SaveMap, $GUI_ENABLE)
	GUICtrlSetData($SaveMap,"Save map")
EndFunc
Func LoadMap()
	Local $txMax = UBound($Label,1)-1,$tyMax = UBound($Label,2)-1
	Local $File = @ScriptDir & "\map_geodata.txt"
	If Not FileExists($File) Then Return 0
	GUICtrlSetState($LoadMap, $GUI_DISABLE)
	$GeoData=_File4Array($File)
	ReDim $GeoData[$txMax+1][$tyMax+1]
    For $y = 0 To $txMax
        For $x = 0 To $txMax
			Select
				Case $GeoData[$y][$x]=0
					GUICtrlSetData($Label[$x][$y], 0)			; Проход
					GUICtrlSetBkColor($Label[$x][$y], 0xFFFFFF)	; Проход
				Case $GeoData[$y][$x]=1
					GUICtrlSetData($Label[$x][$y], 1)			; Стена
					GUICtrlSetBkColor($Label[$x][$y], 0x000000)	; Стена
				Case $GeoData[$y][$x]=4
					GUICtrlSetData($Label[$x][$y], 4)
					GUICtrlSetBkColor($Label[$x][$y], 0x00FF00)
				Case $GeoData[$y][$x]=5
					GUICtrlSetData($Label[$x][$y], 5)
					GUICtrlSetBkColor($Label[$x][$y], 0xFF0000)
			EndSelect
        Next
    Next
	GUICtrlSetState($LoadMap, $GUI_ENABLE)
	GUICtrlSetData($LoadMap,"Load map")
EndFunc
Func Start()
	GUICtrlSetState($bStart, $GUI_DISABLE)
	Local $ttStart[2]=[0,0],$ttFinish[2]=[0,0],$temp
    For $x = 0 To $xMax
        For $y = 0 To $yMax
            $GeoData[$x][$y] = GUICtrlRead($Label[$x][$y])
			If $GeoData[$x][$y]=4 Then Local $ttStart[2]=[$x,$y]
			If $GeoData[$x][$y]=5 Then Local $ttFinish[2]=[$x,$y]
		Next
    Next
	$temp=AnalysisTravel($GeoData,$ttStart,$ttFinish)
	_ArrayDisplay($temp)
	GUICtrlSetState($bStart, $GUI_ENABLE)
EndFunc
Func AnalysisTravel($GeoMap,$tStart,$tFinish)
	Local $txMax = UBound($GeoMap,1)-1, $tyMax = UBound($GeoMap,2)-1
	Local $t2=Round($txMax*$tyMax/1.5)
    Local $t1=10
	$GeoMap[$tStart[0]][$tStart[1]]=$t1
	Local $tX=0,$tY=0,$kletki[9]

Do
	ToolTip($t1)
	For $y = 0 To $tyMax Step 1
		For $x = 0 To $txMax Step 1
			If $GeoMap[$x][$y]=$t1  Then
				For $i = -1 To 1 Step 2
					If $x+$i<0 Then ContinueLoop
					If $x+$i>$txMax Then ContinueLoop
					If $GeoMap[$x+$i][$y] = 0 Then
						$GeoMap[$x+$i][$y] = $t1+1
						GUICtrlSetBkColor($Label[$x+$i][$y], 0x0066CC)
					EndIf
					If $GeoMap[$x+$i][$y] = $GeoMap[$tFinish[0]][$tFinish[1]] Then
						MsgBox(0,0,"Start found!")
						$tX = $x+$i
						$tY = $y
						ExitLoop(4)
					EndIf
				Next
				For $i = -1 To 1 Step 2
					If $y+$i<0 Then ContinueLoop
					If $y+$i>$tyMax Then ContinueLoop
					If $GeoMap[$x][$y+$i] = 0 Then
						$GeoMap[$x][$y+$i] = $t1+1
						GUICtrlSetBkColor($Label[$x][$y+$i], 0x0066CC)
					EndIf
					If $GeoMap[$x][$y+$i] = $GeoMap[$tFinish[0]][$tFinish[1]] Then
						MsgBox(0,0,"Start found!")
						$tX = $x
						$tY = $y+$i
						ExitLoop(4)
					EndIf
				Next
			EndIf
		Next
	Next
	$t1+=1
Until $t1=$t2
ToolTip("")
If $t1=$t2 Then
	ToolTip("путь не найден")
	SetError(1)
	Return 0
EndIf

Local $tt=-1
Local $Return[1][2]
    While 1
		$tt+=1
		If $tt > 0 Then ReDim $Return[$tt+1][2]

        $x = $tX
        $y = $tY
		For $i=0 To 8
            $kletki[$i] = $t2
        Next
        For $i = -1 To 1
            If $x+$i<0 Then ContinueLoop
            If $x+$i>$txMax Then ContinueLoop
            For $j = -1 To 1
                If $y+$j<0 Then ContinueLoop
                If $y+$j>$tyMax Then ContinueLoop
				If $GeoMap[$x+$i][$y+$j] = 0 Or $GeoMap[$x+$i][$y+$j] = 1  Or $GeoMap[$x+$i][$y+$j] = 5 Then $GeoMap[$x+$i][$y+$j] = $t2
                $kletki[4 + $j*3 + $i] = $GeoMap[$x+$i][$y+$j]
            Next
        Next
        Switch _ArrayMinIndex($kletki)
			Case 0
				$tX = $x-1
				$tY = $y-1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 1
				$tX = $x
				$tY = $y-1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 2
				$tX = $x+1
				$tY = $y-1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 3
				$tX = $x-1
				$tY = $y
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 5
				$tX = $x+1
				$tY = $y
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 6
				$tX = $x-1
				$tY = $y+1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 7
				$tX = $x
				$tY = $y+1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 8
				$tX = $x+1
				$tY = $y+1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case Else
                ToolTip("Пришли")
				ReDim $Return[$tt][2]
				Local $t[UBound($Return,1)][2]
				For $i=0 To UBound($Return,1)-1
					$t[UBound($Return,1)-1-$i][0]=$Return[$i][0]
					$t[UBound($Return,1)-1-$i][1]=$Return[$i][1]
				Next
				Return $t
		EndSwitch
    WEnd
EndFunc
Func _File4Array($lFileDir,$lSection="Base")
;-----------------------------------------------------------------------------------
Local $iUb2 = 2
Dim $aSection = IniReadSection($lFileDir, $lSection)
If @error Then
	Return @error
EndIf
														;Author: "madmasles"
Dim $aResult[$aSection[0][0]][$iUb2]
For $i = 0 To $aSection[0][0] - 1
    Local $aTemp = StringSplit($aSection[$i + 1][1], '|')
    If $iUb2 < $aTemp[0] Then
        $iUb2 = $aTemp[0]
        ReDim $aResult[$aSection[0][0]][$iUb2]
    EndIf
    For $j = 0 To $aTemp[0] - 1
        $aResult[$i][$j] = $aTemp[$j + 1]
    Next
Next
Return $aResult
;----------------------------------------------------------------------------------
EndFunc
Func _Array4File($lFileDir,$Array4File,$lSection='Base')
	If Not IsArray($Array4File) Then
		Return @error
	EndIf
	FileOpen($lFileDir,1)
	FileWrite($lFileDir,"[Base]"&@CRLF)
	For $j=0 To UBound($Array4File,2)-1
		FileWrite($lFileDir,$j&"=")
		For $i=0 To UBound($Array4File,1)-1
			FileWrite($lFileDir,$Array4File[$i][$j]&"|")
		Next
		FileWrite($lFileDir,@CRLF)
	Next
	FileClose($lFileDir)
EndFunc
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Dellroc,
ты ж идёшь от финиша к старту. :rofl:

Ну, можно закрыть глаза на то что не умеет искать путь по диагонали, но то что произошло урезание количества точек финиша, по-моему серьёзный шаг назад.
Если скрипт Belfigorа построит путь до ближаёшего финиша, то твой признаёт только один финиш.
:(


Добавлено:
Сообщение автоматически объединено:

Вот с массивом ты хорошо придумал.
Код:
$temp=AnalysisTravel($GeoData,$ttStart,$ttFinish)
    _ArrayDisplay($temp)

Надо чтобы функция поиска пути возвращала массив маршрута, а дальше уже можно делать с ним что угодно.
Переделаю бота своего. ;)
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Добавил хождение по диагонали и мелкие фиксы, а так же выкладываю карты, если лень рисовать.
Код:
#include <GDIP.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Math.au3>
#include <Color.au3>
#include <File.au3>
#include <Misc.au3>
#include <Array.au3>
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
Opt("GUIOnEventMode", 1)
Opt('MustDeclareVars', 1)
Opt("TrayIconHide", 0)
Opt("MouseCoordMode", 2)
HotKeySet("{ESC}", "GUIExit")
Global $Label[99][99],$CellSize = 5, $Data = 1
Global $SaveMap,$LoadMap,$Color='0x000000',$GeoData[UBound($Label,1)][UBound($Label,2)]
Global $GUI,$Stena,$Prohod,$Start,$Finish,$bStart
Global $Loadgui=0
_LoadGUI()
Func _LoadGUI()
$Loadgui = GUICreate("Loading", 60, 20, -1, -1, BitOR($WS_MINIMIZEBOX,$WS_POPUP,$WS_GROUP), BitOR($WS_EX_TOOLWINDOW,$WS_EX_TOPMOST,$WS_EX_WINDOWEDGE))
GUICtrlCreateLabel("Loading...", 5, 5, 60, 20)
GUISetBkColor(0xFFFFFF)
GUISetState(@SW_SHOW, $Loadgui)
EndFunc

GUI()
Func GUI()
Local $RGBColor,$yMax = UBound($Label,2)-1, $xMax = UBound($Label,1)-1
$GUI = GUICreate("Map Editor", 600, 520)
$Stena = GUICtrlCreateRadio("Стена", 0, 0, 101, 17)
$Prohod = GUICtrlCreateRadio("Проход", 105, 0, 89, 17)
$Start = GUICtrlCreateRadio("Старт", 210,0,100,17)
$Finish = GUICtrlCreateRadio("Финиш", 315,0,100,17)

$SaveMap=GUICtrlCreateButton("Save map",510,30,60)
GUICtrlSetOnEvent(-1, "SaveMap")
$bStart=GUICtrlCreateButton("Start",510,60,60)
GUICtrlSetOnEvent(-1, "Start")
$LoadMap=GUICtrlCreateButton("Load map",510,90,60)
GUICtrlSetOnEvent(-1, "LoadMap")
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN,"Mouse1")
GUISetOnEvent($GUI_EVENT_SECONDARYDOWN,"Mouse2")

_GDIPlus_Startup()
Local $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\map.JPG')
Local $iWidth = _GDIPlus_ImageGetWidth($hImage)
Local $iHeight = _GDIPlus_ImageGetHeight($hImage)
Local $iBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($iBitmap)

For $y = 0 To $yMax Step 1
    For $x = 0 To $xMax Step 1
        $Label[$x][$y] = GUICtrlCreateLabel(1, $x*$CellSize, $y*$CellSize+17, $CellSize, $CellSize, $WS_BORDER)
        $Color = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, 33+$x*7, 55+$y*7),6)
		GUICtrlSetData($Label[$x][$y], 0)	; Стена
        GUICtrlSetColor(-1, 0xFFFFFF)
        GUICtrlSetBkColor(-1, 0xFFFFFF)
    Next
Next

LoadMap() ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	GUISetOnEvent($GUI_EVENT_CLOSE, "GUIExit")
    GUISetState()
	GUIDelete($Loadgui)
While 1
	Sleep(1000)
WEnd
EndFunc
Func GUIExit()
	Exit
EndFunc
Func Mouse1()
	Local $pos,$x,$y
	Do
        $pos = MouseGetPos()
		$x = Ceiling($pos[0]/$CellSize)-1
        $y = Ceiling(($pos[1]-17)/$CellSize)-1
		If $x > UBound($Label,1)-1 Or $x < 0 Then
			ExitLoop
		EndIf
		If $y > UBound($Label,2)-1 Or $y < 0 Then
			ExitLoop
		EndIf
        Select
			Case GUICtrlRead($Prohod) = $GUI_CHECKED
                GUICtrlSetData($Label[$x][$y], 0)			; Проход
                GUICtrlSetBkColor($Label[$x][$y], 0xFFFFFF)	; Проход
            Case GUICtrlRead($Stena) = $GUI_CHECKED
				GUICtrlSetData($Label[$x][$y], 1)			; Стена
                GUICtrlSetBkColor($Label[$x][$y], 0x000000)	; Стена
			Case GUICtrlRead($Start) = $GUI_CHECKED
                GUICtrlSetData($Label[$x][$y], 4)
                GUICtrlSetBkColor($Label[$x][$y], 0x00FF00)
			Case GUICtrlRead($Finish) = $GUI_CHECKED
                GUICtrlSetData($Label[$x][$y], 5)
                GUICtrlSetBkColor($Label[$x][$y], 0xFF0000)
        EndSelect
		Sleep(10)
	Until Not _IsPressed("01")
EndFunc
Func Mouse2()
	Local $pos,$x,$y
	Do
        $pos = MouseGetPos()
		$x = Ceiling($pos[0]/$CellSize)-1
        $y = Ceiling(($pos[1]-17)/$CellSize)-1
		If $x > UBound($Label,1)-1 Or $x < 0 Then
			ExitLoop
		EndIf
		If $y > UBound($Label,2)-1 Or $y < 0 Then
			ExitLoop
		EndIf
		GUICtrlSetData($Label[$x][$y], 1)				; Стена
        GUICtrlSetBkColor($Label[$x][$y], 0x000000)		; Стена
		Sleep(10)
	Until Not _IsPressed("02")
EndFunc
Func SaveMap()
	Local $txMax = UBound($Label,1)-1,$tyMax = UBound($Label,2)-1
	GUICtrlSetState($SaveMap, $GUI_DISABLE)
	Local $File = @ScriptDir & "\map_geodata.txt"
	FileDelete($File)
    For $x = 0 To $txMax
        For $y = 0 To $tyMax
            $GeoData[$x][$y] = GUICtrlRead($Label[$x][$y])
			ToolTip($GeoData[$x][$y])
			GUICtrlSetData($SaveMap,"  "&$x&"%  ")
        Next
    Next
	GUICtrlSetData($SaveMap,"  99%  ")
	_Array4File($File,$GeoData)
	GUICtrlSetState($SaveMap, $GUI_ENABLE)
	GUICtrlSetData($SaveMap,"Save map")
EndFunc
Func LoadMap()
	Local $txMax = UBound($Label,1)-1,$tyMax = UBound($Label,2)-1
	Local $File = @ScriptDir & "\map_geodata.txt"
	If Not FileExists($File) Then Return 0
	GUICtrlSetState($LoadMap, $GUI_DISABLE)
	$GeoData=_File4Array($File)
	ReDim $GeoData[$txMax+1][$tyMax+1]
    For $y = 0 To $txMax
        For $x = 0 To $txMax
			Select
				Case $GeoData[$y][$x]=0
					GUICtrlSetData($Label[$x][$y], 0)			; Проход
					GUICtrlSetBkColor($Label[$x][$y], 0xFFFFFF)	; Проход
				Case $GeoData[$y][$x]=1
					GUICtrlSetData($Label[$x][$y], 1)			; Стена
					GUICtrlSetBkColor($Label[$x][$y], 0x000000)	; Стена
				Case $GeoData[$y][$x]=4
					GUICtrlSetData($Label[$x][$y], 4)
					GUICtrlSetBkColor($Label[$x][$y], 0x00FF00)
				Case $GeoData[$y][$x]=5
					GUICtrlSetData($Label[$x][$y], 5)
					GUICtrlSetBkColor($Label[$x][$y], 0xFF0000)
			EndSelect
        Next
    Next
	GUICtrlSetState($LoadMap, $GUI_ENABLE)
	GUICtrlSetData($LoadMap,"Load map")
EndFunc
Func Start()
	GUICtrlSetState($bStart, $GUI_DISABLE)
	Local $ttStart[2]=[0,0],$ttFinish[2]=[0,0],$temp
    For $x = 0 To UBound($Label,1)-1
        For $y = 0 To UBound($Label,2)-1
            $GeoData[$x][$y] = GUICtrlRead($Label[$x][$y])
			If $GeoData[$x][$y]=4 Then Local $ttStart[2]=[$x,$y]
			If $GeoData[$x][$y]=5 Then Local $ttFinish[2]=[$x,$y]
		Next
    Next
	$temp=AnalysisTravel($GeoData,$ttStart,$ttFinish)
	_ArrayDisplay($temp)
	GUICtrlSetState($bStart, $GUI_ENABLE)
EndFunc
Func AnalysisTravel($GeoMap,$tStart,$tFinish)
	Local $txMax = UBound($GeoMap,1)-1, $tyMax = UBound($GeoMap,2)-1
	Local $t2=Round($txMax*$tyMax/1.5)
    Local $t1=10,$t3=0,$t4=0
	$GeoMap[$tStart[0]][$tStart[1]]=$t1
	Local $tX=0,$tY=0,$kletki[9]

Do
	ToolTip($t1)
	For $y = 0 To $tyMax Step 1
		For $x = 0 To $txMax Step 1
			If $GeoMap[$x][$y]=$t1  Then
				$t3=0
				$t4=0
				For $i = -1 To 1 Step 2
					If $x+$i<0 Then ContinueLoop
					If $x+$i>$txMax Then ContinueLoop
					If $GeoMap[$x+$i][$y] = 0 Then
						$GeoMap[$x+$i][$y] = $t1+1
						GUICtrlSetBkColor($Label[$x+$i][$y], 0x0066CC)
						$t3+=1
					EndIf
					If $GeoMap[$x+$i][$y] = $GeoMap[$tFinish[0]][$tFinish[1]] Then
						MsgBox(0,0,"Start found!")
						$tX = $x+$i
						$tY = $y
						ExitLoop(4)
					EndIf
				Next
				For $i = -1 To 1 Step 2
					If $y+$i<0 Then ContinueLoop
					If $y+$i>$tyMax Then ContinueLoop
					If $GeoMap[$x][$y+$i] = 0 Then
						$GeoMap[$x][$y+$i] = $t1+1
						GUICtrlSetBkColor($Label[$x][$y+$i], 0x0066CC)
						$t3+=1
					EndIf
					If $GeoMap[$x][$y+$i] = $GeoMap[$tFinish[0]][$tFinish[1]] Then
						MsgBox(0,0,"Start found!")
						$tX = $x
						$tY = $y+$i
						ExitLoop(4)
					EndIf
				Next
				If $t3=$t4 Then
                    For $i = -1 To 1
                        If $x+$i<0 Then ContinueLoop
                        If $x+$i>$txMax Then ContinueLoop
                        For $j = -1 To 1
                            If $y+$j<0 Then ContinueLoop
                            If $y+$j>$tyMax Then ContinueLoop
                            If $GeoMap[$x+$i][$y+$j] = 0 Then
                                $GeoMap[$x+$i][$y+$j] = $t1+1
								GUICtrlSetBkColor($Label[$x+$i][$y+$j], 0x0066CC)
								$t3+=1
                            EndIf
                            If $GeoMap[$x+$i][$y+$j] = $GeoMap[$tFinish[0]][$tFinish[1]] Then
								MsgBox(0,0,"Start found!")
                                $tX = $x + $i
                                $tY = $y + $j
                                ExitLoop(5)
                            EndIf
                        Next
                    Next
				EndIf
			EndIf
		Next
	Next
	$t1+=1
Until $t1=$t2
ToolTip("")
If $t1=$t2 Then
	ToolTip("путь не найден")
	SetError(1)
	Return 0
EndIf

Local $tt=-1
Local $Return[1][2]
    While 1
		$tt+=1
		If $tt > 0 Then ReDim $Return[$tt+1][2]

        $x = $tX
        $y = $tY
		For $i=0 To 8
            $kletki[$i] = $t2
        Next
        For $i = -1 To 1
            If $x+$i<0 Then ContinueLoop
            If $x+$i>$txMax Then ContinueLoop
            For $j = -1 To 1
                If $y+$j<0 Then ContinueLoop
                If $y+$j>$tyMax Then ContinueLoop
				If $GeoMap[$x+$i][$y+$j] = 0 Or $GeoMap[$x+$i][$y+$j] = 1  Or $GeoMap[$x+$i][$y+$j] = 5 Then $GeoMap[$x+$i][$y+$j] = $t2
                $kletki[4 + $j*3 + $i] = $GeoMap[$x+$i][$y+$j]
            Next
        Next
        Switch _ArrayMinIndex($kletki)
			Case 0
				$tX = $x-1
				$tY = $y-1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 1
				$tX = $x
				$tY = $y-1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 2
				$tX = $x+1
				$tY = $y-1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 3
				$tX = $x-1
				$tY = $y
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 5
				$tX = $x+1
				$tY = $y
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 6
				$tX = $x-1
				$tY = $y+1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 7
				$tX = $x
				$tY = $y+1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case 8
				$tX = $x+1
				$tY = $y+1
				$Return[$tt][0]=$tX
				$Return[$tt][1]=$tY
				GUICtrlSetBkColor($Label[$tX][$tY], 0x00FF00)
            Case Else
                ToolTip("Пришли")
				ReDim $Return[$tt][2]
				Local $t[UBound($Return,1)][2]
				For $i=0 To UBound($Return,1)-1
					$t[UBound($Return,1)-1-$i][0]=$Return[$i][0]
					$t[UBound($Return,1)-1-$i][1]=$Return[$i][1]
				Next
				Return $t
		EndSwitch
    WEnd
EndFunc
Func _File4Array($lFileDir,$lSection="Base")
;-----------------------------------------------------------------------------------
Local $iUb2 = 2
Dim $aSection = IniReadSection($lFileDir, $lSection)
If @error Then
	Return @error
EndIf
														;Author: "madmasles"
Dim $aResult[$aSection[0][0]][$iUb2]
For $i = 0 To $aSection[0][0] - 1
    Local $aTemp = StringSplit($aSection[$i + 1][1], '|')
    If $iUb2 < $aTemp[0] Then
        $iUb2 = $aTemp[0]
        ReDim $aResult[$aSection[0][0]][$iUb2]
    EndIf
    For $j = 0 To $aTemp[0] - 1
        $aResult[$i][$j] = $aTemp[$j + 1]
    Next
Next
Return $aResult
;----------------------------------------------------------------------------------
EndFunc
Func _Array4File($lFileDir,$Array4File,$lSection='Base')
	If Not IsArray($Array4File) Then
		Return @error
	EndIf
	FileOpen($lFileDir,1)
	FileWrite($lFileDir,"[Base]"&@CRLF)
	For $j=0 To UBound($Array4File,2)-1
		FileWrite($lFileDir,$j&"=")
		For $i=0 To UBound($Array4File,1)-1
			FileWrite($lFileDir,$Array4File[$i][$j]&"|")
		Next
		FileWrite($lFileDir,@CRLF)
	Next
	FileClose($lFileDir)
EndFunc
 
Верх