RoundChecker Posted December 19, 2017 Share Posted December 19, 2017 Hi everyone, I am trying to figure out the usage of Array in AutoIT, did read through: https://www.autoitscript.com/wiki/Arrays, and I can say it has helped tremendously, but I still remain with one question that I did not get declared from the WIKI. Below here I'll post a script and then after that I'll tell you what I'm trying to achieve. ;--EXAMPLE Local $c1 = 0xED1C24 Local $c2 = 0xF11C64 Local $c3 = 0x221C84 Local $a = PixelSearch(352,172,604, 235,$c1,10) Local $a1 = PixelSearch(352,172,604, 235,$c2,10) Local $a2 = PixelSearch(352,172,604, 235,$c3,10) Local $iMax = 3 Local $cArr[$iMax] = [$a, $a1, $a2] For $k = 0 to $iMax - 1 If isArray ($cArr[$k]) Then $cK = True Else $cK = False EndIf Next Consolewrite("Result: " & $cK & @LF) As you can see I got 6 variables. 3 Defines colors, and the other 3 from $a to $a2, are 3 arrays when used in the variable below where I define them in brackets; Local $cArr[$iMax] = [$a, $a1, $a2] When I am trying to use isArray(), it will only return true if all arrays (in this example it's 3 different colors within a set search) are found. My question here is, how can I make it return true if either one of them is found? In the example above I am using Quote If isArray ($cArr[$k]) which is a value from 0 to 3 - 1 as declared above, which will only return checking if 0, 1 and 2 is inArray, is there a way to check if 0, or 1 or 2 is inArray other than using Quote if isArray ($cArr[0]) or isArray ($cArr[1]) or isArray . . . Etc Link to comment Share on other sites More sharing options...
Floops Posted December 19, 2017 Share Posted December 19, 2017 Not sure if I understand your question completely but would the following work? $cK = False For $k = 0 to $iMax - 1 If isArray ($cArr[$k]) Then $cK = True EndIf Next Consolewrite("Result: " & $cK & @LF) Link to comment Share on other sites More sharing options...
RoundChecker Posted December 19, 2017 Author Share Posted December 19, 2017 No, you see it will only trigger "true" if all 3 arrays is in array when i use : If isArray ($cArr[$k]) Then My question here is that is there a possible way to trigger the true value if any of the 3 arrays triggers isArray? I have 3 arrays; $a $a1 $a2 Example: If $a is found and $a1 and $a2 isn't, it would still put $cK to true. In my case it only puts it to true IF all 3 arrays are found (In this example its just about finding a pixel) If i for example had 100 arrays and I wrote the code like this If isArray ($cArr[0]) or ($cArr[1]) or . . . . . . ($cArr[100]) Then It would trigger the true if any of those 100 arrays was sighted. - but if I use isArray($cArr[$k]) - then that will no longer be the case. I hope that cleared up any misunderstanding Link to comment Share on other sites More sharing options...
Deye Posted December 19, 2017 Share Posted December 19, 2017 what about: $cK = False For $k = 0 To $iMax - 1 If Not IsArray($cArr[$k]) Then ContinueLoop $cK = True ExitLoop Next RoundChecker 1 Link to comment Share on other sites More sharing options...
RoundChecker Posted December 19, 2017 Author Share Posted December 19, 2017 Hi, yes and thanks Deye. $cK = False For $k = 0 To $iMax - 1 If Not IsArray($cArr[$k]) Then ContinueLoop $cK = True ExitLoop Next Does work, but how do I return which of the 3 array values did trigger the $cK = True ? For example if I am going to further script it, I have to know which array was activated so I can tell it what to do next. As most of us do know that: pixelSearch Does return a value that can be referred to if it's a variable such as what I have in the example at the start of the post: $a = PixelSearch(352,172,604, 235,$c1,10) If we found that array then the X,Y could be accessed by: Mouseclick("left", $a[0],$a[1],1, 10) ;Click,X,Y,Amount of clicks, Speed But that is done by going to the root of the variable that formed the arrays, and that can be very troublesome to do every single array checking which one was activated after it found a positive from searching all. Such as: If isArray($cArr[0]) then Mouseclick("left", $a[0],$a[1],1, 10) Elseif isArray($cArr[1]) then Mouseclick("left", $a1[0],$a1[1],1, 10) Elseif . . . . . Etc EndIf If i'm going to do that example above for all the arrays (if i have way more than 3 of course) that's going to be a lot of if's. Is there another way to determine which of the arrays was found, to make the process shorter? Like finding the array that was activated and use mouse click directly after: $cK = False For $k = 0 To $iMax - 1 If Not IsArray($cArr[$k]) Then ContinueLoop $cK = True ExitLoop Next ^ In this case we do not know which one was activated, we just know that if any of them is present, then it puts $cK = true and we can't use $cArr[$k] to determine the position of the activated one. So in conclusion: What I'm trying to achieve is how to find which one was activated so it can be used in MouseClick and determine the coordinates by that. Thanks for your input, all of you btw. Link to comment Share on other sites More sharing options...
Deye Posted December 19, 2017 Share Posted December 19, 2017 Start the array with just an 0 so its not included it in the search as a valid return Global $cArr[4] = [0, $a, $a1, $a2] Local $inum = _find() If $inum >= 1 Then MouseClick("left", $cArr[$inum][0], $cArr[$inum][1], 1, 10) Func _find() For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop Return $k Next Return 0 EndFunc ;==>_find RoundChecker 1 Link to comment Share on other sites More sharing options...
RoundChecker Posted December 19, 2017 Author Share Posted December 19, 2017 Okay so starting the array with a 0 makes it not included in the search when it comes to if Not isArray, got it. Now I do not need Local $iMax = 3 anymore right? Or Should I do : Global $cArr[4] = [0, $a, $a1, $a2] Local $inum = _find() If $inum >= 1 Then MouseClick("left", $cArr[$inum][0], $cArr[$inum][1], 1, 10) Func _find() For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop Return $k Next Return 0 EndFunc ;==>_find To Local $iMax[4] Global $cArr[$iMax] = [0, $a, $a1, $a2] Global $T = $cArr[$iMax] - 1 Local $inum = _find() If $inum >= 1 Then MouseClick("left", $cArr[$inum][0], $cArr[$inum][1], 1, 10) Func _find() For $k = 1 To UBound($T) If Not IsArray($cArr[$k]) Then ContinueLoop Return $k Next Return 0 EndFunc ;==>_find For shorter reference to UBound later on? Thanks again for your input . Link to comment Share on other sites More sharing options...
RoundChecker Posted December 19, 2017 Author Share Posted December 19, 2017 I tried running both tests and even with changing things around, I ran the one you gave me and some stuff I came up with and we end up with this Quote ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.: If $inum >= 1 Then MouseClick("left", $cArr[$inum][0], $cArr[$inum][1], 1, 10) If $inum >= 1 Then MouseClick("left", ^ ERROR In the console read. I tried doing this: Local $inum = _find() If $inum >= 1 Then MouseClick("left", $cArr-1[$inum][0], $cArr-1[$inum][1], 1, 10) ; - 1 after $cArr But still with no luck, it return then: Quote ==> Subscript used on non-accessible variable.: If $inum >= 1 Then MouseClick("left", $cArr-1[$inum][0], $cArr-1[$inum][1], 1, 10) If $inum >= 1 Then MouseClick("left", $cArr-1^ ERROR Then finally I tried doing this right here: Global $iMax = 4 Global $cArr[$iMax] = [0, $a, $a1, $a2] For $T = 0 To $iMax - 1 Next Local $inum = _find() If $inum >= 1 Then MouseClick("left", $cArr-1[$inum][0], $cArr-1[$inum][1], 1, 10) Func _find() For $k = 1 To UBound($T) If Not IsArray($cArr[$k]) Then ContinueLoop Return $k Next Return 0 EndFunc ;==>_find It returns no errors but unfortunately it doesn't find anything either. Last but not least, I tried one final thing: Global $iMax = 4 Global $cArr[$iMax] = [0, $a, $a1, $a2] For $T = 0 To $iMax - 1 Next Local $inum = _find() If $inum >= 1 Then MouseClick("left", $cArr[$inum][0], $cArr[$inum][1], 1, 10) Else ConsoleWrite("Did not find anything." & @LF) EndIf Func _find() For $k = 1 To UBound($T) If Not IsArray($cArr[$k]) Then ContinueLoop Return $k Next Return 0 EndFunc ;==>_find And unfortunately ended with console: Quote Did not find anything. Link to comment Share on other sites More sharing options...
Deye Posted December 19, 2017 Share Posted December 19, 2017 Didn't expect that lol This should do : If $inum >= 1 Then Local $a = $cArr[$inum] MouseClick("left", $a[0], $a[1], 1, 10) EndIf RoundChecker 1 Link to comment Share on other sites More sharing options...
RoundChecker Posted December 19, 2017 Author Share Posted December 19, 2017 Local $inum = _find() If $inum >= 1 Then ConsoleWrite($inum & @LF) Local $cL = $cArr[$inum] ; note i changed the variable MouseClick("left", $cL[0], $cL[1], 1, 10) EndIf ^ This definitely does work, but remember we are searching several arrays, and if the : Quote $inum >= 1 Then more targets can appear on the array search, it did work, it went and clicked, but what happens to the other targets it does find? How do we define that? I used the example and tried out it worked fine, but when I added that it found 2 targets ( by changing the root search ) it only clicked on the first, never continued for the other, as if it only searches till it finds 1 then stops. That's cause of If Not IsArray($cArr[$k]) Then ContinueLoop this isn't it? it'll stop if one is if Not. So if it finds a target it returns the value and then done, I tried using console to check how many targets it found to debug the code and it comes up with "1". It seems like it only searches till it gets one positive value then stops, should we add in the code that it has to search all the arrays first? Maybe a "Do" and "until" would work? "Do . .. . Until (Max array) - 1 ? Link to comment Share on other sites More sharing options...
Deye Posted December 19, 2017 Share Posted December 19, 2017 (edited) Done: For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop Local $a = $cArr[$inum] MouseClick("left", $a[0], $a[1], 1, 10) Next Edited December 19, 2017 by Deye Link to comment Share on other sites More sharing options...
RoundChecker Posted December 19, 2017 Author Share Posted December 19, 2017 Thanks for all the input, oh trust me I've been trying to think and was testing a lot of stuff I usually never ask for help unless I need some other insight. Been trying to do several methods for 13 hours now. Sorry if this has been troublesome to you. So this For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop Local $a = $cArr[$inum] MouseClick("left", $a[0], $a[1], 1, 10) Next Makes us check the arrays and what is positive gets clicked until positive = 0? (Trying to understand the function to use the experience further on) Also I'm not getting the idea behind: Local $a = $cArr[$inum] That will be used within : Func _find() For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop Local $cL = $cArr[$inum] MouseClick("left", $cL[0], $cL[1], 1, 10) Next Return 0 EndFunc ;==>_find That's how it should be set up right? Cause having it set up like that returns errors. Quote Subscript used on non-accessible variable.: MouseClick("left", $cL[0], $cL[1], 1, 10) MouseClick("left", $cL^ ERROR Is it maybe because we are using the condition as local and not global? For some reason it's not getting the variable. I tried doing this, by actually making it know that [$inum] Local $a = PixelSearch(352,172,498, 251,0xED1C24,10) Local $a1 = PixelSearch(352,172,498, 251,0x880015,10) Local $a2 = PixelSearch(352,172,498, 251,0x231C24,10) Global $cArr[4] = [0, $a, $a1, $a2] Local $inum = _find() Func _find() For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop Return $k ;< Tried return here If $inum >= 1 Then Local $cL = $cArr[$inum] MouseClick("left", $cL[0], $cL[1], 1, 10) Else ConsoleWrite("Blabla") EndIf Return $k ;< Tried return here, and also removed both $k's. Next Return 0 EndFunc ;==>_find But still with no luck, am I doing something wrong here? Or did you not expect something again? - Looking at what you gave me here : For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop Local $a = $cArr[$inum] MouseClick("left", $a[0], $a[1], 1, 10) Next Does only make sense to me is if I have the code looking like this: Local $a = PixelSearch(352,172,498, 251,0xED1C24,10) Local $a1 = PixelSearch(352,172,498, 251,0x880015,10) Local $a2 = PixelSearch(352,172,498, 251,0x231C24,10) Global $cArr[4] = [0, $a, $a1, $a2] Local $inum = _find() Func _find() For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop Local $ad = $cArr[$inum] ;Note - I changed variable, $a to $ad. MouseClick("left", $ad[0], $ad[1], 1, 10) Return $k ;< Tried removing this line, same Error. Next Return 0 EndFunc ;==>_find But even with that we return with the error I stated above: Quote Subscript used on non-accessible variable.: MouseClick("left", $ad[0], $ad[1], 1, 10) MouseClick("left", $ad^ ERROR Did i set the code up wrong? Am I thinking wrong ? Or what's wrong here, I tried several methods, but it can't seem to reach [$inum] - And trust me I'm trying to think you can see that. It's just that I started array 13 hours ago, doing my best here. Link to comment Share on other sites More sharing options...
SlackerAl Posted December 19, 2017 Share Posted December 19, 2017 Your error is occurring as you have defined $ad as a single variable: 29 minutes ago, RoundChecker said: Local $ad = $cArr[$inum] ;Note - I changed variable, $a to $ad. You then try to access it as an array. But it is not an array, it is merely a copy of one element of an array. I suggest you define your variable outside of the loop, then assign values to it within your loop - AutoIt is tolerant to repeated declarations, but most languages are not. Problem solving step 1: Write a simple, self-contained, running, replicator of your problem. Link to comment Share on other sites More sharing options...
kaisies Posted December 19, 2017 Share Posted December 19, 2017 Your error is didn't use the loop variable to assign the nested arrays values to your temp variable, you used something that isn't declared: ` Local $ad = $cArr[$inum] ;Note - I changed variable, $a to $ad. Should Be: Local $ad = $cArr[$k] ;Note - I changed variable, $a to $ad. Alternatively, you can access nested arrays as such, without first assigning the to a temp variable: Local $a = PixelSearch(352,172,498, 251,0xED1C24,10) Local $a1 = PixelSearch(352,172,498, 251,0x880015,10) Local $a2 = PixelSearch(352,172,498, 251,0x231C24,10) Global $cArr[4] = [0, $a, $a1, $a2] Local $inum = _find() Func _find() For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop MouseClick("left",($cArr[$k])[0], ($cArr[$k])[1], 1, 10) Return $k ;< Tried removing this line, same Error. Next Return 0 EndFunc ;==>_find This is how you access those values, as $aArray[1][1] syntax is for 2d arrays Link to comment Share on other sites More sharing options...
RoundChecker Posted December 19, 2017 Author Share Posted December 19, 2017 This is the code I was given from Deye, it worked perfectly fine until our last change. This : Global $cArr[4] = [0, $a, $a1, $a2] local $inum = _func() If $inum >= 1 Then Local $da = $cArr[$inum] MouseClick("left", $da[0], $da[1], 1, 10) EndIf Func _find() For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop Return $k Next Return 0 EndFunc ;==>_find Works perfectly fine, but it only returns 1 value to : Local $a = $cArr[$inum] It clicks one target only as the loop stops when it finds the first target that it should return as a positive. What I'm trying to do is make the loop search all the arrays within $k = 1 to UBound($cArr) - 1 before it continues to return the value. Above we did define $inum that runs the function find, then after that it finds if array is positive then returns to $inum, then executes. But again as stated above, it only returns the first element it sees. For example: If i have 3 arrays, and it searched 1 and found nothing, then 2 and found something, it would stop the search, then goes and executes "if Inum" leaving out array 3 unsearched. Link to comment Share on other sites More sharing options...
kaisies Posted December 19, 2017 Share Posted December 19, 2017 (edited) If you put your loop/click inside a loop, with a return, that is the expected behavior. If you want it to click all elements of the array that exist as an array, there is no need for a function call. Local $a = PixelSearch(352,172,498, 251,0xED1C24,10) Local $a1 = PixelSearch(352,172,498, 251,0x880015,10) Local $a2 = PixelSearch(352,172,498, 251,0x231C24,10) Local $iTimesClicked Global $cArr[4] = [0, $a, $a1, $a2] For $k = 1 To UBound($cArr) - 1 If Not IsArray($cArr[$k]) Then ContinueLoop MouseClick("left",($cArr[$k])[0], ($cArr[$k])[1], 1, 10) Sleep(50) ;do something else here, Maybe increment a variable? $iTimesClicked += 1 Next Msgbox(0,'',"I found and Clicked " & $iTimesClicked & " Times!") Edited December 19, 2017 by kaisies RoundChecker 1 Link to comment Share on other sites More sharing options...
RoundChecker Posted December 19, 2017 Author Share Posted December 19, 2017 Well this is just an example for me to understand arrays while using functions that is linked from variables to arrays, in this example I used pixel search. I am trying to understand the possible ways of using arrays if it could also work with $a = If . .. . or $a = While . .. And so on. So to make it clear for EVERYONE here this is NOT about game automation. And kaisies to your reply thanks, but could you further explain why MouseClick("left",($cArr[$k])[0], ($cArr[$k])[1], 1, 10) Would click all the arrays, and not $cArr in general? why the $k there Does that return the value of what was given after searched? also 1 to UBound, what does 1 refer to in this example of the Arrays? Does that mean the first array? which is in this example [0,.] ? So it's not within the search, so basically 1 to UBound($arr) - 1 = 0 to ? - 1 So in conclusion : 1 to UBound ($cArr) < What is the $cArr here? is it All the arrays ? so the number (4) that we set up there? $cArr[4] To read it out 1 to UBound($cArr) - 1 = 0 to 4 - 1, correct? Link to comment Share on other sites More sharing options...
kaisies Posted December 19, 2017 Share Posted December 19, 2017 (edited) The [$k] is there because you are looping through an array, and autoit needs to know what index of the array to evaluate. It doesn't "click all the arrays". You can't do that. You need to loop through each, determine if it is an array (pixelsearch found it), and then click it. That's the point of the For loop. Sounds like you need to learn about For loops next (which go hand in hand with arrays). I don't know what you mean by return that value of what was given after searched. 1 Refers to Element 1 of Array $cArr. In this case, the result of your First pixelsearch, or $cArr[1]. $cArr is the variable $cArr... which has 4 elements. So For 1 to (4-1), or 1 to 3. Nested arrays are difficult to understand, AND difficult to look at, TBH. It is a poor example of learning arrays / learning for loops. A basic array would suit learning that much better. In this context of a PixelSearch though, it is probably the most ideal use. Perhaps this may help #include <Array.au3> Local $a = PixelSearch(352,172,498, 251,0xED1C24,10) Local $a1 = PixelSearch(352,172,498, 251,0x880015,10) Local $a2 = PixelSearch(352,172,498, 251,0x231C24,10) Local $iTimesClicked Global $cArr[4] = [0, $a, $a1, $a2] For $k = 1 To UBound($cArr) - 1 MsgBox(0,'',"Looping through array indexes. Searching index: " & $k) If Not IsArray($cArr[$k]) Then ContinueLoop _ArrayDisplay($cArr[$k],"Displaying the nested array in index: " & $k) MouseClick("left",($cArr[$k])[0], ($cArr[$k])[1], 1, 10) Sleep(50) ;do something else here, Maybe increment a variable? $iTimesClicked += 1 Next Msgbox(0,'',"I found and Clicked " & $iTimesClicked & " Times!") Edited December 19, 2017 by kaisies Earthshine and RoundChecker 2 Link to comment Share on other sites More sharing options...
RoundChecker Posted December 19, 2017 Author Share Posted December 19, 2017 No I think I understand the content here, with what I mean by returning value is, when the search is complete, a value is returned (I'm new to autoIT but that's how i define it within scriptin) What I meant with 1 is that it refers to the first Element in the array box i put, which is 0 in my example. Global $cArr[4] = [0, $a, $a1, $a2] 1 = 0 2 = $a 3 = $a1 4 = $2 So $k = 1 to UBound($cArr) - 1 ; In this case it would be :: $k = 0 to UBound(4) - 1 (So the entire 4 elements minus 1 so it returns arrays from 0 to 3 instead of 1 to 4, else it would cause an error. (I started with Array on autoit 15 hours ago or so, just learning it, but I got what it does. So the $cArr would be the entire array element put together and that cannot be clicked, it has to go through everyone and returning the value by $k = 1 to UBound($cArr) -1 So $cArr[$k] where $cArr would be our 4 Arrays that contains the elements and $k is the "For" that we used to determine the loop through the elements to find out which one is inArray. Right? Where : $cArr[$k] Will now return the index/element/value/whatever you wanna call it, that it found from this : $k = 1 to UBound($cArr) -1 So that's why $cArr[$k] can be then clicked in the loop as it clicks what is inArray, $cArr is used to the reference of the arrays, $[k] used to find which element was found, did i get the gist of it? Link to comment Share on other sites More sharing options...
kaisies Posted December 19, 2017 Share Posted December 19, 2017 (edited) Close, but not quite. Global $cArr[4] = [0, $a, $a1, $a2] your Values, $a, $a1, and $a2 are in indexes 1, 2, and 3. Not 2, 3, 4 as you said. This is why the For loop needs to start at 1. UBound($cArr) returns 4. There are 4 elements. Subtract 1 to get 3. So now the For statement is: for $k = 1 to 3 A For loop doesn't return anything, it doesn't find anything. This For loop isn't evaluating your array. The 1 means it is literally starting at $cArr[1], which is the value of $a, NOT 0. A for loop in plain english is: Use this Variable ($k). Start it with this value (1), and then increment it (default is 1), until (to) this value (UBound($cArr)-1). It is essentially the same as a Do..Until Loop, but its incrementing the variable for you. $x = 1 Do ConsoleWrite($x & @CRLF) $x+=1 Until $x >= 4 For $x = 1 to 3 ConsoleWrite($x & @CRLF) Next Edited December 19, 2017 by kaisies Earthshine 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now