Jump to content

Detect a change then click where change occurred


Recommended Posts

Hello, I'm trying to make a simple AutoIt bot for a Whack A Mole styled game. If you're not familiar with this sort of game, I'll explain: There are holes in the ground where the Moles will come out of. Each time it will come out of a random new hole, and what you're supposed to do is click on the mole, and this will gain points.

What I'm trying to do is scan the game while waiting for a change to occur. For this game, that change would be the mole popping out. Once it has detected a change, I'd like to know the coordinates for the change, so I can then have the bot click where the change occurred.

Normally, I would use the PixelSearch function, and search for a pixel that's only common to each mole.. that is not a possibility because each time a mole comes out, it has a random color applied to it. Also, I understand that I could use PixelChecksum to discover if a change has occurred, however, I'm not sure of how this could give me the exact location of where this change has occurred.

If anyone knows how I could go about doing this, please let me know.

Link to comment
Share on other sites

just get the color of ONE pixel for EACH mole hole. Shouldn't matter what color the mole is. If the color changes, there is a mole.

I thought about doing this, but it's not exactly the approach that I was looking for. See, I'm trying to make a bot for this game, so that I'm more familiar with them. Then, using the knowledge I have, I'm going to make a bot for another game where there aren't fixed locations where "moles" will come out of. Instead of having these fixed holes, the "moles" will randomly be generated at different locations all over the screen. That's why I was trying to find the "fix" that I described in the first post.

Thanks for your help, though.

Link to comment
Share on other sites

Why not this..

Local $cksum1[5] = [checksum, top, right, bottom, right]

Hole[10] = [cksum1,cksum2,cksum3,....]

Assign a number to each mole hole starting from 0 and get a checksum for each hole without a mole and store each one in an array.

Then continuously scan each mole holes checksum to a change.

While 1

For $i = 0 To 9 ; mole holes

Local Molehole = Hole[$i]

If Checksum(hold) <> Checksum(Hole[20,4,3,23]) Then Return $i

Next

Wend

Use the returned $i to get the information about the pixel location area.

Dim Hole = Hole[$i]

Mouseclick("left", Hole[1], Hole[2])

Make sense?

www.itoady.com

A* (A-star) Searching Algorithm - A.I. Artificial Intelligence bot path finding

Link to comment
Share on other sites

@Toady (and I say this with all due respect, cause Toady is the shit) , he is trying to get it to work even if a mole comes up off the page. He is looking for a lesson in building a dynamic bot via this crappy little game. Otherwise my mole finding function would work too. I guess he wants to do pixelsearch for a change or something.

Link to comment
Share on other sites

yes please. He is looking for a way that he can detect any color mole coming out of a hole which has a random position. In other words, instead of nine static holes, he is looking for a way to detect any number of moles in dynamically placed holes. He wants code that will work even if the holes move. In yours, if the holes move, then your pixel checking will not work. Mine will not work for this either.

Link to comment
Share on other sites

Thanks for your help Toady and danwilli. Initially, I wanted a method that I am no longer interested in.

What I plan to do is to create multiple boxes for the script to scan. It will initially do a PixelChecksum in each box, then it will scan each one for changes. I had begun working on it when Toady posted his suggestion, and I realized that this would be the way to go. However, I need a bit more help working with arrays. I've never used them in AutoIt before, and as such am unexperienced.

Toady, could you please give me an example of the method that you were talking about?

Link to comment
Share on other sites

Thanks for your help Toady and danwilli. Initially, I wanted a method that I am no longer interested in.

What I plan to do is to create multiple boxes for the script to scan. It will initially do a PixelChecksum in each box, then it will scan each one for changes. I had begun working on it when Toady posted his suggestion, and I realized that this would be the way to go. However, I need a bit more help working with arrays. I've never used them in AutoIt before, and as such am unexperienced.

Toady, could you please give me an example of the method that you were talking about?

yes I am working on one now. Your way is the same way I was envisioning, by just using a grid system, then checking each grid square for a change and return its position when that grid's checksum changes.

www.itoady.com

A* (A-star) Searching Algorithm - A.I. Artificial Intelligence bot path finding

Link to comment
Share on other sites

Ok, let me know if this makes sense to you. The script will do a PixelCheckSum on a region of the screen, when a part of that region of the screen changes a message will display the x,y coord of the pixel that changed. You can add a mouseclick using these coords too.

