CodeMaster Rapture Posted March 19, 2006 Share Posted March 19, 2006 (edited) Hello all,I'm trying to come up with a bot that will play a game called Collapse. I'm doing this as a challenge for myself because I figured it would be pretty difficult to come up with an app with the logic needed to play it and also to be very fast. What I've done so far:Figured out a way to find the game on the screen.Decipher the different color boxes and bombs for the game. *Store the position and color of each box for later usage.Destroy bombs before boxes.* I'm currently using pixelchecksum() for simplicity, but I'll most likely change that to a 4 or 5 point pixelgetcolor().What I need help/suggestions to do:Come up with a way to find all boxes of the same color that are connected (3 or more).Come up with a faster screen searching method for boxes/bombs.Here's my code so far:expandcollapse popup#include <Array.au3> #region Globals Const $Title = "Collapse - Microsoft Internet Explorer" Global $FirstRun = 1 Global $StartX = 337 Global $StartY = 393 Const $BoxRed = 3183926199 Const $BoxGreen = 426970639 Const $BoxBlue = 1410215416 Const $BoxWhite = 3294800457 Const $BoxGrey = 3059036688 Const $BoxEmpty = 50331649 Const $BombRed = 1990514232 Const $BombGreen = 1332283690 Const $BombBlue = 904996846 Const $BombBlack = 3050855186 Const $BombWhite = 3039844320 Global $Boxes[1] Global $PosX[1] Global $PosY[1] #endregion Globals #region Main Loop While 1 If (WinActive($Title)) Then If ($FirstRun) Then $FirstRun = _FindFirstBox() MouseMove($StartX,$StartY,0) Else $time = TimerInit() _FindBomb() _UpdateBoxes() EndIf EndIf Sleep(10) WEnd #endregion Main Loop Func _GetBoxColor($X,$Y = -1) Local $Checksum = 0 If ($X > -1 And $Y > -1) Then ;Each box/bomb is 15x15 pixels (well, what we want anyways) $Checksum = PixelChecksum($X,$Y,$X+15,$Y+15) Select Case ($Checksum == $BoxRed) Return "Red Box" Case ($Checksum == $BoxGreen) Return "Green Box" Case ($Checksum == $BoxBlue) Return "Blue Box" Case ($Checksum == $BoxWhite) Return "White Box" Case ($Checksum == $BoxGrey) Return "Grey Box" Case ($Checksum == $BoxEmpty) Return "Empty Box" Case ($Checksum == $BombRed) Return "Red Bomb" Case ($Checksum == $BombGreen) Return "Green Bomb" Case ($Checksum == $BombBlue) Return "Blue Bomb" Case ($Checksum == $BombBlack) Return "Black Bomb" Case ($Checksum == $BombWhite) Return "White Bomb" Case Else MouseMove($X,$Y,0) MsgBox(0,"GetBoxColor","Unknown Color: " & $Checksum) Return "Unknown Color: " & $Checksum EndSelect ElseIf ($X > -1 And $Y == -1) Then Return $Boxes[$X] Else Return 0 EndIf EndFunc;==>_GetBoxColor(X,Y) Func _UpdateBoxes() Local $iterX = 0 Local $iterY = 0 For $iterX = $StartX To ($StartX-264) Step -24 For $iterY = $StartY to ($StartY-336) Step -24 _ArrayAdd($Boxes,_GetBoxColor($iterX,$iterY));Store the color of the box _ArrayAdd($PosX,$iterX) ;Store the X position of the box _ArrayAdd($PosY,$iterY) ;Store the Y position of the box Next Next EndFunc;==>_UpdateBoxes() Func _FindAdjacentBox($X,$Y,$Color) Local $Information[3] Local $Found ;Find a box that is next to the current position (X,Y) and is ;the same color (color checksum) and return it as an array If ($Found) Then $Information[0] = $X $Information[1] = $Y $Information[2] = $Color Else $Information[0] = -1 $Information[1] = -1 $Information[2] = -1 EndIf Return $Information EndFunc;==>_FindAdjacentBox(X,Y) Func _FindFirstBox() $WinInfo = WinGetPos($Title) If (Not @error) Then $pos = PixelSearch($WinInfo[0],$WinInfo[1],($WinInfo[0] + $WinInfo[2]),($WinInfo[1] + $WinInfo[3]),0xCC962C) If (Not @error) Then $StartX = $pos[0] - 26 $StartY = $pos[1] - 42 Return 1 EndIf EndIf EndFunc;==>_FindFirstBox() Func _FindBomb() Local $iter = 1 For $iter = 1 to UBound($Boxes) If (StringInStr($Boxes[$iter],"Bomb")) Then MouseClick("left",$PosX[$iter],$PosY[$iter]) Sleep(1000) ExitLoop EndIf Next EndFunc;==>_FindBomb()Note that _GetBoxColor() will poll the storage array or the current screen position depending on the agruments supplied (so I can use the same function for simplicity). The unfinished function _FindAdjacentBox() is going to be the logic heavy portion of the code. The _FindFirstBox() function finds a single unique pixel on the screen and calculates the position of the bottom-right box. The update function reads all boxes from the bottom up and right to left.I'm having a real mental block trying to come up with a way to find connected boxes efficiently. I will also need to decide if/when to click bombs. Black bombs destroy everything within 5-6 boxes of itself. Every other color bomb destroys all boxes of that color currently on the screen (I.E. A Red bomb destroys all red boxes).Here is a screenshot of the game with some highlighting I've included to show how the logic should work for finding connected boxes (3 or more). Once it finds a set of boxes, it needs to click on it and then refresh the list of boxes.So, the basic loop rundown of this bot is:1.) Search for a bomb, click on it, go to step 12.) Update the list of boxes3.) Find a set of 3 or more same colored boxes that are connected and click on it4.) RepeatAny suggestions would be greatly appreciated,CMR Edited March 19, 2006 by CodeMaster Rapture Link to comment Share on other sites More sharing options...
greenmachine Posted March 19, 2006 Share Posted March 19, 2006 I think it might be easier (but not as bottish) to just have it click really fast nonstop and let you move around to wherever you want it to click. A little unrelated - what's your high score? I just played for the first time and got to level 9 with a score of 210,436. Link to comment Share on other sites More sharing options...
CodeMaster Rapture Posted March 19, 2006 Author Share Posted March 19, 2006 Level 12 With 570,000 points is my top score. Link to comment Share on other sites More sharing options...
greenmachine Posted March 19, 2006 Share Posted March 19, 2006 That's impressive. It really speeds up as the level progresses. I just did a test with a super-fast clicking script (hold space to click at ultra-speed), and I didn't even get past level 10. So if a bot can manage to do that, I'm really impressed. Link to comment Share on other sites More sharing options...
CodeMaster Rapture Posted March 20, 2006 Author Share Posted March 20, 2006 (edited) Hello again, I've been working on the logic part of my bot and I think I've got it down, I'm just not too sure where I should call it. Here's the code I've got: expandcollapse popupGlobal $Tracked[1] Func _FindAdjacentBox($X,$Y,$Color) Local $Found Local $iter ;Find a box that is next to the current position (X,Y) and is the same color (color checksum) While ($Found) For $iter = 1 To (UBound($Boxes)-1) Step 1 If ($Boxes[$iter] == $Color) Then If ($PosX[$iter] == ($X-15) And $PosY[$iter] == $Y) Then _ArrayAdd($Tracked,$iter) $X -= 15 ExitLoop ElseIf ($PosX[$iter] == ($X-15) And $PosY[$iter] == ($Y-15)) Then _ArrayAdd($Tracked,$iter) $X -= 15 $Y -= 15 ExitLoop ElseIf ($PosX[$iter] == ($X-15) And $PosY[$iter] == ($Y+15)) Then _ArrayAdd($Tracked,$iter) $X -= 15 $Y += 15 ExitLoop ElseIf ($PosX[$iter] == $X And $PosY[$iter] == ($Y-15)) Then _ArrayAdd($Tracked,$iter) $Y -= 15 ExitLoop ElseIf ($PosX[$iter] == $X And $PosY[$iter] == ($Y+15)) Then _ArrayAdd($Tracked,$iter) $Y += 15 ExitLoop ElseIf ($PosX[$iter] == ($X+15) And $PosY[$iter] == $Y) Then _ArrayAdd($Tracked,$iter) $X += 15 ExitLoop ElseIf ($PosX[$iter] == ($X+15) And $PosY[$iter] == ($Y+15)) Then _ArrayAdd($Tracked,$iter) $X += 15 $Y += 15 ExitLoop ElseIf ($PosX[$iter] == ($X+15) And $PosY[$iter] == ($Y-15)) Then _ArrayAdd($Tracked,$iter) $X += 15 $Y -= 15 ExitLoop Else $Found = Not $Found EndIf EndIf Next WEnd ;Ok, we found 3 or more adjacent boxes, let's destroy them. If ((UBound($Tracked)-1) > 2) Then MouseClick("left",$PosX[$Tracked[1]],$PosY[$Tracked[1]]) ReDim $Tracked[1] Return EndIf EndFunc ;==>_FindAdjacentBox(X,Y) I figure this is the best method to find connected boxes (8 points around the current box), but I need a little help to exclude the previos box(es) I've tracked. Any ideas on how to go about that? I also am unsure of where to call this function for the best performance. Thanx, CMR Edited March 20, 2006 by CodeMaster Rapture Link to comment Share on other sites More sharing options...
greenmachine Posted March 20, 2006 Share Posted March 20, 2006 I was thinking a little about this, and I decided on a very few things. 1. You don't actually need to check all 8 spaces around a block - only the vertical and horizontal 4 (up, right, down, left, not diagonal). Since blocks aren't considered connected if they are attached diagonally, there's no point in checking. 2. Since the blocks shift when you click a group, you shouldn't check all of the blocks for possible groups - just go through each row checking for neighbors, and if there is a group, click it and start over. Otherwise, you'll be checking stuff that doesn't exist. Although, now that I think about it, checking for neighbors as you go will take care of shifts in blocks.... This is a fun challenge... hopefully the code will be quick enough. Link to comment Share on other sites More sharing options...
CodeMaster Rapture Posted March 20, 2006 Author Share Posted March 20, 2006 I was thinking a little about this, and I decided on a very few things.1. You don't actually need to check all 8 spaces around a block - only the vertical and horizontal 4 (up, right, down, left, not diagonal). Since blocks aren't considered connected if they are attached diagonally, there's no point in checking. 2. Since the blocks shift when you click a group, you shouldn't check all of the blocks for possible groups - just go through each row checking for neighbors, and if there is a group, click it and start over. Otherwise, you'll be checking stuff that doesn't exist. Although, now that I think about it, checking for neighbors as you go will take care of shifts in blocks....This is a fun challenge... hopefully the code will be quick enough.Ya know... that's a good point. I didn't even think of the diagonals. Thank you. As for the "shifting", that won't really be a problem. Since it would take far too much code to track how the blocks "shift", I decided to just click and then update my list of boxes. Well, there goes 4 less boxes to check per cycle!Thanx so much,CMR 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