Jump to content

Who is Who ? (a little drag&drop game)


Gianni
 Share

Recommended Posts

This is a little experiment that makes use of a "Browser Control" embedded in a GUI in order to be able to use AutoIt, HTML, JavaScript and CSS all together.
This little toy will only work on systems with IE11.
The purpose is to drag all the names of the scientists & drop on the right ones. (among scientists it has also infiltrated an intruder). I hope you find it entertaining.
I've posted it here in the hope to have some suggestions on how to improve it all (I mean the interaction between Autoit Javascript html and css). Thanks

; this works on systems with IE11
; -------------------------------
#include <GUIConstantsEx.au3>
#include <array.au3>
Global $oIE, $oDocument, $ohJS, $sDroping
Global $iCorrect = 0, $iGoal = 11
Example()
Exit

Func Example()
    Local $aScientists[12][2] = _
            [["Schrodinger", "Schrodinger"],["Planck", "Planck"],["Pauli", "Pauli"],["Einstein", "Einstein"], _
            ["Chimp", "Chimp"],["Dirac", "Dirac"],["Heisenberg", "Heisenberg"],["Born", "Born"], _
            ["De Broglie", "De_Broglie"],["Bohr", "Bohr"],["Sommerfeld", "Sommerfeld"],["", "empty"]]

    Local $oIE = ObjCreate("Shell.Explorer.2") ; Create a BrowserControl
    Local $hGUI = GUICreate("", 660, 600, 30, 30)
    GUICtrlCreateObj($oIE, 0, 0, 660, 600) ; Place BrowserControl on the GUI
    GUISetState() ;Show GUI
    $oIE.navigate('about:blank') ; file:///' & @ScriptDir & '\WhoIsWho.html')
    While Not String($oIE.readyState) = 'complete' ; wait for about:blank
        Sleep(100)
    WEnd

    ; this waits till the document is ready to be used (portion of code from IE.au3)
    While Not (String($oIE.readyState) = "complete" Or $oIE.readyState = 4)
        Sleep(100)
    WEnd
    While Not (String($oIE.document.readyState) = "complete" Or $oIE.document.readyState = 4)
        Sleep(100)
    WEnd

    $oIE.document.Write(_GetHTML()) ; inject lising directly to the HTML document:
    $oIE.document.close() ; close the write stream
    $oIE.document.execCommand("Refresh")
    While Not String($oIE.readyState) = 'complete' ; wait for readyState after a refresh
        Sleep(100)
    WEnd
    ; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
    ; $ohJS is a reference to the javascript Global Obj
    ; -------------------------------------------------
    $ohJS = $oIE.document.parentwindow.JSglobal
    $oDocument = $oIE.document

    Local $oTable1 = $ohJS.table1
    Local $oTable2 = $ohJS.table2

    _Randomize($aScientists, $oTable1)

    ; --- Setup events ------------
    ; https://msdn.microsoft.com/en-us/library/hh801967(v=vs.85).aspx
    Local $aoEventObject[2]
    $aoEventObject[0] = ObjEvent($oTable1, "IEEvent_", "HTMLTableEvents2")
    $aoEventObject[1] = ObjEvent($oTable2, "IEEvent_", "HTMLTableEvents2")
    ; -----------------------------
    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch

        If $iCorrect = $iGoal Then
            _Goal()
            _Randomize($aScientists, $oTable1)
            $iCorrect = 0
        EndIf

    WEnd
    ; the end
    For $i = 0 To UBound($aoEventObject) - 1
        $aoEventObject[$i] .stop
    Next
    $aoEventObject = 0 ; Kill the Event Object
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUI) ; Remove GUI
EndFunc   ;==>Example

; --- event management zone ---
; following functions are fired by events occurred in the browser control

Volatile Func IEEvent_onDragstart($oEvent)
    ; we save the ID of the dragged obj into the $sDroping variable
    ; for a later use in the drop function
    $sDroping = $oEvent.srcElement.ID
EndFunc   ;==>IEEvent_onDragstart

Volatile Func IEEvent_onDragOver($oEvent)
    $ohJS.event.preventDefault()
EndFunc   ;==>IEEvent_onDragOver

Volatile Func IEEvent_onDrop($oEvent)
    $ohJS.event.preventDefault()
    If $sDroping <> "" Then
        If $oDocument.getElementById($sDroping).innerText <> $oEvent.srcElement.innerText Then
            If $oEvent.srcElement.ClassName = $oDocument.getElementById($sDroping).ClassName Then
                $oEvent.srcElement.innerText = $oDocument.getElementById($sDroping).innerText
                $oDocument.getElementById($sDroping).innerText = ""
                $oDocument.getElementById($sDroping).draggable = False
                $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #80ff80;"
                $iCorrect += 1
            Else
                For $i = 1 To 3
                    $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #ff0000;"
                    Sleep(125)
                    $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #ffffff;"
                    Sleep(125)
                Next
            EndIf
        EndIf
        $sDroping = ""
    EndIf
EndFunc   ;==>IEEvent_onDrop