Make sure that the top left region of your screen is clear and its not changing when you run this script. After its running, a tooltip will display all the checksums for that region, there should be 16 total. Then move your mouse into that region and you will see the popup where it found the change.

#include <Array.au3>

;Get array of 16 different checksum in top left of screen 200x200 size divided into 16 squares
;Example region location x=0,y=0 on screen with bottom right location at x=200,y=200
Local $AreaCheckArray =_PixelCheckSumEx(0, 0, 200, 200, 1, 5) ;Get checksum grid for region
Local $buffer = $AreaCheckArray[0] & " Grid squares" & @CRLF

;Display that checksums are correct
For $i = 1 To $AreaCheckArray[0]
    $GridSquare = $AreaCheckArray[$i]
    $buffer &= "Checksum=" & $GridSquare[0] & @TAB & "Top-Left Location=" & $GridSquare[1] & "," & $GridSquare[2] & "Bottom-right Location=" & $GridSquare[3] & "," & $GridSquare[4] & @CRLF
    ToolTip($buffer)
Next

;Continuosly check each square's checksum with itself until a change has made
;If found a change, mouse will click on that square
While 1
    Local $CurrentSquareCheckSum
    For $i = 1 To $AreaCheckArray[0]
        $GridSquare = $AreaCheckArray[$i]
        If $GridSquare[0] <> PixelChecksum($GridSquare[1],$GridSquare[2],$GridSquare[3],$GridSquare[4]) Then
            ;mouse will click in center of square that was changed
            ;MouseClick("left",$GridSquare[1],$GridSquare[2])
            ToolTip("")
            MsgBox(0,"","Clicked at " & $GridSquare[1] & "," & $GridSquare[2])
            Exit
        EndIf
    Next
WEnd

;Gridsize is the number of slices to make a region, therefor Gridsize = 4 mean 4*4 = 16 grid squares
Func _PixelCheckSumEx($left, $top, $right, $bottom, $step=1, $gridsize=1)
    Local $PixelCheckSums[1] = [$gridsize^2]
    If $gridsize = 1 Then
        Local $GridOBJ[5] = [PixelChecksum($left,$top,$right,$bottom,$step),$left,$top,$right,$bottom]
        _ArrayAdd($PixelCheckSums,$GridOBJ)
        Return $PixelCheckSums
    Else
        Local $grid_dx = Floor(($right-$left)/$gridsize) ;width of each square
        Local $grid_dy = Floor(($bottom-$top)/$gridsize) ;height of each sqaure
        Local $dxdyCheckSum 
        For $dy = $top To $bottom - $grid_dy Step $grid_dy
            For $dx = $left To $right - $grid_dx Step $grid_dx
                Local $GridOBJ[5] = [PixelChecksum($dx,$dy,$dx+$grid_dx,$dy+$grid_dy,$step),$dx,$dy,$dx+$grid_dx,$dy+$grid_dy]
                _ArrayAdd($PixelCheckSums,$GridOBJ)
            Next
        Next
    EndIf
    Return $PixelCheckSums
EndFunc
EndFunc
Edited by Toady

www.itoady.com

A* (A-star) Searching Algorithm - A.I. Artificial Intelligence bot path finding

Link to comment
Share on other sites

This is what I did.

World of warcraft fish bot. Sounds about like what your wanting to do.

There is a blue piece on the bobber which is fairly unique to anything else on the screen. Lets just say it was "98726252".

Step one: I would use my fishing skill.

Step two: perform a pixelsearch() of the entire screen for the color 98726252. If I failed I would do the search again, if it failed again I would simply recast.

Step three: once it found the pixel, it would mousemove() to the location($pos) of the pixel.

Step four: it would perform another pixelsearch($pos[0]-10,$pos[1]-10,$pos[0]+10,$pos[1]+10) looking for a white pixel. The reason I was looking for white was because when the fish would bite, there was a splash around the bobber which was white.

Step five: sleep(500) and mouseclick($pos[0],$pos[1])

So end result. I could locate the bobber at any postion on the screen. Wait for a change to occur at a random time, and click it. Should be able to accomplish what you want in a similar fashion. Might have to get creative depending on things like random colors on the screen, if the object your trying to click changes colors, etc.

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...