Что нового

выход из цикла после полной проверки по массиву

running-frag

why me?
Сообщения
441
Репутация
60
Задача така. Есть массив, ну допустим (полностью не буду описывать)
Код:
...
$stClient[1][3] = True
...
$stClient[2][3] = False
...

и есть функция
Код:
Func _window_checkAllClients ()
	Local $_return = False
	
	While Not ($_return)
		
		For $i = 1 To 4
			If $stClient[$i][3] Then
				If _window_checkLocation ($stClient[$i][2], True, True) Then ; вот тут нужно изменять чекер $_return
			EndIf
		Next
		
	WEnd	
	
	Return True
EndFunc


Теперь задача.
Задача функции пробежать все элементы массива (ну в данный момент у нас получается только 4). На накоторых выполняется функция _window_checkLocation (), которая отдаёт True\False. Теперь чего хочется от этой функции. Нужно что бы мы вышли из цикла (While Not $_return) только тогда, когда все вызовы функции _window_checkLocation () отдали нам True. Если хотя бы один элемент отдал False - катаемся дальше по циклу.

Чего то кручу верчу нефига не получается.


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

Вот ещё вариант родил.
Код:
Func _window_checkAllClients ()
	Local $_result = True
	Local $_chr = 4 ; предпологается что в массиве будет всего четыре значения True
	Local $_sum = 0
	
	While True
		
		For $i = 1 To $_chr
			If $stClient[$i][3] Then
				_client_makeActive ($stClient[$i][1])
				If _window_checkLocation ($stClient[$i][2], True, True) Then $_sum += 1
					; вот тут нужно изменять чекер
			EndIf
		Next
		
		If $_sum = 4 Then ExitLoop
		
		$_sum = 0
	WEnd	
	
	Return True
EndFunc


Но это не подойдёт т.к. нам нужна будет ещё функция для определение количество $_chr (количество значений True из массива $stClient[$i][3]). А хочется без неё.


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

OffTopic:
Назвал тему не так, сейчас переименую.
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Сделайте функцию для проверки валидности всех элементов массива и вставьте в цикл, если эта функция вернёт 1 то выходим из цикла.

Например такая функция:

Код:
Func ValidArray(ByRef $aArray)
	If Not IsArray($aArray) Then
		Return -1
	EndIf	
	For $i = 1 To $aArray[0][0]
		If (Not $aArray[$i][3]) Then
			Return 0
		EndIf	
    Next
	Return 1
EndFunc
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Немного не понял как это работает. Ам, давай ещё раз расскажу смысл (я плохой оратор я вкусре ;D).

Есть массив (статически, т.е. мы его никак не будем менять) $stClient. Сколько у нас элементов в нём, неизвестно. Каждый элемент это массив (вложенный). Т.е. как описано выше $stClient[$i][3] это флаг, стоит ли нам делать проверку (выполнять нашу функцию) или нет.

Так вот мы запускаем цикл (While) и после проверям все элементы (получается только те что $stClient[$i][3] == True), если хотя бы один элемент нам отдал False (из _window_checkLocation ($stClient[$i][2], True, True)) тогда мы продолжаем цикл While (т.е. For добегает до конца своим ходом). А если же все элементы (те что _window_checkLocation ($stClient[$i][2], True, True)) отдали True - выходим из цикла (While).