Func _Randomize(ByRef $aScientists, ByRef $oTable)
    Local $iRows = ($oTable.rows.length) - 1
    Local $iCols = ($oTable.rows.item(0).cells.length) - 1
    Local $index
    _ArrayShuffle($aScientists)
    For $y = 0 To $iRows
        For $x = 0 To $iCols
            $index = ($y * ($iCols + 1)) + $x
            $oTable.rows.item($y).cells.item($x).innerText = $aScientists[$index][0] ; text
            $oTable.rows.item($y).cells.item($x).className = $aScientists[$index][1] ; class
            $oTable.rows.item($y).cells.item($x).draggable = $aScientists[$index][0] <> ""
        Next
    Next
EndFunc   ;==>_Randomize

Func _Goal()
    Local $oTable1 = $ohJS.table1 ; names
    Local $oTable2 = $ohJS.table2 ; photos
    Local $iRows = ($oTable1.rows.length)
    Sleep(250)
    Local $iCols = 6 ; ($oTable1.rows.item(0).cells.length)
    Local $aIndex[$iRows * $iCols], $sTemp
    For $i = 0 To UBound($aIndex) - 1
        $aIndex[$i] = $i ; + 1
    Next
    _ArrayShuffle($aIndex)
    For $i = 0 To UBound($aIndex) - 1
        $oTable2.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).innerText = ""
        $oTemp0 = $oTable2.rows
        $oTemp1 = $oTemp0.item(Int($aIndex[$i] / $iCols)).cells
        $oTemp2 = $oTemp1.item(Mod($aIndex[$i], $iCols)).getAttribute("style")
        $oTable2.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: " & _rndColor()
        Sleep(100); MsgBox(0,"Debug",$sTemp)
        $oTable2.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = $oTemp2
    Next
    For $x = 1 To 2
        For $i = 0 To UBound($aIndex) - 1
            $oTable1.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: " & _rndColor()
            Sleep(100)
            $oTable1.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: #ffffff;"
        Next
    Next
EndFunc   ;==>_Goal

Func _rndColor()
    Return String("#" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & ";")
EndFunc   ;==>_rndColor

Func _GetHTML()
    Local $sHTML = _
            "<!DOCTYPE HTML>" & @CRLF & _
            "<html>" & @CRLF & _
            "<head>" & @CRLF & _
            "<meta http-equiv=""X-UA-Compatible"" content=""IE=edge"" />" & @CRLF & _
            "   <script type=""text/javascript"">" & @CRLF & _
            "       var JSglobal = (1,eval)(""this"");" & @CRLF & _
            "   </script>" & @CRLF & _
            "</head>" & @CRLF & _
            "<body>" & @CRLF & _
            "<h2>Who is who?</h2>" & @CRLF & _
            "<p>Drag&Drop names on the right scientist</p>" & @CRLF & _
            "<img src=""https://i.imgur.com/STWql7w.jpg""" & @CRLF & _
            "height=""394"" width=""640""" & @CRLF & _
            "style=""position: absolute; left: 10px; top: 100px;"">" & @CRLF & _
            "" & @CRLF & _
            "<style>" & @CRLF & _
            ".target td {width: 100px; height: 160px; text-align: center; color: white; font-weight: bold; vertical-align: bottom; border: 0px solid grey;}" & @CRLF & _
            ".source td {width: 100px; height: 30px; text-align: center; border: 1px solid red;}" & @CRLF & _
            "</style>" & @CRLF & _
            "" & @CRLF & _
            "<table class=""target"" style=""position: absolute; left: 25px; top: 100px;"" id=""table2"">" & @CRLF & _
            "    <tr><td class=""Schrodinger""></td><td class=""Planck""></td><td class=""Pauli""></td><td class=""Einstein""></td><td class=""Chimp""></td><td class=""Dirac""></td></tr>" & @CRLF & _
            "    <tr><td class=""Heisenberg""></td><td class=""Born""></td><td class=""De_Broglie""></td><td class=""Bohr""></td><td class=""Sommerfeld""></td><td class=""empty""></td></tr>" & @CRLF & _
            "</table>" & @CRLF & _
            "" & @CRLF & _
            "<table class=""source"" style=""position: absolute; left: 10px; top: 504px;"" id=""table1"">" & @CRLF & _
            "    <tr><td ID=""td1""></td><td ID=""td2""></td><td ID=""td3""></td><td ID=""td4"" ></td><td ID=""td5"" ></td><td ID=""td6"" ></td></tr>" & @CRLF & _
            "    <tr><td ID=""td7""></td><td ID=""td8""></td><td ID=""td9""></td><td ID=""td10""></td><td ID=""td11""></td><td ID=""td12""></td></tr>" & @CRLF & _
            "</table>" & @CRLF & _
            "</body>" & @CRLF & _
            "</html>"
    Return $sHTML
EndFunc   ;==>_GetHTML

 

Edited by Chimp
little correction on the red flash effect on error when dropping on wrong scientist

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Where is "Doctor Who" ? ;)

 

Signature beginning:
* Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
* ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * 

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * 

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors  * HTML editor * 

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

19 hours ago, wysocki said:

Brilliant piece of work!

Thanks :)

19 hours ago, wysocki said:

Newb question about coding technique though: Why put mainline code in a function instead of just inline?

Example()
Exit

Func Example()

 

Is in this way to better separate the scope of Local and Global variables
.. for a better explanation have a look here: https://www.autoitscript.com/wiki/Best_coding_practices#Scopes_of_Variables

p.s.

I've made a little variation in the script so to wait a ready state after a page refresh.

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

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

×
×
  • Create New...