I have tried the above settings for tesseract, but still getting a bad accuracy (50% only, no more). I'm diving into tesseract config to enable digits only, and "coc" langage to use the trained data on Supercell Magic font.
Video Game Reverse Engineering
Developing Bot
Started by Antidote · Dec 5, 2014
I am having the same problem that qaqaq use to have, I am running the Search Function script yet it only clicks next once and fails to do anything else. I've looked at the code and it clicks next first without trying to run CheckScreen functions, so I believe that I am having some difficulties with tesseract.
Any help would be much appreciated, I want to be involved in improving the script and helping create a bot 🙂.EDIT: I didn't read qaqaq's more recent reply and it worked
I got it working, I copied the Tesseract-OCR that came with the bot to the location of where I installed tesseract, 'C:\Program Files (x86)\Tesseract-OCR'. I merged the folder and it worked after that.
I noticed a lot of functions were disabled in Search function script. Probably, it did only one search because the Tesseract wasn't able to read the values properly and would always result in a 7-digit value which is usually greater than the settings you have specified thus fulfilling the need for CheckScreen Functions. Then there were no more functions left to do because it was disabled in the search function script:
Func Start()
ControlClick ($HWnD, "","", "left", "1", 715*$x_ratio, 405*$y_ratio)
;While 1
;CheckIdle() ;Check disconnect message and click on reload
GetInput() ;Read user's input
;ZoomOut()
;LocateBarrack() ;If barrack not located, ask user to manually click on barrack to locate position
;Train() ;Train troop according to user's input
;Sleep(900000) ;Wait 15 mins for troops training
;AssignTroop() ;Assign troop type to troop position in attack (unfinished)
;PrepareAttack() ;Click Attack
VillageSearch()
;DropTroop() ;Drop troop in order: Giant, Barbarian, Archer (unfinished)
;DropAll() ;Drop everything
;Sleep(180000) ;Wait 3 mins
;ControlClick ($HWnD, "","", "left", "1", 400*$x_ratio, 450*$y_ratio) ;Click Return Home
;Sleep(10000)
;WEnd
EndFunc
@ Vanadium
Since the adjustment, I don't have problems with the values that Tesseract is giving me. I think it's just the coordinates. How I wish I'm a programmer..
After the Tesseract, we have to secure identifying the Zombies.. I don't know if Pixelsearch will do any good but somehow I luckily stumbled upon ImageSearch.. Check this link http://www.autoitscript.com/forum/topic/65748-image-search-library/page-4#entry746428
I tried your setting for tesseract capture, it's not accurate enough. Many values are missread. Any other setting i may have missed ?
I know imagesearch, i made it work on my machine. I'm going to implement full collector search, lvl10 and lvl11 only. Lower collectors have not enough capacity.
Th sniping can also be implemented quite easily. It involves locating the th, compare it with a corner location and choose appropriate deploy point for deployment.
I'm going to investigate again on tesseract in this script. I'm stuck since weeks on tesseract, almost all the other features done in java. Just i can't get it read loot properly, thinking i'm going to abandon using tesseract and concentrate on image search.
I've also spent many time trying to make java image search api sikuli work, but somehow it's not stable. Sometimes it just doesn't find any image, sometimes just half, sometimes working perfectly. And this happens when testing on a static screenshot..
I checked again.. Mine wasn't 100% accurate too.. I tried changing BS resolution but I find 860x720 more accurate for tesseract. Also, I tried running read value twice per search and got different results. I think we could run read value 2-4x then choose the minimum value and/or greater number of occurence. atleast the accuracy will be around 95% if not 100% I think. And if you match it with image search I think It'll be ok.
Sorry guys haven't had much free time lately, thanks for all your feedback and contribution, really appreciate it!
@odySSeys: I use ControlClick so it won't interfere with the cursor so you can still use mouse for other thing (like interacting with bot) but yea MouseClick is more helpful for testing. Also your implementation of PixelSearch is nice, haven't had time to try it but thinking of using Pixelsearch to identify if certain buttons are available on screen so the bot knows exactly when and where to click what.
@AtoZ, qaqaq: yea the whole script is in the file Bot.rar, Search Function is simply Click Next, Run Tesseract, Compare Value. If it finds a wrong match, just click Start again and it will continue finding.
About accuracy, I also find for the same value different Tesseract calls give different results. You can tweak read region to improve accuracy but it's only a temporary solution (I jumped between 800x600 and 860x720 but keeps base numbering at 800x600 so sometimes I fine tune for one or another). I think the problem at the core is the traineddata not being good enough. (just notice it will return only number with or without "digits" since I only trained it with number it won't recognize anything else lol). I'll be looking into training it again this time with sample number specifically from 0 to 999999 instead of randomly generated ones. I'll be writing a tut for training Tesseract tonight so we can all do it together, it's very easy once you know all the steps :D
A few ideas in mind:
- implement pixelsearch to identify button
- identify all possible error, message pop up,.. so the bot can handle unexpected outcome (pixelsearch can be used I think)
- look into image compare to identify different buildings (barracks, townhall, defense,..)
- identify if army is full (I found a bitmap image from Lf with this, so maybe image compare too)
- read troops amount from Barracks and Army Camp to optimize training time (this is how lf robot do)
- ...
Really appreciate it if you guys can all contribute. You don't even have to know coding, you can give feedback on error, recommend features, logic flow (click here, click there, then check this check that, then do this do that,..) Sometimes coding is the easiest part and that stuffs are much more troublesome :deadtongue: If we do well in the next few weeks we can have a stable bot, might not be as advanced as lp or lf (maybe more, who knows 😎) but stable enough and more flexibility
@vanadium: you seem to get all the image search figured out, mind sharing some experience with us? :D
Also here's the script I use to locate pixel in BlueStacks. Just run it, make BlueStacks the active windows, hover your mouse where you want to get x,y value and press F7.
http://www5.zippyshare.com/v/34265429/file.html
#include <MsgBoxConstants.au3>
Opt ("MouseCoordMode", 2)
HotKeySet ("{F7}", "ShowMouseLocation")
HotKeySet ("{F8}", "Terminate")
While 1
Sleep (100)
WEnd
Func ShowMouseLocation ()
Local $CurrentMouseLocation = MouseGetPos ()
MsgBox ($MB_SYSTEMMODAL, "Mouse x, y:", $CurrentMouseLocation[0] & ", " & $CurrentMouseLocation[1])
EndFunc
Func Terminate()
Exit
EndFunc
I've added a small feature to the Search Function script to help see the data from which is returned when tesseract reads the gold and elixir.
It is basically a textbox, like in LF Robot, that displays the gold and elixir everytime it searches.
#RequireAdmin
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <TrayConstants.au3>
#include <Misc.au3>
#include "Tesseract.au3"
Opt ("MouseClickDelay", 10)
Opt ("MouseClickDownDelay", 10)
Opt ("MouseCoordMode", 0)
Opt ('PixelCoordMode', 0)
$Title = "BlueStacks App Player"
$Full = WinGetTitle ($Title)
$HWnD = WinGetHandle ($Full)
WinActivate ($HWnD)
Global $Left = 45, $Top = 70, $Right = 660, $Bottom = 490
Global $BSsize = WinGetClientSize($hWnd)
Global $x_ratio = $BSsize[0]/800, $y_ratio = $BSsize[1]/600
Global $Gold, $Elixir, $MinGold = 50000, $MinElixir = 50000, $SearchCount = 0
Global $SearchMode = 1, $SearchCheck = 0, $ErrorCheck = 0
HotKeySet("+{ESC}","Terminate")
#Region ### GUI ###
$BotGUI = GUICreate("Clash of Clans Bot", 280, 500)
GUICtrlSetFont(-1, 10, 800, 0, "Calibri")
$MeetAll = GUICtrlCreateCheckbox("Meet all conditions", 150, 20, 140, 17)
GUICtrlCreateLabel("Min Gold:", 150, 48, 58, 17)
$MinGoldInput = GUICtrlCreateInput("", 200, 44, 55, 21, $ES_NUMBER)
GUICtrlSetLimit(-1, 6)
GUICtrlCreateLabel("Min Elixir:", 150, 72, 57, 17)
$MinElixirInput = GUICtrlCreateInput("", 200, 68, 55, 21, $ES_NUMBER)
GUICtrlSetLimit(-1, 6)
$Barrack01 = GUICtrlCreateCombo("Barrack 01", 30, 16, 80, 30, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Barbarian|Archer|Goblin|Giant")
$Barrack02 = GUICtrlCreateCombo("Barrack 02", 30, 40, 80, 30, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Barbarian|Archer|Goblin|Giant")
$Barrack03 = GUICtrlCreateCombo("Barrack 03", 30, 64, 80, 30, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Barbarian|Archer|Goblin|Giant")
$Barrack04 = GUICtrlCreateCombo("Barrack 04", 30, 88, 80, 30, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Barbarian|Archer|Goblin|Giant")
$StartButton = GUICtrlCreateButton("START (Shift+ESC to Exit)", 30, 120, 220, 40)
$Results = GUICtrlCreateEdit("", 10, 170, 260, 300)
GUISetState(@SW_SHOW)
#EndRegion ### GUI ###
While 1
$Msg = GUIGetMsg()
Switch $Msg
Case $GUI_EVENT_CLOSE
$ExitCheck = MsgBox(4+65536, "Confirm Exit", "Are you sure you want to exit?", 0, $BotGUI)
If $ExitCheck = 6 Then
Exit
EndIf
Case $StartButton
Start()
EndSwitch
WEnd
Func Start()
ControlClick ($HWnD, "","", "left", "1", 715*$x_ratio, 405*$y_ratio)
;While 1
;CheckIdle() ;Check disconnect message and click on reload
GetInput() ;Read user's input
;ZoomOut()
;LocateBarrack() ;If barrack not located, ask user to manually click on barrack to locate position
;Train() ;Train troop according to user's input
;Sleep(900000) ;Wait 15 mins for troops training
;AssignTroop() ;Assign troop type to troop position in attack (unfinished)
;PrepareAttack() ;Click Attack
VillageSearch()
;DropTroop() ;Drop troop in order: Giant, Barbarian, Archer (unfinished)
;DropAll() ;Drop everything
;Sleep(180000) ;Wait 3 mins
;ControlClick ($HWnD, "","", "left", "1", 400*$x_ratio, 450*$y_ratio) ;Click Return Home
;Sleep(10000)
;WEnd
EndFunc
Func GetInput()
$MinGold = Number(GUICtrlRead($MinGoldInput))
$MinElixir = Number(GUICtrlRead($MinElixirInput))
If GUICtrlRead($MeetAll) = $GUI_CHECKED Then
$SearchMode = 2
Else
$SearchMode = 1
EndIf
EndFunc
Func CheckScreen()
Local $Check = ""
$i = 0
While $Check = ""
$Check = _TesseractWinCapture($HWnD,"",0,"",1,2,$Left*$x_ratio,$Top*$y_ratio,$Right*$x_ratio,$Bottom*$y_ratio,0)
$Check = StringStripWS($Check, 8)
Sleep(200)
$i += 1
If $i > 150 Then
MsgBox(0,"Search Time Out","Exiting..")
Exit
EndIf
WEnd
EndFunc
Func VillageSearch()
CheckScreen()
ReadValue()
CompareValue()
While $SearchCheck = 0
ControlClick ($HWnD, "","", "left", "1", 715*$x_ratio, 405*$y_ratio) ;Click Next
CheckScreen()
ReadValue()
CompareValue()
WEnd
TrayTip ("Enemy Found!","Requirement met: Gold: " & $Gold & ". Elixir: " & $Elixir, 0, $TIP_ICONASTERISK)
EndFunc
Func ReadValue()
$Read = _TesseractWinCapture($HWnD,"",0,"",1,2,($Left+10)*$x_ratio,($Top + 10)*$y_ratio,($Right)*$x_ratio,($Bottom)*$y_ratio,0) ;Capture screen region with gold and elixir
$Read = StringRegExpReplace(StringRegExpReplace($Read, "(\v)+", @CRLF), "\A\v|\v\Z", "")
$Read = StringSplit($Read, @CRLF, 1) ;Strip whitespaces & blank lines and split into array
$Gold = Number(StringRegExpReplace($Read[1], "[^[:digit:]]", "")) ;Convert gold to number
$Elixir = Number(StringRegExpReplace($Read[2], "[^[:digit:]]", "")) ;Convert exlir to number
GUICtrlSetData(-1, "(" & $SearchCount & ") Gold: " & $Gold & ". Elixir: " & $Elixir & @CRLF & String(GUICtrlRead($Results))) ;Sends Gold and Elixir to textbox
$SearchCount = $SearchCount + 1 ; Counter for number of searches
Sleep(2000)
EndFunc
Func CompareValue()
If $Gold >= $MinGold Then
If $Elixir >= $MinElixir Then
Select
Case $SearchMode = 1
$SearchCheck = 1
Case $SearchMode = 2
$SearchCheck = 1
Case Else
$SearchCheck = 0
EndSelect
Else
Select
Case $SearchMode = 1
$SearchCheck = 1
Case $SearchMode = 2
$SearchCheck = 0
Case Else
$SearchCheck = 0
EndSelect
EndIf
Else
If $Elixir >= $MinElixir Then
Select
Case $SearchMode = 1
$SearchCheck = 1
Case $SearchMode = 2
$SearchCheck = 0
Case Else
$SearchCheck = 0
EndSelect
Else
Select
Case $SearchMode = 1
$SearchCheck = 0
Case $SearchMode = 2
$SearchCheck = 0
Case Else
$SearchCheck = 0
EndSelect
EndIf
EndIf
EndFunc
@Antidote, Vanadium
We only need the first two digits of Gold and Elixir to match our criteria that represents 10,000 per unit. You guys probably notice from the existing robots in the market that has the unit 'W'. We don't actually need other non-significant digits which usually we get error from Tesseract reading it. And we could recalculate 2x-4x to confirm the read value and choose the minimum value if there are equal occurences. I think it'll be 99% accurate.
Since the adjustment of the $Left value, I'm only having problems with the ROWS read by the Tesseract. There are instances that the single row in between the Gold and Elixir is missing thus result in misread ELIXIR (having the value of DE). But I think it'll just be an easy fix. Either we use tesseract for each resources or just add codes after the stringsplit. But I believe the solution in the previous paragraph will also fix this.
I know this, but to know if you have 10k elixir, or 100k elixir, you need to read the whole value. And if the value is not accurate (example: 50.000 elixir, but reads 500.000), then it fails. I disagree with the W feature, which was a lot confusing when i was using lf-robot.
I suggest we stick to thousands, far easier to understand than 10th of thousands. Think about a hard disk drive sold with 10th of thousands of Megabytes, you will love the conversion haha
W means 10.000
EX: 8, LF Robot will find village that have >= 80.000 Gold
I know, this is not the point. It's not because you only want the first digits that you don"t have to read the whole value. otherwise how do you differentiate 10.000 from 100.000k, first two digits are the same but it's not the same overall value. If the reading tesseract makes is not accurate, we can't go further. On my computer, it does not run fine with the given positions. I've tested many, it's simply not accurate enough.
This discussion is closed.