Viktor1703 если ты именно об этом писал то плз напиши на моём примере, я не понял как это работает. :(
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Объясню на одномерном массиве

Код:
Dim $aTest[5] 
$aTest[0] = True
$aTest[1] = True
$aTest[2] = True
$aTest[3] = False
$aTest[4] = True

$i = 0

While 1
	If ValidArray($aTest) Then
		ExitLoop
	EndIf	
	ConsoleWrite($i & @CRLF)
	$i += 1
	If $i >= 500 Then
		$aTest[3] = True
	EndIf	
Wend	

Func ValidArray(ByRef $aArray)
	If Not IsArray($aArray) Then
		Return -1
	EndIf	
	For $i = 0 To UBound($aArray) -1
		If (Not $aArray[$i]) Then
			Return 0
		EndIf	
    Next
	Return 1
EndFunc


Ну или вот на двумерном массиве

Код:
Dim $aTest[6][4] 
$aTest[0][0] = UBound($aTest) - 1
$aTest[1][3] = True
$aTest[2][3] = True
$aTest[3][3] = True
$aTest[4][3] = False
$aTest[5][3] = True

$i = 0

While 1
	If ValidArray($aTest) Then
		ExitLoop
	EndIf	
	ConsoleWrite($i & @CRLF)
	$i += 1
	If $i >= 500 Then
		$aTest[4][3] = True
	EndIf	
Wend	

Func ValidArray(ByRef $aArray)
	If Not IsArray($aArray) Then
		Return -1
	EndIf	
	For $i = 1 To $aArray[0][0]
		If (Not $aArray[$i][3]) Then
			Return 0
		EndIf	
    Next
	Return 1
EndFunc
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Ну да, логика верна. Одно но, у нас $stClient не может быть изменён (в твоём случае это $aTest[5]). Т.е. это нужно создавать доп. массив, в который добавлять значения, а после искать в нём False.
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Ну если массив $stClient не может быть изменён и если при запуске скрипта в любом элементе массива $stClient[$i][3] стоит False то какой смысл его проверять

Нужно что бы мы вышли из цикла (While Not $_return) только тогда, когда все вызовы функции _window_checkLocation () отдали нам True. Если хотя бы один элемент отдал False - катаемся дальше по циклу.

Или я не правильно что - то понял :scratch:


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

Я понял что Вам нужно
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Viktor1703,
ИМХО, можно и без функции.
Код:
Dim $aTest[5] = [1, 1, 1, 0, 1]
$i = 0

While 1
	$iCountFalse = 0
	For $j = 0 To UBound($aTest) - 1
		If $aTest[$j] Then ContinueLoop
		$iCountFalse += 1
	Next
	ConsoleWrite($i & @TAB & $iCountFalse & @LF)
	$i += 1
	If $i >= 50 Then
		$aTest[3] = True
	EndIf
	If Not $iCountFalse Then ExitLoop
	Sleep(10)
WEnd
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Ну если так говоря то в массиве $stClient[$i][3] находится флаг, будем ли мы использывать данного чара (персонажа в игре, для бота). И я хочу делать проверки только по тем персонажам которые "включены" (имеют True значение). А всех остальных лесом...
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Вы это имели ввиду?

Код:
Func _window_checkAllClients ()
    Local $_result = True
    Local $_chr = 4
    Local $_len = 0 
    Local $_sum = 0
    
    While $_result
        For $i = 1 To $_chr
            If $stClient[$i][3] Then
				$_len += 1
                _client_makeActive ($stClient[$i][1])
                If _window_checkLocation ($stClient[$i][2], True, True) Then 
					$_sum += 1
				EndIf	
            EndIf
        Next
        If $_len == $_sum Then
			ExitLoop
		EndIf	
        $_len = 0
        $_sum = 0
    WEnd    
    
    Return True
EndFunc
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
да, тольк вот тут не сработает цикл
Код:
For $i = 1 To $_chr


в теории как то вот так получается (но скрипт не работает)

Код:
Func _window_checkAllClients ()
	Local $_check
	
	While True
		
		For $i = 1 To 4
			If $stClient[$i][3] Then
				
				_ArrayAdd ($_check, _window_checkLocation ($stClient[$i][2], True, True))
			EndIf
		Next
		
		;_ArrayDisplay ($_check)
		
		If Not (_ArraySearch ($_check, False)) Then ExitLoop ; если нету False
			
		$_check = "" ; затираем массив 
	WEnd	
	
	Return True
EndFunc
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Я уже исправил

madmasles, да, но с функцией для меня удобнее :smile:
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
увидел, но всё равно это будет работать только если мы знаем значение $_chr, а если нет? :stars:

madmasles походу близок к правде, сейчас перепишу проверю (сразу не увидел)

нет, ошибся, там не такой принцеп что хочется
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Вообще значение $_chr должно браться из размерности массива то есть $stClient[0][0] :blink:

OffTopic:
хотя не знаю как вообще выглядит скрипт и откуда берётся это значение :stars:
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Массив генерится из GUI. По сути мы можем там иметь от 1 до 100. Вариант конечно с доп. функцией, что б сначало пробегать узнавать сколько чаров имеют "True" и отдавать это значение в $_chr. Тогда всё красиво. Или другой вариант довести до ума, тот что "сохранять результаты в массиве и после в них искать False" (посл. мой пример с _ArraySearch()).


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

ВО! Коряво но работает, вот что я хотел.
Код:
Func _window_checkAllClients ()

	While True
		Dim $_check[1] = [0]
		
		For $i = 1 To 4
			If $stClient[$i][3] Then
				_ArrayAdd ($_check, _window_checkLocation ($stClient[$i][2], True, True))
			EndIf
		Next
		
		If _ArraySearch ($_check, False, 1) = -1 Then ExitLoop ; нету там False 
		
	WEnd	
	
	Return True
EndFunc



И то как то не очень красиво, но данный выход работает правильно.


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

Тема решена, спасибо всем кто приниман участвие. Ваши примеры натолкнули на мыслю. ;) Хотя всё же от "расчитать кол. активных персонажей" (те у которых True) не уйти :(
 
Верх