JockoDundee Posted October 28, 2020 Share Posted October 28, 2020 I’m creating a front-end for the LC0 chess engine via the UCI protocol*. To model the board I am using a simple 2-d 8x8 array. But I am using Enums with number named identifiers, to make the array correspond with the standard algebraic notation used in chess. tldr; Are there any reasons NOT to do the following; Local Enum $a, $b, $c, $d, $e, $f, $g, $h Local Enum $8, $7, $6, $5, $4, $3, $2, $1 Local $board[8][8] $board[$a][$1]="rook" *ICYWW, game creation, not game automation. Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
pseakins Posted October 28, 2020 Share Posted October 28, 2020 You can test this for yourself by adding an _ArrayDisplay() debug statement. You will see that while it works, because the array is zero based your rook ends up at 7, 0 which may not be what you want. #include <Array.au3> Local Enum $a, $b, $c, $d, $e, $f, $g, $h Local Enum $8, $7, $6, $5, $4, $3, $2, $1 Local $board[8][8] $board[$a][$1]="rook" _ArrayDisplay($board) Phil Seakins Link to comment Share on other sites More sharing options...
JockoDundee Posted October 28, 2020 Author Share Posted October 28, 2020 4 minutes ago, pseakins said: because the array is zero based your rook ends up at 7, 0 which may not be what you want. Do you mean 0,7? It should be at 0,7. 0,7 in the array corresponds to chess notation a1 (when the player is playing the white pieces,) Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
pseakins Posted October 28, 2020 Share Posted October 28, 2020 (edited) Row 0, Column 7 Did you try running the code for yourself? Edited October 28, 2020 by pseakins JockoDundee 1 Phil Seakins Link to comment Share on other sites More sharing options...
JockoDundee Posted October 28, 2020 Author Share Posted October 28, 2020 22 minutes ago, pseakins said: Did you try running the code for yourself? Yes, I am already using the array. I know that it works as far as that is concerned. What I am worried about is some unintended consequence using integers as identifiers for other integers. I come from a C/Java background, and since there is no $ token to distinguish variables from literals, it’s not even an option there. That said I haven’t come across anyone doing it in autoit yet. Probably cuz there wasn’t a good enough reason. Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
spudw2k Posted October 28, 2020 Share Posted October 28, 2020 I don't think there is any issue doing that, but I would recommend making the variable name a little more meaningful. For your purposes, you know what they mean, so do as you wish; but if it were me, I might do something like this. #include <Array.au3> Local Enum $eColA, $eColB, $eColC, $eColD, $eColE, $eColF, $eColG, $eColH, $eColSize Local Enum $eRow8, $eRow7, $eRow6, $eRow5, $eRow4, $eRow3, $eRow2, $eRow1, $eRowSize Local $aBoard[$eColSize][$eRowSize] $aBoard[$eRow1][$eColA]="rook" _ArrayDisplay($aBoard) You'll notice a few small changes; Added a prefix to each variable (following best coding practices formats) to make the variable names more meaningful to coders. Added 9th variable at the end of the Enum statements to simplify the array defining. Changed Row and Col dimensions of the array, which is is what @pseakins was trying to illustrate (totally optional since array is a square as long as you are consistent with which dimension is which--but if you ever need or want to use _ArrayDisplay to view the contents, swapping them as I did makes ArrayDisplay represent the "real" board, better. JockoDundee 1 Spoiler Things I've Made: Always On Top Tool ◊ AU History ◊ Deck of Cards ◊ HideIt ◊ ICU ◊ Icon Freezer ◊ Ipod Ejector ◊ Junos Configuration Explorer ◊ Link Downloader ◊ MD5 Folder Enumerator ◊ PassGen ◊ Ping Tool ◊ Quick NIC ◊ Read OCR ◊ RemoteIT ◊ SchTasksGui ◊ SpyCam ◊ System Scan Report Tool ◊ System UpTime ◊ Transparency Machine ◊ VMWare ESX Builder Misc Code Snippets: ADODB Example ◊ CheckHover ◊ Detect SafeMode ◊ DynEnumArray ◊ GetNetStatData ◊ HashArray ◊ IsBetweenDates ◊ Local Admins ◊ Make Choice ◊ Recursive File List ◊ Remove Sizebox Style ◊ Retrieve PNPDeviceID ◊ Retrieve SysListView32 Contents ◊ Set IE Homepage ◊ Tickle Expired Password ◊ Transpose Array Projects: Drive Space Usage GUI ◊ LEDkIT ◊ Plasma_kIt ◊ Scan Engine Builder ◊ SpeeDBurner ◊ SubnetCalc Cool Stuff: AutoItObject UDF ◊ Extract Icon From Proc ◊ GuiCtrlFontRotate ◊ Hex Edit Funcs ◊ Run binary ◊ Service_UDF Link to comment Share on other sites More sharing options...
JockoDundee Posted October 28, 2020 Author Share Posted October 28, 2020 2 hours ago, spudw2k said: I don't think there is any issue doing that, but I would recommend making the variable name a little more meaningful. Thanks for your suggestions, they are very reasonable and understandable However, I think perhaps I could have done better explaining what I was trying to achieve initially. Right off, let me state that if I were a contract programmer working on this project for hire, and knew little about chess, there would be no need for any of this, a straight 0-7 2d array is totally clear. The thing is that I am an experienced player as well. Every square has a name, and I “know” where they all are without even looking at a board. I know that a knight on b1 can get to the other side of the board via c3 d5 f6 and e8 as quickly as I could type it. So, in chess notation, the column (or file) comes first, followed by the row (or rank). Therefore, it is the whole point of the exercise to end up where I can simply refer to a square as $board[$b][$6] and have it do the translation to 1,2. In other words, b6 has meaning to me, 1,2 not so much. In fact it took me several seconds just to translate it and confirm it right now. I was mostly worried about potential technical problems; the caveat about _ArrayDisplay is a good example of that. Thanks! Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
water Posted October 28, 2020 Share Posted October 28, 2020 You could use Maps (latest Beta version of Autoit is needed) to do things like this: Global $mBoard[] $mBoard["b1"] = "King" MsgBox(0, "", $mBoard.b1) My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
pseakins Posted October 28, 2020 Share Posted October 28, 2020 1 hour ago, JockoDundee said: the whole point of the exercise to end up where I can simply refer to a square as $board[$b][$6] There's nothing wrong with this notation (variable naming) if you are happy with it and it's clearer in your mind. As @spudw2k pointed out, the AutoIt community has guidelines for variable and function naming but there is no need to adhere to them, particularly if it makes coding more difficult for you. Thanks for your clarification @spudw2k. I don't know anything about the Maps feature that @water refers to but it looks like it may be very useful. Phil Seakins Link to comment Share on other sites More sharing options...
JockoDundee Posted October 28, 2020 Author Share Posted October 28, 2020 7 hours ago, water said: You could use Maps (latest Beta version of Autoit is needed) to do things like this: Yes, that’s worth considering here, and for other applications as well. Thanks. Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
Gianni Posted October 29, 2020 Share Posted October 29, 2020 (edited) My 2 Cents: you could also create a small function to convert "chess notation" to "array coordinates" for the 8x8 array. in this small example script I wrote: the _ConvertCoords() function which accepts a chess notation and returns a 2-element array with the corresponding row and column coordinates for the 8x8 array the _BoardSet() and _BoardGet() functions to show how you can use it. The _Example() function uses the 3 functions above to initialize the 'chessboard' (the array) at the starting position. Just for fun I used Unicode symbols (for black chess) but of course you can insert whatever string is more appropriate into the array expandcollapse popup#include <Array.au3> ; For _ArrayDisplay() #include <StringConstants.au3> Global $board[8][8] Global Enum $iRow, $iCol ; 0, 1 Global Enum $iFile, $iRank Global $WhiteChess = ObjCreate("Scripting.Dictionary") $WhiteChess.add('King', ChrW(9812)) $WhiteChess.add('Queen', ChrW(9813)) $WhiteChess.add('Rook', ChrW(9814)) $WhiteChess.add('Bishop', ChrW(9815)) $WhiteChess.add('Knight', ChrW(9816)) $WhiteChess.add('Pawn', ChrW(9817)) Global $BlackChess = ObjCreate("Scripting.Dictionary") $BlackChess.add('King', ChrW(9818)) $BlackChess.add('Queen', ChrW(9819)) $BlackChess.add('Rook', ChrW(9820)) $BlackChess.add('Bishop', ChrW(9821)) $BlackChess.add('Knight', ChrW(9822)) $BlackChess.add('Pawn', ChrW(9823)) _Example() Func _Example() _BoardSet('a8', $BlackChess.item('Rook')) _BoardSet('b8', $BlackChess.item('Knight')) _BoardSet('c8', $BlackChess.item('Bishop')) _BoardSet('d8', $BlackChess.item('Queen')) _BoardSet('e8', $BlackChess.item('King')) _BoardSet('f8', $BlackChess.item('Bishop')) _BoardSet('g8', $BlackChess.item('Knight')) _BoardSet('h8', $BlackChess.item('Rook')) _BoardSet('a7', $BlackChess.item('Pawn')) _BoardSet('b7', $BlackChess.item('Pawn')) _BoardSet('c7', $BlackChess.item('Pawn')) _BoardSet('d7', $BlackChess.item('Pawn')) _BoardSet('e7', $BlackChess.item('Pawn')) _BoardSet('f7', $BlackChess.item('Pawn')) _BoardSet('g7', $BlackChess.item('Pawn')) _BoardSet('h7', $BlackChess.item('Pawn')) _BoardSet('a2', 'Pawn') ; $WhiteChess.item('Pawn')) _BoardSet('b2', 'Pawn') ; $WhiteChess.item('Pawn')) _BoardSet('c2', 'Pawn') ; $WhiteChess.item('Pawn')) _BoardSet('d2', 'Pawn') ; $WhiteChess.item('Pawn')) _BoardSet('e2', 'Pawn') ; $WhiteChess.item('Pawn')) _BoardSet('f2', 'Pawn') ; $WhiteChess.item('Pawn')) _BoardSet('g2', 'Pawn') ; $WhiteChess.item('Pawn')) _BoardSet('h2', 'Pawn') ; $WhiteChess.item('Pawn')) _BoardSet('a1', 'Rook') ; $WhiteChess.item('Rook')) _BoardSet('b1', 'Knight') ; $WhiteChess.item('Knight')) _BoardSet('c1', 'Bishop') ; $WhiteChess.item('Bishop')) _BoardSet('d1', 'Queen') ; $WhiteChess.item('Queen')) _BoardSet('e1', 'King') ; $WhiteChess.item('King')) _BoardSet('f1', 'Bishop') ; $WhiteChess.item('Bishop')) _BoardSet('g1', 'Knight') ; $WhiteChess.item('Knight')) _BoardSet('h1', 'Rook') ; $WhiteChess.item('Rook')) _ArrayDisplay($board) MsgBox(0, 'a1', "in a1 there is: " & _BoardGet('a1')) EndFunc ;==>_Example ; set a 'piece' on the board ; -------------------------- Func _BoardSet($sSquare, $vPiece) Local $xy = _ConvertCoords($sSquare) $board[$xy[$iRow]][$xy[$iCol]] = $vPiece EndFunc ;==>_BoardSet ; get the content of a square ; --------------------------- Func _BoardGet($sSquare) Local $xy = _ConvertCoords($sSquare) Return $board[$xy[$iRow]][$xy[$iCol]] EndFunc ;==>_BoardGet ; convert chess notation to Array coordinates ; =========================================== Func _ConvertCoords($sSquare) Local $aTemp = StringSplit($sSquare, "", $STR_NOCOUNT) Local $aRowCol[2] $aRowCol[$iCol] = StringInStr("abcdefgh", $aTemp[$iFile]) - 1 $aRowCol[$iRow] = 8 - Number($aTemp[$iRank]) Return $aRowCol EndFunc ;==>_ConvertCoords Edited October 30, 2020 by Chimp seadoggie01 and JockoDundee 1 1 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
JockoDundee Posted October 30, 2020 Author Share Posted October 30, 2020 10 hours ago, Chimp said: The _Example() function uses the 3 functions above to initialize the 'chessboard' (the array) at the starting position. Just for fun I used Unicode symbols (for black chess) but of course you can insert whatever string is more appropriate into the array Nice. Typically, when specifying chess positions, (as opposed to moves), the convention is to use majuscule letters for white and minuscule for black, code wise you can take a white Bishop and make it black by: Chr(Asc(“B”)+32) Similarly, for the file to column conversion I have done something like: (not tested) $aRowCol[$iCol] = Int(Chr(Asc($aTemp[$iFile])-48)) But that’s nowhere near as clever as: $aRowCol[$iCol] = StringInStr("abcdefgh", $aTemp[$iFile]) - 1 Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
JockoDundee Posted October 30, 2020 Author Share Posted October 30, 2020 Fwiw, another example of unintended consequences of remapping Enums to Integer identifiers just came up... so we had: Local Enum $a, $b, $c, $d, $e, $f, $g, $h Local Enum $8, $7, $6, $5, $4, $3, $2, $1 Local $board[8][8] Now, when I try to use something normal like: For $rank = $1 To $8 it doesn’t work because $1 > $8. Of course there’s always: Local Enum $One=-1 For $rank = $1 To $8 Step $One but maybe things are getting out of hand here... seadoggie01 1 Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
seadoggie01 Posted October 30, 2020 Share Posted October 30, 2020 8 hours ago, JockoDundee said: maybe things are getting out of hand here... I think so... maybe just use some comments? This reminds of defining things in C to be other pre-defined things. We're going to need a script to translate your code into "real code" pretty soon All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
JockoDundee Posted October 30, 2020 Author Share Posted October 30, 2020 54 minutes ago, seadoggie01 said: maybe just use some comments? Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
seadoggie01 Posted November 1, 2020 Share Posted November 1, 2020 To each their own I suppose, but don't ask me to read your code! All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
seadoggie01 Posted November 1, 2020 Share Posted November 1, 2020 (edited) <Snip> Edited November 1, 2020 by seadoggie01 Slow internet? Double posted All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
JockoDundee Posted November 1, 2020 Author Share Posted November 1, 2020 1 hour ago, seadoggie01 said: To each their own I suppose, but don't ask me to read your code! If the programmer chooses descriptive function and variable names, and wraps magic numbers, even uncommented code can be easily read by strangers 🤓 Func _Acro_DocDisplay($oPdDoc, $sTitle = Default, $iPage = Default) If IsKeyword($sTitle) Then $sTitle = "" If Not __Acro_ObjCheck($oPdDoc, "PDDoc") Then Return SetError(1, 0, False) Local $oAvDoc = $oPdDoc.OpenAVDoc($sTitle) If Not __Acro_ObjCheck($oAvDoc, "AVDoc") Then Return SetError(2, 0, False) If Not IsKeyword($iPage) Then Local $oPageView = $oAvDoc.GetAVPageView If Not __Acro_ObjCheck($oPageView, "AVPageView") Then Return SetError(3, 0, False) If Not ($oPageView.GoTo($iPage) = -1) Then Return SetError(4, 0, False) EndIf Return $oAvDoc EndFunc ;==>_Acro_DocDisplay Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
seadoggie01 Posted November 1, 2020 Share Posted November 1, 2020 Sure, it can be. But honestly, I wish I'd added more comments when writing that UDF as I seem to edit it every week. You're asking for advice here, so this is mine: use comments instead of variables. I'd rather read an explanation of why a For loop is walking backwards instead of trying to figure out if $One equaling -1 is an error and why there are variables with numbers for names. I think that Chimp's code shows a great workaround for avoiding this entire issue and that would be my personal preference. All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
JockoDundee Posted November 1, 2020 Author Share Posted November 1, 2020 2 hours ago, seadoggie01 said: You're asking for advice here, so this is mine: use comments instead of variables. Fair enough. 2 hours ago, seadoggie01 said: I think that Chimp's code shows a great workaround for avoiding this entire issue and that would be my personal preference. I think that Chimp’s code is good as well, as I have already indicated. Originally, I considered using maps, but was concerned about the overhead involved. Not to add ex post facto requirements as a justification for my decision, but when you doing chess interfaces, a large portion of the code is looping up files and over ranks and doing compares etc. So performance has to be considered. Basically, things like For $row = 0 To 7 For $col = 0 To 7 If $board[$row][$col] = ... Next Next Chimp’s code requires multiple String library calls per usage. So I was looking to maintain the performance of direct array access with more intuitive semantics. I have amended my code thusly: ; These enums allow access to the zero-based board array thru the use of standard ; algebraic notation, such that $board[$h][$1] = $board[7][7] Local Enum $a, $b, $c, $d, $e, $f, $g, $h Local Enum $8, $7, $6, $5, $4, $3, $2, $1 Local $board[8][8] 2 hours ago, seadoggie01 said: I wish I'd added more comments when writing that UDF as I seem to edit it every week. Ok, granted. But you don’t see any value in using descriptive constants for the return codes, for instance? Return SetError(2, 0, False) Code hard, but don’t hard code... 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