Affe Posted September 7, 2007 Share Posted September 7, 2007 Well, I was going to post this in the example scripts section, but for some reason it says that I do not have the rights to post there.So I'll go ahead and post this here, and also see if anyone has any ideas for finishing the program.First, I would like to note that I am writing this bot out of boredom and to see what I can come up with as far as pattern recognition goes.I have the program currently set up to open Solitaire (sol.exe), and then identify the first seven cards dealt. Below is the code for the program, and the .ini file that is used to identify the cards.I use the following method to identify the cards:The program reads several lines of pixels off of the cards, and then turns those pixel numbers into a string. This string is then searched for in an array of cards where the definitions of these strings is kept. When a match is found, the card is identified.I figured someone may be interested in the method I used to identify the cards, as I feel it may have many uses. The code is below, and the .ini file and code file are linked below:expandcollapse popup#Include<Array.au3> Run("sol.exe") WinWaitActive("Solitaire") $size = WinGetPos("Solitaire") ;~ MsgBox(0, "Active window stats (x,y,width,height):", $size[0] & " " & $size[1] & " " & $size[2] & " " & $size[3]) $x_coord_window = $size[0] $y_coord_window = $size[1] $window_width = $size[2] $window_height = $size[3] $Tooltip = True ;~ Card size on 1028 x 768 is 70 wide by 96 tall ;~ Window opens as 593 wide by 438 tall ;~ 7 cards put together are 490 wide ;~ Green space between cards is 12 pixels ;~ Width Example: ;~ [Left Window Edge to card 15 px]<-->[Card 70 px]<-->12 px<-->[Card 70 px]<-- etc... ;~ Height from top of solitaire screen to top of most left hand card = 157 px ;~ Height from top of solitaire screen to top of first Ace slot = 55 px ;~ Height of stacked cards (cards behind viewable cards) = 3 px ;~ Height of stacked cards (multi-visible) = 15 px ;~ Location from top of card to top of Unit Image = 4 px and 4 px from left side of card ;~ Example of where cards are "grabbed": ;~ * = grab point ;~ ________ ;~ * _| ;~ _| ;~ | ;~ | ;~ Note that it just barely grabs at the corner -- the far left edge ;Identify Cards Section: Used to first identify the cards dealt ;First Create an array that can contain 56 cards with the following attributes: X coordinates, Y coordinates, Number/Character/Type Global $Card[52][3] ;Now Create an array to load from the .ini and compare to the $Card array to identify cards Global $Load[52][2] Global $Load2[52] ;Now load from the .ini $Load = IniReadSection("cards.ini", "section1") If @error Then MsgBox(4096, "", "Error occurred, probably no INI file.") ;~;Test to see if .ini loaded properly ;~ Else ;~ For $i = 1 To $Load[0][0] ;~ MsgBox(4096, "", "Key: " & $Load[$i][0] & @CRLF & "Value: " & $Load[$i][1]) ;~ Next EndIf ;Below finds the location of the first card on the left $x_card = $x_coord_window + 15 $y_card = $y_coord_window + 157 ;Then the program assigns locations to each of the first seven cards $x = 0 While $x < 7 $Card[$x][0] = $x_card $Card[$x][1] = $y_card $x_card = $x_card + 70 + 12;adds 70 to consider width of card, 12 to consider space between cards $y_card = $y_card + 3;adds 3 to consider the distance due to each unknown bottom card $x = $x + 1 Wend ;~;**************************************************************************************** ;~;TEST FOR THE ARRAY ADDITIONS - MOVES EACH CARD UP 4 PIXELS GOING FROM LEFT TO RIGHT ;~ $x = 0 ;~ While $x < 7 ;~ MouseMove($Card[$x][0], $Card[$x][1]) ;~ MouseDown("left") ;~ MouseMove($Card[$x][0], $Card[$x][1] - 4) ;~ MouseMove($Card[$x][0], $Card[$x][1]) ;~ MouseUp("left") ;~ $x = $x + 1 ;~ WEnd ;~;**************************************************************************************** ;~;**************************************************************************************** ;~;Below was used to populate the .ini for the "Pattern Identifier" ;(creates a code used to identify cards and stores it in a file to be used as a reference) ;~ $file = FileOpen("test.txt", 1) ;~; Check if file opened for writing OK ;~ If $file = -1 Then ;~ MsgBox(0, "Error", "Unable to open file.") ;~ Exit ;~ EndIf ;~ $x = 0 ;~ $check = "" ;~ While $x < 7 ;~ For $j = 5 to 27 Step 2 ;~ For $i = 4 to 11 Step 1 ;~ $check = $check & PixelGetColor($Card[$x][0] + $i, $Card[$x][1] + $j) ;~ Next ;~ Next ;~ $Card[$x][2] = $check ;~ $str = StringFormat("Position %s", $x) ;~ $card_name = InputBox("What am I looking at?", $str) ;~ $str = StringFormat("%s=%s", $card_name, $Card[$x][2]) ;~ FileWriteLine($file, $str) ;~ $x = $x + 1 ;~ $check = "" ;~ WEnd ;~;**************************************************************************************** ;First, we need to load the two-dimensional $Load array into a one dimensional array so that we can search it $x = 0 While $x < 52 $Load2[$x] = $Load[$x][1] $x = $x + 1 WEnd ;Now we need to identify the number and character on the cards $x = 0 $check = "" While $x < 7 For $j = 5 to 27 Step 2 For $i = 4 to 11 Step 1 $check = $check & PixelGetColor($Card[$x][0] + $i, $Card[$x][1] + $j) $Pos = _ArraySearch ($Load2, $check, 0, 0, 0, True) Select Case $Pos = -1 MsgBox(0, "Not Found", '"' & $check & '" was not found in the array.') Case Else $Card[$x][2] = $Load[$Pos][0] ToolTip($Card[$x][2], $Card[$x][0], $Card[$x][1]) EndSelect Next Next $x = $x + 1 $check = "" Sleep(2000) WEndIf anyone has any suggestions on how to finish the bot (pattern matching to make it move the cards in the correct places, etc) I happily welcome input.Cards.iniSolitaire_Bot.au3 [center][/center] Link to comment Share on other sites More sharing options...
Affe Posted September 7, 2007 Author Share Posted September 7, 2007 I noticed that on different machines the window opens at different sizes. I've fixed the file where you can download the .au3, and here is the change below: ;Below finds the location of the first card on the left $x_adj = 15 $y_adj = 157 If $size[3] < 438 Then $change = 438 - $size[3] $y_adj = 157 - $change ElseIf $size[3] > 438 Then $change = $size[3] - 438 $y_adj = 157 + $change EndIf If $size[2] < 593 Then $change = 593 - $size[2] $x_adj = 15 - $change ElseIf $size[3] > 593 Then $change = $size[2] - 593 $x_adj = 15 + $change EndIf $x_card = $x_coord_window + $x_adj $y_card = $y_coord_window + $y_adj [center][/center] Link to comment Share on other sites More sharing options...
Ozi Posted September 9, 2007 Share Posted September 9, 2007 Well done Affe, I think your way about recognizing the cards is brilliant. I to have been working on a card recognition bot and your way about doing everything has really helped me. Regards, Ozi Link to comment Share on other sites More sharing options...
Myshaak Posted January 24, 2014 Share Posted January 24, 2014 Hi, may I ask you for cards.ini file for Solitaire bot? Link is dead. Thank you Link to comment Share on other sites More sharing options...
Geir1983 Posted January 24, 2014 Share Posted January 24, 2014 lol, thread is almost 7 years old... Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 24, 2014 Moderators Share Posted January 24, 2014 Myshaak,Welcome to the AutoIt forum. Firstly, please note that the post above yours is over 6 years old - we do not encourage necro-posting after such time, particularly in view of the thread subject as you will see in a moment. Next, you appear to have missed the Forum rules on your way in. Please read them now (there is also a link at bottom right of each page) - particularly the bit about not discussing game automation - and then you will understand why you will get no help and this thread will now be locked. See you soon with a legitimate question I hope. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Recommended Posts