Aquarium Scripter - Chess shop from the developers of Rybka 4 ...
Aquarium Scripter - Chess shop from the developers of Rybka 4 ...
Aquarium Scripter - Chess shop from the developers of Rybka 4 ...
- No tags were found...
Transform your PDFs into Flipbooks and boost your revenue!
Leverage SEO-optimized Flipbooks, powerful backlinks, and multimedia content to professionally showcase your products and significantly increase your reach.
http://chessok.com/aqtiki/tiki-print_multi_pages.php1 <strong>of</strong> 144 26.05.2011 19:56<strong>Aquarium</strong> <strong>Scripter</strong><strong>Aquarium</strong> <strong>Scripter</strong> is a s<strong>of</strong>tware that avails anyone to process <strong>Aquarium</strong> data objects ‐ trees and databases in a way you like. It's alike <strong>the</strong> environment Apeculiar things, developed especially for chess data and <strong>Aquarium</strong>.The following manual and tutorial? give a whole overview <strong>of</strong> Aq<strong>Scripter</strong> possibilities, but it's still being developed and new functions are being added.Table <strong>of</strong> ContentsIntroductionBrief IDE overviewMain panelsToolbarsUpper toolbarMiddle and lower toolbarsSome IDE featuresAq<strong>Scripter</strong> TutorialDatabase UsageOpening databaseProcessing a gameComparing tree with databaseAnnotationsVariationsTree UsageOpening a treeSearching positions in treeCopying a treeDedupeEPDFinding endnodesGenerating subtreesJoining treesMarking a nodeMinimaxRecolorRoot NodesGenerating Back MovesCheck TreeImport tree comparisonCompress TreeExport EPDImport EPDExport Subtree to EPD‐fileMultiple MinimaxExport SubtreeImport tree difference
http://chessok.com/aqtiki/tiki-print_multi_pages.php2 <strong>of</strong> 144 26.05.2011 19:56How to work with Tree ConfigurationsTreeConfigurations <strong>of</strong> <strong>Aquarium</strong>How to work with enginesRunning an engineAnalyze <strong>of</strong> timeAnalyze <strong>of</strong> depthAnalyze all <strong>the</strong> linesTest SuiteHow to work with o<strong>the</strong>r useful thingsRegExpXMLTagsAq<strong>Scripter</strong> ManualAq<strong>Scripter</strong> syntaxFormatting<strong>Aquarium</strong> classesCommon classesClass TSNodeInfoClass TSMoveInfoClass TSAnnotationClass TSSearchInfoCommon functionsClasses for processing <strong>Aquarium</strong> data objectsTree classesClass TSTreeScannerClass TSTreeJoinerClass TSTreeConfigurationDatabase classesClass TSDatabaseClass TSGameClass TSGameHeaderClasses for working with <strong>the</strong> enginesClass TSEngineIDeA classesTIDeATaskTIDeAQualityTIdeaProjectInfoTIdeaTreeExpandOptionsTIdeaProlongationOptionsTIdeaRootNodeTIdeaProjectNoteFunctions that work only in IDeAFunctions that work only in IDeA Project viewDelphi classes
http://chessok.com/aqtiki/tiki-print_multi_pages.php3 <strong>of</strong> 144 26.05.2011 19:56Class TObjectListClass TStringListO<strong>the</strong>r ClassesClass TVariantListClass TPropertyListTCustomPropertyClass XMLParserClass TXMLTagClass TRegExprClass TBackgroundEventReleasing objectsProcedures used in <strong>Aquarium</strong> onlyFunctions that work everywhereFunctions that work only in IDeAFunctions that work only in IDeA Project viewFunctions working with GameViewFunctions working in databasePossible problems1 Introduction_2The <strong>Scripter</strong> is designed to provide access to low level <strong>Aquarium</strong> structures using high level implementation. This implementation highlights <strong>the</strong> most imsignificantly worse than usual <strong>Aquarium</strong> performance. Never <strong>the</strong> less <strong>the</strong> speed <strong>of</strong> processing is quite acceptable and higher than that <strong>of</strong> external scriptperformance and ease <strong>of</strong> use.What you'll find now in <strong>Scripter</strong> is <strong>the</strong> first set <strong>of</strong> functions designed for independent processing <strong>of</strong> <strong>Aquarium</strong> data objects. It should be used mainly asdramatic changes after <strong>the</strong> first week <strong>of</strong> its usage. After research stage, we're going to incorporate <strong>Scripter</strong> into various <strong>Aquarium</strong> modes (first <strong>of</strong> all, IDAccess to any <strong>Aquarium</strong> function can be provided in <strong>Scripter</strong>, depending on necessity.<strong>Scripter</strong> language is based on simplified Delphi/Pascal language. Note that Pascal is case‐insensitive. We assume you're familiar with Delphi/Pascal synlanguages). We don't aim to teach you <strong>the</strong> Delphi/Paslanguage syntax, we ra<strong>the</strong>r aim to acquaint you with data structures and functions available for uDelphi tutorialAll <strong>Scripter</strong> classes are incomplete as <strong>of</strong> now. Every class will be populated with at least twice as many methods and events later on.An IDE provides you <strong>the</strong> following possibilities <strong>of</strong> coding and debugging1. Putting breakpoints. Click <strong>the</strong> blue point <strong>of</strong> <strong>the</strong> left side <strong>of</strong> <strong>the</strong> page to put a breakpoint2. Running a script line‐by‐line without going into procedures. Press F8 to go to <strong>the</strong> next line3. Running a script line‐by‐line and going into procedures. Press F7 for it.4. Making user variables. Press Debug‐User variables to add a new string variable, that will be used in any script you like. It's worth creating variables th
http://chessok.com/aqtiki/tiki-print_multi_pages.php4 <strong>of</strong> 144 26.05.2011 19:565. To clear console, type clear; in script or press View‐Clear ConsoleColoring used to highlight <strong>Scripter</strong> language constructs in this manual:ReadGame(Index: integer): TSDataBaseGame – procedures/functions and types/return typesDelete ‐ methodsMove – read‐only propertiesColor – read/write propertiesmcNone – constantsOnInit – event identifiersfunction(): boolean – event pr<strong>of</strong>iles2 Brief IDE overviewAq<strong>Scripter</strong> IDE is a full environment for writing scripts. It has all <strong>the</strong> features needed to debug and write scripts ‐ debug, breakpoints and watches, consTable <strong>of</strong> contentsMain panelsToolbarsUpper toolbarMiddle and lower toolbarsSome IDE features2.1 Main panelsThis is an IDE <strong>of</strong> 3.11 beta‐version, but it won't change much by <strong>the</strong> release
http://chessok.com/aqtiki/tiki-print_multi_pages.php5 <strong>of</strong> 144 26.05.2011 19:56Aq<strong>Scripter</strong> IDEThe main panel is Source. Here you write <strong>the</strong> code <strong>of</strong> your script. To <strong>the</strong> left <strong>of</strong> it <strong>the</strong>re's a column. In this column <strong>the</strong> number <strong>of</strong> every line is printed. ASome words about breakpointsCode with numbers and breakpointsA red circle <strong>of</strong> a breakpoint (on lines 16 and 20 here) stops <strong>the</strong> script on <strong>the</strong> line, so you can see inspect your code. It helps debugging much.Object inspector is a very helpful thing, it allows you manage variables and objects <strong>of</strong> <strong>the</strong> code. For example, it stores a list <strong>of</strong> variables
http://chessok.com/aqtiki/tiki-print_multi_pages.php6 <strong>of</strong> 144 26.05.2011 19:56Variables in object inspectorAnd double‐click on any variable locates it in <strong>the</strong> source panel.Console is a panel used for printing debug information or information that won't be saved after leaving Aq<strong>Scripter</strong>. To print something in Console, priUsing print commandStatus bar and progress bar are situated in <strong>the</strong> very bottom <strong>of</strong> <strong>the</strong> IDEStatus bar and progress barStatus bar consists <strong>of</strong> 7 panels. In <strong>the</strong> first <strong>the</strong>re're current row and column. In <strong>the</strong> second <strong>the</strong> type <strong>of</strong> source‐writing is displayed: Insert or overwrite.display, whe<strong>the</strong>r NumLock (NUM), CapsLock(CAP) or ScrollLock(SCRL) are pressed. The seventh panel contains progress bar. You can set a progress b2.2 ToolbarsLet's look more carefully on <strong>the</strong> toolbarsToolbarsTable <strong>of</strong> contentsUpper toolbarMiddle and lower toolbars
http://chessok.com/aqtiki/tiki-print_multi_pages.php7 <strong>of</strong> 144 26.05.2011 19:562.2.1 Upper toolbarThis upper toolbar consists <strong>of</strong> 5 menusFile menu is <strong>the</strong> one working with current script.File menuIt has <strong>the</strong> following functions: New (Creating a new script, shortcut CTRL+N), Open (opening some script, shortcut CTRL+O), Save and Save Asrecently opened scripts (Recent).Edit menu is used to edit <strong>the</strong> scripts. Toge<strong>the</strong>r with <strong>the</strong> common functions, as Undo (cancelling <strong>the</strong> last actions, shortcut CTRL+Z), CopyEdit menuToge<strong>the</strong>r with Undo, Redo (Shortcut CTRL+ALT+Z), Cut(CTRL+X) and o<strong>the</strong>rs <strong>the</strong>re're such functions as Find (finds a given line in <strong>the</strong> source, shortcut CCTRL+Y), and tabulation functions – Move Left (Moves a whole selection left, shortcut CTRL+U) and Move Right (Moves a whole selection right, short(CTRL+F11) is described below.View menu sets <strong>the</strong> view <strong>of</strong> <strong>the</strong> display. You can hide Console or Object explorer or clear <strong>the</strong> console. Console can also be cleared <strong>from</strong> SourceView menuDebug menu is, maybe, <strong>the</strong> most important here.
http://chessok.com/aqtiki/tiki-print_multi_pages.php8 <strong>of</strong> 144 26.05.2011 19:56Debug menuRun function (shortcut F9) executes a script. Before executing it verifies it and checks syntax. If <strong>the</strong>re're syntax errors, it pops up <strong>the</strong> error messageError message. ExampleThere're two o<strong>the</strong>r methods <strong>of</strong> executing <strong>the</strong> scripts – Step over (F8) that goes through all <strong>the</strong> lines, but doesn't look into functions, and Trace Intoscript up to <strong>the</strong> line where <strong>the</strong> cursor stands. It works as a breakpoint.Run until return (shortcut Shift+F11) executes <strong>the</strong> current script until <strong>the</strong> end <strong>of</strong> a long cycle or procedure. It's useful, for instance, if you are sure that thShow execution point stops <strong>the</strong> script and shows where is it now.Pauseis a pause, <strong>of</strong> course, and Script reset recompiles and rechecks a script.Also, you can add and view watches, special conditions on variables. When this condition is true, it's written in a watch list. Note, that true is ‐1, and faHere variable i equals 1Toggle breakpoint (F5) sets a breakpoint to a current line.
http://chessok.com/aqtiki/tiki-print_multi_pages.php9 <strong>of</strong> 144 26.05.2011 19:56Evaluation featureWhile executing a script, you may like to know, which value has variable now. For this, stop <strong>the</strong> script via breakpoint (or run it by F7 or F8) and drag moThe last menu is Help. It has only two important featuresHelpYou can associate files with .tsc extension with <strong>Scripter</strong> and delete this association. By default, it exists.You may notice, that <strong>the</strong>re's no help or manual. It's true, actually, but instead we have provided direct access <strong>from</strong> Aq<strong>Scripter</strong> to <strong>the</strong> tiki‐pages, that is,Going to <strong>the</strong> manualFind <strong>the</strong> name <strong>of</strong> <strong>the</strong> class (<strong>the</strong>y start with T, e.g. TSTreeScanner) and press CTRL+F1 or Edit – Find URL to fetch help.2.2.2 Middle and lower toolbarsMiddle and lower toolbars is QAT for <strong>the</strong> upper one. Each button has its pair in <strong>the</strong> upper toolbar. Their action are described in hints.Run button is in a circle2.3 Some IDE featuresFor example, you make like to know, what methods can be called for this or that variable. Press CTRL+Space, and a list <strong>of</strong> methods and properties willAutocompletion list
http://chessok.com/aqtiki/tiki-print_multi_pages.php10 <strong>of</strong> 144 26.05.2011 19:563 Aq<strong>Scripter</strong> ExamplesYou can find all <strong>the</strong>se sample scripts also in AScripts directory in <strong>Aquarium</strong> data folderTable <strong>of</strong> contents:Database UsageOpening databaseProcessing a gameComparing tree with databaseAnnotationsVariationsTree UsageOpening a treeSearching positions in treeCopying a treeDedupeEPDFinding endnodesGenerating subtreesJoining treesMarking a nodeMinimaxRecolorRoot NodesGenerating Back MovesCheck TreeImport tree comparisonCompress TreeExport EPDImport EPDExport Subtree to EPD‐fileMultiple MinimaxExport SubtreeImport tree differenceHow to work with Tree ConfigurationsTreeConfigurations <strong>of</strong> <strong>Aquarium</strong>How to work with enginesRunning an engineAnalyze <strong>of</strong> timeAnalyze <strong>of</strong> depthAnalyze all <strong>the</strong> linesTest SuiteHow to work with o<strong>the</strong>r useful things
http://chessok.com/aqtiki/tiki-print_multi_pages.php11 <strong>of</strong> 144 26.05.2011 19:56RegExpXMLTags3.1 How to work with databaseThere’re two classes designed for database usage:TSDatabaseTSGameEvery TSDatabase object represents a chess database (.cdp, .pgn and o<strong>the</strong>rs) and contains a numbers <strong>of</strong> games which can be referenced viaHave a look at basic scripts <strong>of</strong> how to:Open databaseProcess a game:Open databasePrint <strong>the</strong> number <strong>of</strong> gamesRead a gamePrint its header (class TSHeader)Scan it forward and backwardExport information about every node (class TSNodeInfo) in <strong>the</strong> file.Compare tree with database: open a database and process <strong>the</strong> first three games. To begin with, find <strong>the</strong> first node that exists in <strong>the</strong> databasehad chosen <strong>the</strong> best move. If <strong>the</strong> player didn't choose <strong>the</strong> best move, write in a file, o<strong>the</strong>rwise, if <strong>the</strong> difference between evaluations is too signAnnotations This is a very simple script. It reads annotations (class TSAnnotation) to <strong>the</strong> move and writes <strong>the</strong>m.Variations This script shows how to work with annotations: read, add, and delete <strong>the</strong>m3.1.1 Opening database
http://chessok.com/aqtiki/tiki-print_multi_pages.php12 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> 4.0.6vardb: TSDatabase; // Database objectgam: TSGame;// Game objectname: string;// a stringbegin// Create database object// DataPath returns <strong>the</strong> path to <strong>the</strong> directory where <strong>Aquarium</strong> data is storedname := DataPath + 'AScripts\Data\Abases\comment.cdp';db := TSDatabase.Create(name);// if database existsif db.Opened <strong>the</strong>nbegin//print command prints <strong>the</strong> argument in <strong>the</strong> consoleprint( 'Database '+name + ' opened. Games:' + IntToStr(db.Count) );// Read game number 19gam := db.ReadGame(19, true);// if Game was readif gam nil <strong>the</strong>nbeginprint ('game opened: ' + gam.Header.White + '-' + gam.Header.Black + ', ' + gam.Header.Result);gam.Free;endelseShowMessage('Error opening game');endelseShowMessage('Error opening database');// Release database object. Compulsory!!db.Free;end.3.1.2 Processing a game
http://chessok.com/aqtiki/tiki-print_multi_pages.php13 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> 4.0.6//Opening a game and processing it://scanning a game and writing down some info about movesvardb: TSDatabase; // Database objectgam: TSGame;// Game objectf: text; // Text file objecth: TPGNHeader; // Header object// This procedure is assigned for processing moves in //ScanGameForward procedureprocedure OnScan1(gam: TSGame);varsi: TSNodeInfo;begin// si.Number - ply number// si.VarLevel - 0 - main line; 1 - variant for main line;// si.Move - notation <strong>of</strong> <strong>the</strong> movesi := gam.CurrentNode;WriteLn(f, Format('fwd: %.3d [%d]: %s (%s)', [si.Number, si.VarLevel, si.Pos, si.Move]));//writing into a fileend;// This procedure is assigned for processing moves in ScanGameBackward procedureprocedure OnScan2(gam: TSGame);varsi: TSNodeInfo;beginsi := gam.CurrentNode;WriteLn(f, Format('bwd: %.3d [%d]: %s (%s)', [si.Number, si.VarLevel, si.Pos, si.Move]));end;begin// Create database objectname := DataPath + 'Ascripts\Data\Abases\comment.cdp';db := TSDatabase.Create(name);// if database existsif db.Opened <strong>the</strong>nbeginprint('opened');// Create db_script.log fileAssignFile(f, DataPath+'AScripts\data\db.epd');//Make <strong>the</strong> file writableRewrite(f);// Inform about number <strong>of</strong> games in <strong>the</strong> databaseShowMessage(format('%d',[db.Count])+' games');// Read game number 19gam := db.ReadGame(19);if gamnil <strong>the</strong>n//if openedbegin//Creating header objecth:= gam.Header;//prints who played whiteprint (h.White);//Setting OnScan procedure//for evey new processed position
http://chessok.com/aqtiki/tiki-print_multi_pages.php14 <strong>of</strong> 144 26.05.2011 19:563.1.3 Comparing tree with database
http://chessok.com/aqtiki/tiki-print_multi_pages.php15 <strong>of</strong> 144 26.05.2011 19:56//Compares <strong>the</strong> evaluation <strong>of</strong> <strong>the</strong> position in <strong>the</strong> game with <strong>the</strong> one in <strong>the</strong> treeconstDBname = 'AScripts\data\ABases\4_e3_is_better.cdp';TreeName = 'AScripts\DATA\Atrees\cap.hsh';EPDFile = 'AScripts\data\db_tree_combined.epd';vardb: TSDatabase; // Database objectgam: TSGame;//Game objectf: text; // Text file objectt: TSTreeScanner; // Input tree objectni: TSNodeInfo; // List <strong>of</strong> movesposline: string; // Cuurent positionj :integer;//an auxiliry varlines: integer; // number <strong>of</strong> lines saves to file// This procedure is assigned for processing moves in ScanGameForward procedureprocedure OnScan(gm: TSGame); //scanning <strong>the</strong> databasevargmove: string;p:string;mi: TSMoveInfo;si: TSNodeInfo;tmove_score: integer;beginsi := gm.CurrentNode;beginposline := si.Pos;//takes <strong>the</strong> current positionni := t.SearchFEN(posline);//looks for it in <strong>the</strong> treeif (ni nil) <strong>the</strong>nif (ni.Count>0) and (si.Count>0) <strong>the</strong>n //checking that it exists and has movesbegingmove := si.Move;//<strong>the</strong> move <strong>from</strong> mainlinemi := ni.Moves[ni.Sorted[0]];//<strong>the</strong> best move in <strong>the</strong> treetmove_score := mi.cpScore;if gmove mi.Move <strong>the</strong>n// if a player didn't choose <strong>the</strong> best moveif not t.DoMove(mi.Move) <strong>the</strong>n //if <strong>the</strong>re's nowhere to gobeginWriteLn(f, t.CurrentNode.Pos);//writes it to a epd-file fileinc(lines);end;//stop scan if eval itself is too bigif abs(tmove_score)>100 <strong>the</strong>nbegingam.StopScan;end;end;end;end;begin// Create database objectdb := TSDatabase.Create(DBname);//And a tree object//There're folloeing parameters^ path to <strong>the</strong> tree, if it should be read only (here TRUE)//if it could be created by <strong>the</strong> script (here FALSE)//and <strong>the</strong> memory to use (here 128)t := TSTreeScanner.Create(TreeName, True, False, 128);
http://chessok.com/aqtiki/tiki-print_multi_pages.php16 <strong>of</strong> 144 26.05.2011 19:563.1.4 Annotations
http://chessok.com/aqtiki/tiki-print_multi_pages.php17 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> version 4.0.6// Examples how to read and edit annotations in <strong>the</strong> game// The first game <strong>of</strong> Comment.cdp is annotated.constdbName = 'AScripts\Data\ABases\Comment.cdp';vardb: TSDataBase; //database objectgam: TSGame; //game objectsl: TStringList; //list <strong>of</strong> annotationssl1: TStringList;//list <strong>of</strong> annotationsni: TSNodeInfo; //<strong>the</strong> position we work withi: Inetger;ant: TSAnnotation;//annotationbegin//clearing consoleclear;//opening a base. It should be closed in Database mode in <strong>Aquarium</strong>!db := TSDataBase.Create( dbName);//Get<strong>Aquarium</strong>Base - current databaseif not db.Opened <strong>the</strong>nShowMessage('No database found ('+dbName+')')elsebegin //if it is opened//opening <strong>the</strong> first game.gam := db.ReadGame(1);if gam = nil <strong>the</strong>n // if not openedShowMessage('ReadGame failed')elsebegin//getting annotations for <strong>the</strong> current position (first position)ant := gam.Annot;//going to <strong>the</strong> 4 move, stayng after itni := gam.LnGoTo(4, true);//printing FENprint (ni.Pos);//getting <strong>the</strong> move <strong>from</strong> <strong>the</strong> main line and printing itmi := ni.Moves[0];print (mi.Move);// setting Progress Bar with 7 stagesShowProgressBar(7);//setting evaluation 4 centipawns. Returns <strong>the</strong> number <strong>of</strong> a comment (i)i := ant.SetComment(antEval, '4');print(i);//getting all evaluation annotationssl := ant.GetAllCommentsByType(antEval);if sl nil <strong>the</strong>n//printing all lines separation <strong>the</strong>m by commasprint(sl.CommaText);//we should free a stringlistsl.Free;
http://chessok.com/aqtiki/tiki-print_multi_pages.php18 <strong>of</strong> 144 26.05.2011 19:563.1.5 VariationsVariations
http://chessok.com/aqtiki/tiki-print_multi_pages.php19 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> 4.0.6vardb: TSDataBase; //Databasegam: TSGame; //gameni: TSNodeInfo; //node=positionbegin//clearing consoleclear;//creating databasedb := TSDataBase.Create(DataPath + 'Ascripts\Data\abases\comment.cdp');if db.Opened <strong>the</strong>n //if database existsbegin//reading game number 3, games are counted <strong>from</strong> 0//(so in fact it's <strong>the</strong> fourth game)gam := db.ReadGame(3);if gam nil <strong>the</strong>n//if openedbegin//going to <strong>the</strong> first move in <strong>the</strong> mainline//in this case it's <strong>the</strong> same as LnGoToMove(1);//true stands for AfterMove=true//so we have positioned between <strong>the</strong> first and <strong>the</strong> second moves//to make it clear - it's black to moveni := gam.MainLineGoTo(1, true);if ni nil <strong>the</strong>nbegin//printing that move and i's number//Moves are counted <strong>from</strong> 1!print(Format('Move to start: %s, its number %d ', [ni.Move, ni.Number]));//first level variations, adding new line with movesgam.NewLine('b7b5 h2h4');//adding moves to <strong>the</strong> currnt position with numbers before <strong>the</strong>mgam.AddMoves('1.h6h5 2.g2g4', tsNumbers);//second level variationsgam.NewLine('a2a3');//returning to upper lineni:=gam.returnToUpperLine;if ni nil <strong>the</strong>n//if we've returned rightbegin//printing current info:print(Format('Move on which <strong>the</strong> second-line variation hangs: %s, its number %d ', [ni.Move, ni.Number]));//number <strong>of</strong> moves in current lineprint(Format('Moves in <strong>the</strong> current line: %d', [gam.LineCount]));//new line <strong>of</strong> variations <strong>of</strong> second levelgam.NewLine('b2b3');//returning to mainlineni := gam.ReturnToMainLine;if ni nil <strong>the</strong>n //if we've returned rightbegin//total number <strong>of</strong> variations <strong>from</strong> this moveprint(Format('Variations <strong>from</strong> here: %d', [gam.VariationsCount]));//choosing a variationni := gam.SelectLine(0);if ni nil <strong>the</strong>n //if <strong>the</strong>re's such a variationprint(Format('First move in <strong>the</strong> second variation: %s, its number %d ', [ni.Move, ni.Number]));//total number <strong>of</strong> moves in a gameprint(Format('Moves in a game: %d ', [gam.TotalCount]));end;end;end;end;
http://chessok.com/aqtiki/tiki-print_multi_pages.php20 <strong>of</strong> 144 26.05.2011 19:563.2 How to work with treesTree is <strong>the</strong> most common way to store chess information. The tree file has .hsh‐extension. In Aq<strong>Scripter</strong> <strong>the</strong>re're many functions developed especiallypowerful and interesting scripts.So, to open a tree, write <strong>the</strong> following:vart: TSTreeScanner; // Tree objectbegin't' is <strong>the</strong> name <strong>of</strong> <strong>the</strong> tree object, as a parameter to Create function we give a path to <strong>the</strong> tree.Trees consist <strong>of</strong> nodes. Node is a special object <strong>of</strong> class TSNodeInfo, where we store FEN position and an array <strong>of</strong> moves (class TSMoveInfo<strong>the</strong>m in <strong>the</strong> manual.Here is some examples <strong>of</strong> scripts:Script one: opening a tree.Script two: Searching positions in tree.Script three: Copying a tree. This script opens a tree, processes first 6000 nodes, and adds it with all moves to ano<strong>the</strong>r.Script four: DedupeEPD. This is a very simple script that eliminates duplicates <strong>from</strong> epd‐file.Script five: Finding endnodes. This script checks, if a given node is endnode in <strong>the</strong> tree (has no moves after it.)Script six: Joinig trees. We take two trees, join <strong>the</strong>m and write <strong>the</strong> result in a third. Joining parameters are described in <strong>the</strong> script comments.Script seven: Marking a node. It's used if you want to mark some nodes with a Boolean flag – i.e., while scanning to mark that <strong>the</strong> node was pScript eight: Minimax. This script shows <strong>the</strong> usage <strong>of</strong> minimax function. First it unminimax <strong>the</strong> move, that is, writes a wrong evaluation. Than iour trees are minimaxed.Script nine: Recolor. This script works with colors. It opens a tree, sets parameters for scanning and scans it. It does two things – writes <strong>the</strong> numcolor, it's colored red.Script ten: Root Nodes. It is an illustration <strong>of</strong> <strong>the</strong> GetRootNodes function that finds positions in tree that have no parents. The result is writtenScript eleven: Generating Back Moves. It takes a node and generates (adds into a tree) all its possible parents.Script twelve: Check Tree. This is very important if you need to know whe<strong>the</strong>r a tree is normal or corrupted.Script thirteen: Compare Trees Compares two trees and adds nodes and positions <strong>from</strong> <strong>the</strong> first one to <strong>the</strong> result (third)treeScript fourteen: Compress TreeCompresses a tree, eliminating extra nodes and adding linking moves. Note, that a compressed tree might beScript fifteen: Export EPD This scripts takes a tree and exports it to a epd‐fileScript sixteen: Import EPD Makes a tree <strong>from</strong> a given EPD‐file.Script seventeen: Export subtree to EPD This script creates a subtree <strong>from</strong> a given node and exports it to epd‐file. You can use Generate SubtScript eighteen: Multiple minimax Minimaxing a tree <strong>from</strong> a number <strong>of</strong> FEN positionsScript nineteen: Save <strong>from</strong> position Saves a tree <strong>from</strong> a given position as ano<strong>the</strong>r treeScript twenty: Subtract trees Compares 2 trees and adds nodes <strong>from</strong> a first one only to <strong>the</strong> result tree3.2.1 Opening a tree
http://chessok.com/aqtiki/tiki-print_multi_pages.php21 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> 4.0.6vart: TSTreeScanner; // Tree objectbegin// Create tree objectt := TSTreeScanner.Create(DataPath + 'AScripts\Data\ATrees\cap.hsh');// if opened successfullyif t.Opened <strong>the</strong>nbeginShowMessage('opened');endelseShowMessage('not opened');// Release <strong>the</strong> object (close tree file). Don't forget about such thingsend.t.Free;3.2.2 Searching positions in tree
http://chessok.com/aqtiki/tiki-print_multi_pages.php22 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> 4.0.6// Search <strong>the</strong> position in <strong>the</strong> tree and show information about movesvart: TSTreeScanner; // Tree objectni: TSNodeInfo; // List <strong>of</strong> movess1: string; // string, line <strong>of</strong> charactersi: integer; // integer = real numberbegin//clearing consoleclear;// Create tree objectt := TSTreeScanner.Create(DataPath + 'AScripts\Data\ATrees\cap.hsh');// if opened successfullyif t.Opened <strong>the</strong>nbegin// Search some position and fill moves structure if successni := t.SearchFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - ');// if foundif ni nil <strong>the</strong>nbegin//writing <strong>the</strong> first moves1 := ni.Move;// show number <strong>of</strong> moves <strong>from</strong> position, first move in <strong>the</strong> list and its evaluation//ni.Moves - array <strong>of</strong> moves//ni.Moves[0] -f irst move, ni.Moves[1] -s econd move, etc//cpScore - attribute <strong>of</strong> a move//its evaluation in centipawnsShowMessage( format('%d moves <strong>from</strong> <strong>the</strong> position after 1.e4 e5 2.Nf3: 2...%s %d',[ni.Count, s1, ni.Moves[0].cpScore]));//making a first move. It changes current position in a tree!if t.DoMove(ni.Moves[0].Move) <strong>the</strong>nbegin//filling structure for current positionni := t.CurrentNode;//now informationShowMessage( format('%d moves <strong>from</strong> <strong>the</strong> position after 1.e4 e5 2.Nf3: 2...%s 3.%s %d',[ni.Count,s1,ni.Moves[0].Move,ni.Moves[0].cpScore]));end;endelseShowMessage('not found');//Looking for new positionni := t.SearchFEN('rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -');if ni nil <strong>the</strong>n//if foundbegin// using 'with' operator for simplifying access to <strong>the</strong> fieldswith ni.Moves[0] doShowMessage( format('%d moves <strong>from</strong> <strong>the</strong> position after 1.e4 e5: 2.%s %d',[ni.Count,Move,cpScore]));endelseShowMessage('not found');endelse
http://chessok.com/aqtiki/tiki-print_multi_pages.php23 <strong>of</strong> 144 26.05.2011 19:563.2.3 Copying a tree
http://chessok.com/aqtiki/tiki-print_multi_pages.php24 <strong>of</strong> 144 26.05.2011 19:56//Copies 6000 positions <strong>from</strong> one tree into an ano<strong>the</strong>r.varsrc: TSTreeScanner; //source treedst: TSTreeScanner; //destination treecnt: integer; //counter//this function works for every node found while scanning a treeprocedure ProcessNodeSrc(AScanner: TSTreeScanner);vari: integer; //integer, used for a cyclemi: TSMoveInfo; //moveni: TSNodeInfo; //nodebegininc(cnt);//+1 to counter//mod is getting a remainder.if (cnt mod 1000) = 0 <strong>the</strong>n//we print every thousandprint(IntToStr(cnt));if cnt > 6000 <strong>the</strong>nAScanner.StopScan;//limit copying only for first 6000 moveselsebegin//taking a current nodeni := AScanner.CurrentNode;//Adding node to a destination treedst.Add(ni);//Copying all moves and marking <strong>the</strong>m GREENfor i := 0 to ni.Count - 1 dobeginmi := ni.Moves[i];mi.Color := mcGreen;dst.AddMove(mi);end;//Very important - to save destination treedst.Reset;end;end;begin//setting countercnt := 0;print('started');//change directory - for smart inputChDir(InputPath(DataPath+'<strong>Scripter</strong>\Atrees\'));// Create tree objectsrc := TSTreeScanner.Create('cap.hsh');if not src.Opened <strong>the</strong>nShowMessage('Tree not found')elsebeginprint('src opened');//Setting procedure, executed when a node is processedsrc.OnProcessNode := 'ProcessNodeSrc';//destination treedst := TSTreeScanner.Create('out', False, True);
http://chessok.com/aqtiki/tiki-print_multi_pages.php25 <strong>of</strong> 144 26.05.2011 19:563.2.4 DedupeEPD// For <strong>Aquarium</strong> versoin 4.0.6// DedupeEPD is one <strong>of</strong> <strong>the</strong> TreeUtils procedures.// It removes identical lines <strong>from</strong> EPD file.//input EPD file, where duplicates are searched//output EPD file without duplicatesconstinput_epd = 'AScrips\data\EPD\inepd.epd';output_epd = 'AScripts\data\EPD\outepd.epd';vart: TSTreeScanner;ni: TSNodeInfo;begin// Tree is usually used in TreeUitls operations// Any tree you like. It is not used in this operationt:= TSTreeScanner.Create(DataPath+'AScripts\Data\Atrees\idea.hsh');if t.Opened <strong>the</strong>nbegint.DedupeEpd(DataPath+input_epd, DataPath+output_epd) //Dedupe procedureShowMessage('ok')end;//Dot't forgetend;t.Free;3.2.5 Finding endnodes
http://chessok.com/aqtiki/tiki-print_multi_pages.php26 <strong>of</strong> 144 26.05.2011 19:56//This script shows how to use EndNode function for trees//Endnode is a node that has no more positions after it//For <strong>Aquarium</strong> version 4.0.6vart: TStreeScanner; //treeni: TSNodeInfo; //node in treeni1:TSNodeInfo; //node in treebegin//opening a treet := TSTreeScanner.Create(DataPath+'<strong>Scripter</strong>\ATrees\idea.hsh', False);if t.Opened <strong>the</strong>n //if openedbeginprint('opened');//Serachs for FENni := t.SearchFEN('r1bqkbnr/1ppp1ppp/p1n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -');if ninil <strong>the</strong>n //if foundbeginif t.IsEndNode(ni) <strong>the</strong>n//Checks if it's an endnodeprint('Endnode!')elseprint ('Not endnode')endelse //if not foundprint('Position is not found in tree');ni1 := t.SearchFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');if ni1nil <strong>the</strong>n //if foundbeginif t.IsEndNode(ni1) <strong>the</strong>n//Checks if it's an endnodeprint('Endnode!')elseprint ('Not endnode')endelse //if not foundprint('Position is not found in tree');end;t.Free;end.3.2.6 Generating subtrees
http://chessok.com/aqtiki/tiki-print_multi_pages.php27 <strong>of</strong> 144 26.05.2011 19:56vart: TSTreeScanner;//input treeo: TStReeScanner;//output treeout: string; //path to <strong>the</strong> output treeAFen: String; //position <strong>from</strong> where to generateni: TSNodeInfo; //NodeInfo with AFEN poaitioni: integer; //Counter//Scan and count nodesprocedure OnScan(Ascanner: TStreeScanner)varnn: TSNodeInfo;beginnn := Ascanner.CurrentNode;inc(i);end;begint:=TSTreeScanner.Create('Data/Atrees/cap.hsh')if t.Opened <strong>the</strong>nbegini := 0;t.OnProcessNode := 'OnScan';Afen := 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -';t.StartRecursive;print (inttostr(i) + ' positions')//Nodes in <strong>the</strong> whole treeni := t.SearchFEN(AFen);if ni nil <strong>the</strong>nbeginout := 'Data/Atrees/gensub.hsh'print(t.ImportSubtree(out, Afen));//Generate subtree <strong>from</strong> <strong>the</strong> given node, returns integer - number <strong>of</strong> nodesprint('ok');i := 0;//Creating result tree and counting nodes <strong>the</strong>reo := TStreeScanner.Create(out);if o.Opened <strong>the</strong>nbegino.OnProcessNode := 'OnScan';o.StartRecursive;print (inttostr(i) + ' positions');//Number <strong>of</strong> positions in <strong>the</strong> subtree;ShowMessage('ok');end;o.Free;end;end;t.Free;end.3.2.7 Joining trees
http://chessok.com/aqtiki/tiki-print_multi_pages.php28 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> version 4.0.6//Joins 2 trees, similar to TreeUtilsvar// treessrc: TSTreeScanner;att: string;dst: string;beginprint('started');ChDir(InputPath('AScripts\data\ATrees'));//Change directory// Create tree object and open treesrc := TSTreeScanner.Create('cap.hsh');if src.Opened <strong>the</strong>nbeginShowMessage('src opened ok');att := DataPath+'AScripts\data\Atrees'+'idea.hsh';//An attached treedst := DataPath+'AScripts\data\Atrees'+'out.hsh';//A destination=output treesrc.JoinTrees(att, dst, jrJoin, jrJoin, jrJoin, jrJoin, jrJoin, apInter, 128);//Params://att - attached tree//dst - destination tree//Next 6 constants where to take <strong>the</strong> data <strong>from</strong>//Statistics, Evaluations, Moves, Annotation, Variants//Constants for <strong>the</strong>m: jrNo (<strong>from</strong> nowhere) jrJoin(Join), jrSrc(source tree),//jrAtt(Attached tree), jrSrcPrior(priority to source), jrAttPrioprio(prority to attached)//!!!!You cannot join Moves and Stat with jrSrcPrior, jrAttPrior!!!!//Position//Constants for it: apJoin (joined), apSource(source), apInter(Intersection)//Memory to use: integerend;src.Free;//O<strong>the</strong>r trees should not be freed!print('ok');end.3.2.8 Marking a node
http://chessok.com/aqtiki/tiki-print_multi_pages.php29 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> version 4.0.6//Joins 2 trees, similar to TreeUtilsvar// treessrc: TSTreeScanner;att: string;dst: string;beginprint('started');ChDir(InputPath('AScripts\data\ATrees'));//Change directory// Create tree object and open treesrc := TSTreeScanner.Create('cap.hsh');if src.Opened <strong>the</strong>nbeginShowMessage('src opened ok');att := DataPath+'AScripts\data\Atrees'+'idea.hsh';//An attached treedst := DataPath+'AScripts\data\Atrees'+'out.hsh';//A destination=output treesrc.JoinTrees(att, dst, jrJoin, jrJoin, jrJoin, jrJoin, jrJoin, apInter, 128);//Params://att - attached tree//dst - destination tree//Next 6 constants where to take <strong>the</strong> data <strong>from</strong>//Statistics, Evaluations, Moves, Annotation, Variants//Constants for <strong>the</strong>m: jrNo (<strong>from</strong> nowhere) jrJoin(Join), jrSrc(source tree),//jrAtt(Attached tree), jrSrcPrior(priority to source), jrAttPrioprio(prority to attached)//!!!!You cannot join Moves and Stat with jrSrcPrior, jrAttPrior!!!!//Position//Constants for it: apJoin (joined), apSource(source), apInter(Intersection)//Memory to use: integerend;src.Free;//O<strong>the</strong>r trees should not be freed!print('ok');end.3.2.9 Minimax
http://chessok.com/aqtiki/tiki-print_multi_pages.php30 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> version 4.0.6//Joins 2 trees, similar to TreeUtilsvar// treessrc: TSTreeScanner;att: string;dst: string;beginprint('started');ChDir(InputPath('AScripts\data\ATrees'));//Change directory// Create tree object and open treesrc := TSTreeScanner.Create('cap.hsh');if src.Opened <strong>the</strong>nbeginShowMessage('src opened ok');att := DataPath+'AScripts\data\Atrees'+'idea.hsh';//An attached treedst := DataPath+'AScripts\data\Atrees'+'out.hsh';//A destination=output treesrc.JoinTrees(att, dst, jrJoin, jrJoin, jrJoin, jrJoin, jrJoin, apInter, 128);//Params://att - attached tree//dst - destination tree//Next 6 constants where to take <strong>the</strong> data <strong>from</strong>//Statistics, Evaluations, Moves, Annotation, Variants//Constants for <strong>the</strong>m: jrNo (<strong>from</strong> nowhere) jrJoin(Join), jrSrc(source tree),//jrAtt(Attached tree), jrSrcPrior(priority to source), jrAttPrioprio(prority to attached)//!!!!You cannot join Moves and Stat with jrSrcPrior, jrAttPrior!!!!//Position//Constants for it: apJoin (joined), apSource(source), apInter(Intersection)//Memory to use: integerend;src.Free;//O<strong>the</strong>r trees should not be freed!print('ok');end.3.2.10 Recolor
http://chessok.com/aqtiki/tiki-print_multi_pages.php31 <strong>of</strong> 144 26.05.2011 19:56//For Aqurium version 4.0.6//Example <strong>of</strong> changing move colors in <strong>the</strong> tree{<strong>the</strong> folloiwng color constants may be used:mcNone, mcRed, mcGreen, mcBlue, mcOrange}//Results are not saved in <strong>the</strong> treevarcount,// nubmer <strong>of</strong> scanned positionschanged_count: integer; // nubmer <strong>of</strong> changed positionst: TSTreeScanner; // tree objectf: text; // file handle// This procedure is called for every scanned positionprocedure ProcessNode(Ascanner:TStreeScanner);varm: TSMoveInfo; // Move objecti: integer;ni: TSNodeInfo; //Node i\objectbegin//Getting current nodeni := AScanner.CurrentNode;//Writing in a file//a position and a number <strong>of</strong> moves in itwriteln( f, format('%s %d moves ',[ni.Pos,ni.Count]));//clearing a lines := '';//cycle^ processing move by movefor i := 0 to ni.Count - 1 dobeginm := ni.Moves[i]; // Get <strong>the</strong> movecase m.Color <strong>of</strong> //it's like if, but for many cases//printing move with its colormcNone: print(format('None: [%s]; ',[m.Move]));mcRed: print(format('Red (%s); ',[m.Move]));mcGreen: print(format('%s Green; ',[m.Move]));mcBlue: print(format('%s Blue; ',[m.Move]));mcOrange: print(format('%s Orange; ',[m.Move]));end;if m.Color=mcRed <strong>the</strong>n // if it is Redbeginm.Color := mcNone; // make it BlackInc(changed_count); // count it as changedend;end;//writing an empty line into a log-filewriteln( f,'');end;Inc(count);begin// Create tree objectname := DataPath+'AScripts\data\ATrees\colored2.hsh';//Example <strong>of</strong> smart input, to change paths easilyInputQuery('Change Tree', 'Path: ', name);//creating a treet := TSTreeScanner.Create(name);
http://chessok.com/aqtiki/tiki-print_multi_pages.php32 <strong>of</strong> 144 26.05.2011 19:563.2.11 Root Nodes//For <strong>Aquarium</strong> version 4.0.6//This simple script looks for <strong>the</strong> root node <strong>of</strong> <strong>the</strong> tree//Root node=node, that has no parents,//it means, <strong>the</strong>re's no ways to reach such a position in <strong>the</strong> treevart: TStreeScanner; //tree scanneri: integer;sl: TStringlist; //stringlist to write rootnodesbeginclear;//opening a tree, false stands for ReadOnly = false and//ACanCreate=false//<strong>the</strong> tree should exist, we cannot create itt := TSTreeScanner.Create(DataPath + 'AScripts\data\ATrees\cap.hsh', False, False);if t.Opened <strong>the</strong>n //if openedbegin//printingprint('opened');//Generates a StringList <strong>of</strong> root nodessl := t.GetRootNodes;ShowMessage(Format('%d root nodes found', [sl.Count]));//Printing all rootsfor i:=0 to sl.Count-1 doprint (sl.Strings[i]);//releasingsl.Free;end;//one more releasingt.Free;end.3.2.12 Generating Back Moves
http://chessok.com/aqtiki/tiki-print_multi_pages.php33 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> 4.0.6vart:TSTreeScanner;//our treeni: TSNodeInfo;begint := TSTreeScanner.Create(DataPath+'Ascripts\Data\ATrees\idea.hsh', False);if t.Opened <strong>the</strong>nbeginprint ('opened');ni := t.SearchFEN('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -');//Node to generate parentsPif ninil <strong>the</strong>nbeginif t.GenerateBackMoves(ni) <strong>the</strong>n//Generates back movesprint ('Moves Generated')elseprint ('nothing generated');//all back moves already in treeend;end;t.Free;end.3.2.13 Check Tree
http://chessok.com/aqtiki/tiki-print_multi_pages.php34 <strong>of</strong> 144 26.05.2011 19:56// Checking a tree for corruption (like TreeUtils operation)// For <strong>Aquarium</strong> version 4.0.6vart: TSTreeScanner;t_Cor: TSTreeScanner;begin//Open <strong>the</strong> treet := TSTreeScanner.Create('AScripts\Data\Atrees\cap.hsh');t_Cor := TSTreeScanner.Create('AScripts\Data\Atrees\idea_corrupted.hsh');if not t.Opened <strong>the</strong>nprint ('cap tree not found')else //if openedbegin//Checking that tree is not corrupt//returns True when <strong>the</strong> tree is all rightif t.Check <strong>the</strong>nprint ('cap tree is Good!')else {(= if false)}print('cap tree is Bad!');end;if not t_Cor.Opened <strong>the</strong>nprint ('idea_cor tree not found')else //if openedbegin//This tree is deliberately corrupted by <strong>the</strong> <strong>developers</strong>if t_Cor.Check <strong>the</strong>nprint ('idea_cor tree is Good!')else {(= if false)}print('idea_cor tree is Bad!');end;//release <strong>the</strong>m!t.Free;t_cor.Free;end.3.2.14 Import tree comparisonThis script compares two trees and adds to <strong>the</strong> third one <strong>the</strong> positions and moves that exist only in <strong>the</strong> first one.//For <strong>Aquarium</strong> 4.0.6vart: TStreeScanner;begin//creating result TreeScanner, readonly=false, CanCreate = truet := TSTreeScanner.Create(DataPath + 'AScripts\Data\Atrees\out.hsh', false, true);if t.Opened <strong>the</strong>nbegin//comparing, result is <strong>the</strong> number <strong>of</strong> gpositions processedprint(t.ImportTreeComparison(DataPath + 'AScripts\Data\Atrees\nnt.hsh', DataPath + 'AScripts\Data\Atrees\idea.hsh'end;t.Free;end.3.2.15 Compress Tree
http://chessok.com/aqtiki/tiki-print_multi_pages.php35 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> version 4.0.6vart: TStreeScanner;begin//creating result treet := TSTreeScanner.Create(DataPath+'AScripts\Data\Atrees\idea_compressed.hsh', false, true);//if createdif t.Opened <strong>the</strong>nbegin//returns integer - number <strong>of</strong> positions processedprint(t.CompressTree(DataPath + 'AScripts\Data\Atrees\idea.hsh'));end;t.Free;end.3.2.16 Export EPD//For Aq<strong>Scripter</strong> beta version 3.11vart: TStreeScanner;i: integer;epd: String;begin//creating a result treet := TSTreeScanner.Create(DataPath + 'AScripts\Data\Atrees\cap.hsh');if t.Opened <strong>the</strong>nbegin//source tree//file to exportepd := DataPath + 'AScripts\Data\epd\exported.epd'i := t.ExportEPD(epd);print(i);ShowMessage(Format('Export done, see %s, %d positions processed', [epd, i]))end;//releasingt.Free;end.3.2.17 Import EPD
http://chessok.com/aqtiki/tiki-print_multi_pages.php36 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> 4.0.6vart: TStreeScanner;i: integer;epd: String;s: string;beginclear;s := DataPath + 'AScripts\Data\Atrees\cap_out.hsh';t := TSTreeScanner.Create(s, false, true);if t.Opened <strong>the</strong>nbegin//file to importepd :=DataPath + 'AScripts\Data\epd\toimport.epd';i := t.ImportEPD(epd);print(i);ShowMessage(Format('Import done, see %s, %d positions processed', [epd, i]))end;t.Free;end.3.2.18 Export Subtree to EPD‐file// For <strong>Aquarium</strong> version 4.0.6// This tree exports recursivly <strong>the</strong> tree <strong>from</strong> given position// into a epd-fileconstTreeName = 'AScripts\Data\Atrees\cap.hsh';epdFile = 'AScripts\data\EPD\subepd.epd'vart: TStreeScanner;//tree we exprtAFen: string; //fen <strong>from</strong> which to startbegin//opening a treet := TSTreeScanner.Create(TreeName);if t.Opened <strong>the</strong>n//if openedbegin//setting a fenAfen := 'rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -';//setting <strong>the</strong> name <strong>of</strong> <strong>the</strong> epd-file. For better use, it should be empty//parameters are: FEN line, epd-file name,//whe<strong>the</strong>r to export all <strong>the</strong> lines (here TRUE) or onlyt main//what to export - all levaes (here ExAll), or only//internal (exInternal) or only endnodes (exConcluding)//<strong>the</strong> last integers are min and max valuesif t.ExportSubtreeTOEPD(AFen, epdFile, true, 'exAll', -30000, 30000) <strong>the</strong>nShowMessage(Format('Export done, see %s', [epdFile]))elseShowMessage('Export was not done');end;t.Free;end.
http://chessok.com/aqtiki/tiki-print_multi_pages.php37 <strong>of</strong> 144 26.05.2011 19:563.2.19 Multiple Minimax//For Aq<strong>Scripter</strong> beta version 3.11vart: TStreeScanner;sl: TStringList;begint := TSTreeScanner.Create(DataPath+'AScripts\data\Atrees\cap.hsh', false);if t.Opened <strong>the</strong>nbegin//stringlist with FENs <strong>from</strong> that to start minimaxsl := TStringList.Create;//importing <strong>the</strong>m <strong>from</strong> filesl.LoadFromFile(DataPath+'AScripts\Data\EPD\minimax.epd');t.MultipleMinimax(sl);//releasing a stringlistsl.Free;ShowMessage('Minimaxed');end;t.Free;end.3.2.20 Export Subtree//For Aq<strong>Scripter</strong> version beta 3.11vart: TSTReeSCanner;beginclear;//result treet := TSTreeScanner.Create(DataPath +'AScripts\Data\Atrees\out.hsh', false, true);if t.Opened <strong>the</strong>n//params: path to a tree, fenprint(t.ExportSubtree(DataPath+'AScripts\Data\Atrees\cap.hsh', 'r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 wt.free;end.3.2.21 Import tree difference
http://chessok.com/aqtiki/tiki-print_multi_pages.php38 <strong>of</strong> 144 26.05.2011 19:56//For Aq<strong>Scripter</strong> beta version 3.11vart: TSTreeScanner;beginclear;t := TSTreeScanner.Create(DataPath+'AScripts\Data\Atrees\out.hsh', false, true);if t.OPened <strong>the</strong>nbeginif t.ImportTreeDifference(DataPath+'Ascripts\DATA\ATrees\cap.hsh', DataPath+'A<strong>Scripter</strong>\Data\Atrees\idea.hsh') <strong>the</strong>nprint('Import Done')elseprint('Import not done');end;t.Free;end.3.3 How to work with Tree ConfigurationsWe've implemented some features <strong>of</strong> TreeConfiguarions, in class TSTreeConfiguration. They can work with PlayProbability and colors <strong>of</strong> <strong>the</strong> moves. T3.3.1 TreeConfigurations <strong>of</strong> <strong>Aquarium</strong>
http://chessok.com/aqtiki/tiki-print_multi_pages.php39 <strong>of</strong> 144 26.05.2011 19:56//For Aq<strong>Scripter</strong> beta version 3.11//To get it work, copy config and atrees folders <strong>of</strong> <strong>Aquarium</strong> into <strong>the</strong> directory <strong>of</strong> Aq<strong>Scripter</strong>.exevarTSConfig: TSTreeConfiguration;t: TStreeScanner;//we need it only to have a node.ni: TSNodeInfo;begint := TSTreeScanner.Create('data\ATrees\cap.hsh');if t.Opened <strong>the</strong>nbeginni := t.SearchFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -');if ni nil <strong>the</strong>nbeginTSConfig := TSTreeConfiguration.Create('NarrowBook');//OpenConfigTSConfig.SetManualPercent(12, ni, 1);//Set Play Propability percents: percents, nodeinfo, number <strong>of</strong> moveTSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[0]], tmcRed); //Set ColorsTSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[1]], tmcBlue);//nodeinfo, moveinfo, colorTSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[2]], tmcOrange);TSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[3]], tmcGreen);TSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[4]], tmcPurple);t.Reset;ni := t.SearchFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -');if ni nil <strong>the</strong>nbeginprint(inttostr(TSConfig.GetPlayProbabilityPercents(ni, 1)));// get play probability percentprint(inttostr(TSConfig.GetPlayProbabilityPercents(ni, ni.Sorted[0]))); //nodeinfo, move numbverprint(ni.Moves[ni.Sorted[0]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[0]]));//get colorprint(ni.Moves[ni.Sorted[1]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[1]]));//nodeinfo, moveinfoprint(ni.Moves[ni.Sorted[2]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[2]]));print(ni.Moves[ni.Sorted[3]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[3]]));print(ni.Moves[ni.Sorted[4]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[4]]));end;endelseShowMessage('No position!');end;t.Free;TSConfig.Free;end.3.4 How to work with enginesOf course, we couldn't leave Aq<strong>Scripter</strong> without engines. It has a set <strong>of</strong> functions, permitting working with engines. To create an engine object, write thvare: TSEngine; // Engine objectThere are some most common examples:Script one: Running an engine.Script two: Analyze to time. This script shows how to make an engine analyze <strong>the</strong> position for <strong>the</strong> given time.Script three: Analyze to depth. If you want an engine to analyze a position to a certain depth, see <strong>the</strong> following script.
http://chessok.com/aqtiki/tiki-print_multi_pages.php40 <strong>of</strong> 144 26.05.2011 19:56Script four: Analyze all <strong>the</strong> lines. These functions are used when you want to process every line returned by an engine. It has an event structurScript five: test Suite It creates a test for an engine, that it works well enough.3.4.1 Running an enginevare: TSEngine; // Engine objectf: text; // Text file objects: string;begin// Search engine and load itname := DataPath + 'Engines\<strong>Rybka</strong>\1-cpu\w32\<strong>Rybka</strong> 4 w32.exe'e := TSEngine.Create(name);if e.Started <strong>the</strong>nShowMessage('Engine was started.')elsebeginShowMessage('Engine was not started. Please check <strong>the</strong> path '+name);end;e.Free;end.3.4.2 Analyze <strong>of</strong> time
http://chessok.com/aqtiki/tiki-print_multi_pages.php41 <strong>of</strong> 144 26.05.2011 19:56vare: TSEngine; // Engine objectf: text; // Text file objects: string;begin// Search engine and load itname := DataPath + 'Engines\<strong>Rybka</strong>\1-cpu\w32\<strong>Rybka</strong> 4 w32.exe'e := TSEngine.Create(name);if e.Started <strong>the</strong>nbegin// Create 'engine.log' fileAssignFile(f, 'engine.log'); Rewrite(f);// You may use low level UCI commandse.SetPosition('startpos moves c2c4 e7e5');e.SendUciCommand('setoption name hash value 32');// Or higher level commandse.SetIgnoreMoves('g1f3,e2e4,d2d4');// Run analysis for 1 seconds := e.AnalyseToTime(1000);// Write resulting string to fileWriteLn(f, 'Analyse: '+s);CloseFile(f);endelsebeginShowMessage('Engine was not started. Please check <strong>the</strong> path '+name);end;e.Free;end.ShowMessage('Success. See engine.log for <strong>the</strong> results');3.4.3 Analyze <strong>of</strong> depth
http://chessok.com/aqtiki/tiki-print_multi_pages.php42 <strong>of</strong> 144 26.05.2011 19:56vare: TSEngine; // Engine objectbegin// Search engine and load itname := DataPath + 'Engines\<strong>Rybka</strong>\1-cpu\w32\<strong>Rybka</strong> 4 w32.exe'e := TSEngine.Create(name);if e.Started <strong>the</strong>nbegine.SetFen('rnbqkbnr/8/8/8/8/8/8/RNBQKBNR w KQkq -');e.SetIgnoreMoves('');e.AnalyseToDepth(10);WriteLn(f, 'Last response: '+ e.LastResponse);WriteLn(f, 'Last PVLine: '+ e.LastPV);WriteLn(f, 'Last Eval: ' + IntToStr(e.Eval));WriteLn(f, 'Last Depth: ' + IntToStr(e.Depth));WriteLn(f, 'Last Time: ' + IntToStr(e.Time));WriteLn(f, 'Last Nodes ' + IntToStr(e.Nodes));WriteLn(f, 'Last NPS: ' + IntToStr(e.NPS));WriteLn(f, 'Last PV: ' + e.PV);//string!endelsebeginShowMessage('Engine was not started. Please check <strong>the</strong> path '+name);end;e.Free;end.ShowMessage('Success. See engine.log for <strong>the</strong> results');3.4.4 Analyze all <strong>the</strong> lines
http://chessok.com/aqtiki/tiki-print_multi_pages.php43 <strong>of</strong> 144 26.05.2011 19:56vare: TSEngine; // Engine objects: string;procedure OnEngMsg(Sender: TSEngine; AResponse: integer; AValues: TStringList; ACommand: string);beginif Pos('depth 6', ACommand) > 0 <strong>the</strong>nSender.Stop;print(ACommand);end;if AValues.Values['depth'] '' <strong>the</strong>nprint('DP: ' + AValues.Values['depth']);beginclear;// Search engine and load itname := DataPath + 'Engines\<strong>Rybka</strong>\1-cpu\w32\<strong>Rybka</strong> 4 w32.exe';e := TSEngine.Create(name);e.OnEngMsg := 'OnEngMsg';if e.Started <strong>the</strong>nbegin// You may use low level UCI commandse.SetPosition('startpos moves c2c4 e7e5');e.SendUciCommand('setoption name hash value 32');e.AnalyseToDepth(8);endelsebeginShowMessage('Engine was not started. Please check <strong>the</strong> path '+name);end;e.Free;end.3.4.5 Test Suite//For Aq<strong>Scripter</strong> beta version 3.11varRegExp: TRegExpr;s: string;TTag: TXMLTag;e: TSengine;beginclear;s := 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -';e := TSEngine.Create('data\Engines\<strong>Rybka</strong> 3 1-cpu w32.exe', false);if e.Started <strong>the</strong>n//params: type <strong>of</strong> test, EPD, bestmove, mintime <strong>of</strong> analysis, maxtime, mindepth, delay(how long to hold result and evaluatie.TestSuite(tstBestMoveAndEval, s, 'e2e4', 5, 20, 7, 4, 9);print(e.TestRes);e.Free;end.
http://chessok.com/aqtiki/tiki-print_multi_pages.php44 <strong>of</strong> 144 26.05.2011 19:563.5 How to work with o<strong>the</strong>r useful thingsRegular expressionsRegular expressions allow you to process strings. See a description <strong>of</strong> class TRegExpr in our manual.Script one: RegExp.XMLTags.Using this class you can store your data as XML tree. For example, parse <strong>Aquarium</strong> Config files.Script two: XMLTags.For more information, refer to <strong>the</strong> manual, classes TXMLParser and TXMLTag3.5.1 RegExpFor more info on regular expressions look herehttp://en.wikipedia.org/wiki/Regular_expressions
http://chessok.com/aqtiki/tiki-print_multi_pages.php45 <strong>of</strong> 144 26.05.2011 19:56//For <strong>Aquarium</strong> 4.0.6//regular expressions, usage example//Regular expression help to process lines or text//usually used to find out <strong>the</strong> needed information <strong>from</strong> <strong>the</strong> whole text//for example, files with certain extension//Here we process floating-point numbersvarRegExp: TRegExpr; //object that processes expressionss: string; //string to processbegin//Smart entering a numberInputQuery('Enter floating-point number', 'Number (e.g. 3,5 or 5.66)', s);// creating objectRegExp := TRegExpr.Create;// guarantee to free memorytry//-------------Example 1---------------------------//it means: we must find 3 parts in our line => 3 pairs <strong>of</strong> brackets//<strong>the</strong> first and <strong>the</strong> third are integers//<strong>the</strong> second is ei<strong>the</strong>r full stop or commaRegExp.Expression := '(\d+)([.,])(\d+)';// do search; s - source string//Use Exec if you want your expression to be appended to a line once//and ExecNext is used to append it as much times as possible//ExecNext is used only AFTER Execif RegExp.Exec (s) <strong>the</strong>nrepeatprint('Whole number: '+ RegExp.Match[0]); //first match = whole expressionprint('Integer part: '+ RegExp.Match[1]); //second match = first bracketsprint('Divider : '+ RegExp.Match[2]); //third match = second bracketsprint('Fractional part: '+ RegExp.Match[3]);//forth match = third brackets//Substitute is used to put one match instead <strong>of</strong> ano<strong>the</strong>r = exchange matchesprint(RegExp.Substitute('$3$2$1'));until not RegExp.ExecNextelseprint('Entered string doesn''t contain number in required format!');//------------ Example 2-------------------------------//This expression lloks for construction like//anything - am - anything - ; - anythingRegExp.Expression := '.* am (.*);.*';if RegExp.Exec('blablabla; am Ra1; bm e4') <strong>the</strong>nbeginprint('am:' + RegExp.Match[1]); //returns what stayes sfter amend;//------------ Example 3-------------------------------//This expression lloks for construction like//anything - am - anythingRegExp.Expression := '.* am (.*)';if RegExp.Exec('blablabla; am Ra1') <strong>the</strong>nbeginprint('am:' + RegExp.Match[1]); //returns what stayes sfter amend;
http://chessok.com/aqtiki/tiki-print_multi_pages.php46 <strong>of</strong> 144 26.05.2011 19:563.5.2 XMLTags
http://chessok.com/aqtiki/tiki-print_multi_pages.php47 <strong>of</strong> 144 26.05.2011 19:56//Please, before starting a script, specify an AqPath variable://Debug-User VAriables, Add AqPath, <strong>the</strong> VAlue is a path to your <strong>Aquarium</strong> folder//(where Auarium.exe lies). Add a slash after it! For example: C:/Program Files/<strong>Aquarium</strong>/varroot: TXMLtag; //root tagengines: TXMLTag;//engine tagt: TXMLTag;e: TSEngine; //engine objectpath: string; //path to <strong>the</strong> engineAqPath1: string;function GetPath (ATag: TXMLTag): string;beginengines := TXMLTag.Create; //Creating a child tagengines := ATag.FindChild('Engines'); //filling tags with datafor i:=0 to engines.ChildCount-1 dobegint := engines.Children[i];//search throgh all <strong>the</strong> childrenif t.Values['name'] = '<strong>Rybka</strong> 3 w32' <strong>the</strong>n // looking for <strong>the</strong> needed enginebegins := Copy(t.Values['path'], 3, Length(t.Values['path']));//creating a half <strong>of</strong> pathlineresult := AqPath1 + s;//making a path <strong>from</strong> <strong>the</strong> one found in XML and a special user variableend;end;Engines.Free;end;beginpath := '';AqPath1 := 'D:\Petr\Exe\'root := TXMLTag.Create;//creating a tagroot := LoadXML('data/engines.xml'); //loading an XML tree <strong>from</strong> fileif Assigned (root) <strong>the</strong>n //check that succeedpath := GetPath(root);if path '' <strong>the</strong>nbegine := TSEngine.Create(path); //creating an engine objectif e.Started <strong>the</strong>nbeginprint ('engine started');//Starting analyzes := e.AnalyseToDepth(12);//Inserting into an XML tagroot.ClearChildren; //clear <strong>the</strong> root tagroot.TagName := 'Analyse'; //setting a tagname//Creating a first childEngines := TXMLTAg.Create(root);Engines.TagName := 'Engine';Engines.Values['Path'] := path;//Setting values//Creating a "grandchild"t := TXMLTag.Create(Engines);t.Values['an_res'] := s;t.TagName := 'Data';//Setting valuest.Values['Eval']:=e.Eval;t.Values['Depth'] := e.Depth;
http://chessok.com/aqtiki/tiki-print_multi_pages.php48 <strong>of</strong> 144 26.05.2011 19:564 Aq<strong>Scripter</strong> ManualTable <strong>of</strong> contents:Aq<strong>Scripter</strong> syntaxFormatting<strong>Aquarium</strong> classesCommon classesClass TSNodeInfoClass TSMoveInfoClass TSAnnotationClass TSSearchInfoCommon functionsClasses for processing <strong>Aquarium</strong> data objectsTree classesClass TSTreeScannerClass TSTreeJoinerClass TSTreeConfigurationDatabase classesClass TSDatabaseClass TSGameClass TSGameHeaderClasses for working with <strong>the</strong> enginesClass TSEngineIDeA classesTIDeATaskTIDeAQualityTIdeaProjectInfoTIdeaTreeExpandOptionsTIdeaProlongationOptionsTIdeaRootNodeTIdeaProjectNoteFunctions that work only in IDeAFunctions that work only in IDeA Project viewDelphi classesClass TObjectListClass TStringListO<strong>the</strong>r ClassesClass TVariantListClass TPropertyListTCustomProperty
http://chessok.com/aqtiki/tiki-print_multi_pages.php49 <strong>of</strong> 144 26.05.2011 19:56Class XMLParserClass TXMLTagClass TRegExprClass TBackgroundEventReleasing objectsProcedures used in <strong>Aquarium</strong> onlyFunctions that work everywhereFunctions that work only in IDeAFunctions that work only in IDeA Project viewFunctions working with GameViewFunctions working in database4.1 Aq<strong>Scripter</strong> syntaxAq<strong>Scripter</strong> is an instrument to write small programs for <strong>Aquarium</strong>. Look in <strong>the</strong> Tutorial? for <strong>the</strong> examples and most popular scripts, and in <strong>the</strong> list <strong>of</strong> claHere we give a description <strong>of</strong> a syntax used in Aq<strong>Scripter</strong>. It will be familiar to everyone, who has ever worked in Delphi or Pascal.Script structureMain keywordsThe main body <strong>of</strong> script is written between begin and end. keywords:beginSomething happens;end.Procedures and functionsAq<strong>Scripter</strong> supports functions and procedures. They must have a header and be written between begin and end; keywordsprocedure ProcedureOne;beginSomething happens;end;beginend.ProcedureOne;Procedures and functions can have parameters. They must have a specified type (delimited by ':') and are written in brackets after a header, like this:procedure ProcedureOne (AParam: SomeType);beginSomething happens;end;beginend.ProcedureOne(FParam);
http://chessok.com/aqtiki/tiki-print_multi_pages.php50 <strong>of</strong> 144 26.05.2011 19:56Functions, unlike procedures, must have result <strong>of</strong> a specified type. It is written after <strong>the</strong> parameters delimited by ':'. Like this:function FunctionOne(AParam: SomeType): Ano<strong>the</strong>rType;beginSomething happens;Result := Something;end;beginend.AResult := FunctionOne(FParam);VariablesTo work with all this parameters and types, we use variables. They're written after a keyword var. Variables must be <strong>of</strong> specified type, which is writtenfunction FunctionOne(AParam: SomeType): Ano<strong>the</strong>rType;varAvar: SomeType;beginSomething happens;Result := Something;end;If we need a variable for <strong>the</strong> whole script or for main body, it is written in <strong>the</strong> very top <strong>of</strong> <strong>the</strong> page, like this:VarAresult: Ano<strong>the</strong>rType;function FunctionOne(AParam: SomeType): Ano<strong>the</strong>rType;varAvar: SomeType;beginSomething happens;Result := Something;end;beginend.AResult := FunctionOne(FParam);Supported variables are:integer – integerdouble – floating‐point numeralsstring – stringschar – characterstext: text filesBoolean: true and falseFor example:
http://chessok.com/aqtiki/tiki-print_multi_pages.php51 <strong>of</strong> 144 26.05.2011 19:56VarAResult: string;Function FunctionOne(AParam: integer): string;varAvar: string;beginSomething happens;Result := Avar;end;beginend.AResult := FunctionOne(FParam);ClassesCreating objectsAq<strong>Scripter</strong> has a set <strong>of</strong> its own classes, toge<strong>the</strong>r with some auxiliary ones and common Delphi classes. The whole list <strong>of</strong> <strong>the</strong>m is in <strong>the</strong> list <strong>of</strong> classesVarScanner: TSTreeScanner;beginScanner := TSTreeScanner.Create(path);end.Look up in <strong>the</strong> manual <strong>the</strong> full description <strong>of</strong> Create function for every class.Releasing objectsWhen you create an object (and any instance <strong>of</strong> any class, that starts with <strong>the</strong> letter 'T' is an object)m you need to release it, to free memory. For this, FVarScanner: TSTreeScanner;beginScanner := TSTreeScanner.Create(path);Scanner.Free;end.Also note that you need to free an object only after you have stopped working with it. For example, if you have created an object, and <strong>the</strong>n have writtThis is very important for a TSMoveInfo class, because every instance <strong>of</strong> TSNodeInfo class has an array <strong>of</strong> MoveInfos. More info on releasing is inCommon operatorsConditionsThere're two condition operators: if and caseIF is used if you have no more than two possible cases. It has <strong>the</strong> following syntax:For one case, a is a conditionif a <strong>the</strong>nbeginSomething;Something;end;
http://chessok.com/aqtiki/tiki-print_multi_pages.php52 <strong>of</strong> 144 26.05.2011 19:56Begin and end; are compulsory if <strong>the</strong>re're two or more lines between <strong>the</strong>m. If you have only one line, begin and end; can be omitted.For two cases, a is a conditionif a <strong>the</strong>nbeginSomething;Something;endelsebeginSomething;Something;end;Note, that before else you shouldn't put ';' symbol, nei<strong>the</strong>r after end, nei<strong>the</strong>r after a unique line <strong>of</strong> <strong>the</strong> case. Like that:if a <strong>the</strong>nSomethingelseSomething;Case is used if you have more than two cases. It has <strong>the</strong> following syntax:Case a <strong>of</strong>1:something;2:beginsomething;something;end;3: somethingelseSomething;end;Note, that here a should be a variable and 1, 2, 3 are its possible values (so a is a numeral). We have cases for a=1, a=2, a=3 and for all o<strong>the</strong>rs we haveCyclesHere we have three types <strong>of</strong> cycle operators: for, while, and repeat.For operator is used when we know for sure, <strong>from</strong> which value to start and after which to finish. Also, it has a predefined step (1). Example:For i:=0 to 14 doBeginSomething happens 15 times;End;While operator is more flexible. It can be used when you don't know where to stop <strong>the</strong> cycle or if it should be stopped when a certain condition is satis
http://chessok.com/aqtiki/tiki-print_multi_pages.php53 <strong>of</strong> 144 26.05.2011 19:56While not a dobeginSomething happens;end;You can also exchange places <strong>of</strong> cycle and it condition. For this you need repeat operator:repeatSomething;Something;until a>0;No begin and end; is needed here.O<strong>the</strong>r notes1. Every line should be finished with ';' symbol (except <strong>the</strong> one before else)2. To assign a value to a variable, we use ':=' (a:=3;). To create a condition (equals), simply '=' (if a=3 <strong>the</strong>n). For "doesn't equals" condition '' symbol is u3. Boolean values are true and false.4. Negation operator is not. Conjunction operator is and, disjunction operator is or. Operands are written in () brackets5. If an object isn't assigned, it's nil.6. Comments are written a '//' symbol for one‐line comments and between {} brackets for multiline comments8. To print a string on a command line, type 'something'?;.9. To run a script, press F9. To run it line‐by‐line, press F7 and F8.10. You can have ano<strong>the</strong>r script used in <strong>the</strong> current one, e.g. it has some useful procedures you don't want to copy. You can do it by printing on <strong>the</strong> ve{CODE}usesmy_script;{/CODE}And after that you can use <strong>the</strong> procedures <strong>of</strong> that script as if <strong>the</strong>y were in <strong>the</strong> currently opened scriptFor more information on syntax, look in <strong>the</strong> Delphi tutorial4.2 FormatingYou can write you scripts as you like, but to make <strong>the</strong>m readable easily, it's worth following a standard <strong>of</strong> writing, common to <strong>the</strong> users <strong>of</strong> Pascal. The1.2.3.The var, begin and end. operators that are used in <strong>the</strong> whole program, should be printed at <strong>the</strong> beginning <strong>of</strong> <strong>the</strong> line, without spaces or tabulaThe part <strong>of</strong> <strong>the</strong> code between begin and end operators and after var should have one tabulation before.After if, for, etc only code should have tabulations – begin and end should be on <strong>the</strong> same level.Recommendations:1.2.3.Don't put begin and end; for code in cycles and conditions <strong>of</strong> 1 linePut ';' in all ends <strong>of</strong> code, except <strong>the</strong> line before else, conditions and cycles.If you want to print an integer, you should convert it into a string(inttostr command). But if you want to print only an integer, don't convert it.4.3 <strong>Aquarium</strong> classesThis is classes Aq<strong>Scripter</strong> was designed for ‐ <strong>Aquarium</strong> data classes. They have complicated hierarchy, described here:
http://chessok.com/aqtiki/tiki-print_multi_pages.php54 <strong>of</strong> 144 26.05.2011 19:56The links don't mean parent‐child relationship, but availabilityMutual availability exists between:TSDataBase(one instance) and TSDataBaseGame?(many instances)TSNodeInfo(one instance) and TSMoveInfo(many instances)TSMoveInfo(one instance) and TSAnnotation(one instance)One‐direction availability exist betweenTSDataBaseGame?(one instance) and TSHeader(one instance)TSDataBaseGame?(one instance) and TSNodeInfo(many instances)TSTreeScanner(one instance) and TSNodeInfo(many instances)Classes TSEngine, TSTreeJoiner and TSTreeConfiguration are unavailable <strong>from</strong> any o<strong>the</strong>r classes.Table <strong>of</strong> contents:
http://chessok.com/aqtiki/tiki-print_multi_pages.php55 <strong>of</strong> 144 26.05.2011 19:56Common classesClass TSNodeInfoClass TSMoveInfoClass TSAnnotationClass TSSearchInfoCommon functionsClasses for processing <strong>Aquarium</strong> data objectsTree classesClass TSTreeScannerClass TSTreeJoinerClass TSTreeConfigurationDatabase classesClass TSDatabaseClass TSGameClass TSGameHeaderClasses for working with <strong>the</strong> enginesClass TSEngineIDeA classesTIDeATaskTIDeAQualityTIdeaProjectInfoTIdeaTreeExpandOptionsTIdeaProlongationOptionsTIdeaRootNodeTIdeaProjectNoteFunctions that work only in IDeAFunctions that work only in IDeA Project viewDelphi classesClass TObjectListClass TStringListO<strong>the</strong>r ClassesClass TVariantListClass TPropertyListTCustomPropertyClass XMLParserClass TXMLTagClass TRegExprClass TBackgroundEvent4.3.1 Common classes
http://chessok.com/aqtiki/tiki-print_multi_pages.php56 <strong>of</strong> 144 26.05.2011 19:56This classes are labeled as 'Common', because <strong>the</strong>y are used both in Trees and DataBases. Without bounds to <strong>the</strong>se parent classes <strong>the</strong>y loose a big pieTable <strong>of</strong> contents:Class TSNodeInfoClass TSMoveInfoClass TSAnnotationClass TSSearchInfo4.3.1.1 Class TSNodeInfo↑ Is used in: TSDataBaseGame, TSTreeScanner↓ Uses: TSMoveInfoDeclaration:varni: TSNodeInfo;This is <strong>the</strong> class used to store <strong>the</strong> information about a position and to work with it. This information isPropertiesPos: string ‐ <strong>the</strong> FEN position.Exampleni.Pos;Moves[Index: integer]: TSMoveInfo – array <strong>of</strong> moves (<strong>from</strong> 0 to Count‐1). Moves[0]=MoveExampleni.Moves[4].Move;Move: string – main move for notation,that is first move for a tree.Exampleni.Move;Sorted: [Index: integer]:integer – <strong>the</strong> array <strong>of</strong> <strong>the</strong> move indexes sorted by evaluation. Sorted[4] ‐ number <strong>of</strong> <strong>the</strong> forth best move.Exampleni.Sorted[4];//number <strong>of</strong> <strong>the</strong> forth best moveni.Moves[ni.Sorted[0]];//best move
http://chessok.com/aqtiki/tiki-print_multi_pages.php57 <strong>of</strong> 144 26.05.2011 19:56AllMoves[Index: integer]: TSMoveInfo – <strong>the</strong> list <strong>of</strong> all <strong>the</strong> moves available <strong>from</strong> this position.Exampleni.AllMoves[7];//seventh move <strong>from</strong> all that can be done <strong>from</strong> this positionBestMove: TSMoveInfo – returns a move with <strong>the</strong> biggest evaluation. Same as ni.Moves[ni.Sorted0]Examplemi := ni.BestMove;Count: integer – <strong>the</strong> number <strong>of</strong> <strong>the</strong> moves assigned to this node.Exampleni.Count;TotalCount: integer – <strong>the</strong> total number <strong>of</strong> moves <strong>the</strong>oretically available <strong>from</strong> this position.Exampleni.TotalCount;Number: integer – <strong>the</strong> number <strong>of</strong> a move.Exampleni.Number;IsWhite: boolean – side to move.Exampleni.IsWhite//returns true if white to move and false if blackVarLevel: integer – nesting level <strong>of</strong> variation, returns 0 for main level.Exampleni.VarLevel;AllBackPos: TStringList – All backward (parent) positions, that is positions <strong>from</strong> which a given one is available, and linking moves.Examplesl := ni.AllBackPos;//sl is stringlistprint (sl.Strings[0]);//first parentprint (TSMoveInfo(sl.Objects[0]).Move);//a move <strong>from</strong> a parent node to a child node
http://chessok.com/aqtiki/tiki-print_multi_pages.php58 <strong>of</strong> 144 26.05.2011 19:56Score: integer – <strong>the</strong> score <strong>of</strong> a node. Basically it <strong>the</strong> evaluation <strong>of</strong> <strong>the</strong> best move <strong>from</strong> a position, but in some cases <strong>the</strong>se evaluations mExampleni.ScorePositions: integer – <strong>the</strong> number <strong>of</strong> times this position was played (Wins+Loses+Draws).Exampleni.PositionsIsCheckmate: boolean – returns TRUE if a position is a checkmate and FALSE o<strong>the</strong>rwiseExampleif ni.IsCheckmate <strong>the</strong>nIsCheck: boolean – returns TRUE if a position is a check and FALSE o<strong>the</strong>rwiseExampleif ni.IsCheck <strong>the</strong>nIsStalemate: boolean – returns TRUE if a position is a stalemate and FALSE o<strong>the</strong>rwiseExampleif ni.IsStalemate <strong>the</strong>nPlayer: PlayerCol – side to move. Writable. Constants are WhiteCol and BlackColExampleni.PlayerCol := WhiteCol;MethodsCreate[Pos: string = '' ]: TSNodeInfo – Creating a node <strong>from</strong> a given FEN line, by default it's empty. Moves are not added.Exampleni:=TSNodeInfo.Create('r1b2k1r/5pbp/p1pqp3/3P1p2/5P2/2N3R1/P1PQB1PP/1R5K w - - ');Free ‐ Releasing an object. It is needed when you don't need to use this node any more. Note, that if you add it into a List (TObjectListExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php59 <strong>of</strong> 144 26.05.2011 19:56ni.Free;Copy:TSNodeInfo ‐ used to copy one NodeInfo into an ano<strong>the</strong>r, as long as it's prohibited to work, for instance, with two NodeInfos <strong>of</strong>Exampleni1.Copy(ni2);//ni2 is a NodeInfo being copiedAddMove(string): TSMoveInfo – adding a move (TSMoveInfo object) into a TSNodeInfo object. Note, that it doesn't add it into a treeExampleni.AddMove(mi);//mi is TSMoveInfo objectDelete[Index: integer] – Deleting a move (TSMoveInfo object) <strong>from</strong> a TSnodeInfo objectExampleni.Delete[2];//deleting a second moveIndexOf(TSMoveInfo): integer – getting an index <strong>of</strong> a move.Examplei:=ni.IndexOf(mi);//i is integer, mi is TSMoveInfoLocateMove(string): integer – locating a move returns 1 if <strong>the</strong>re's such move in a given node and 0 o<strong>the</strong>rwise.Exampleb:=ni.LocateMove('e2e4');//b is BooleanSearchMove(string): TSMoveInfo – Searching for a move returns TSMoveInfo if a move exists <strong>the</strong> node and nil o<strong>the</strong>rwiseExamplemi := ni.SearchMove('e2e3');//mi is TSMoveInfoNewPosition(TSMoveInfo): string – Getting a EPD string <strong>of</strong> <strong>the</strong> position that will occur after a certain move.Examples := ni.NewPosition(mi);//s is string, mi is TSMoveInfoInvertPlayer: string – Inverting <strong>the</strong> position so that <strong>the</strong> white pieces become black and vv, that means, updise down. Moves are also inExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php60 <strong>of</strong> 144 26.05.2011 19:56fen := ni.InvertPlayer;Usage examplevarni:TSNodeInfo;//creating new variable <strong>of</strong> type TSNodeInfomi:TSMoveInfo;//creating new variable <strong>of</strong> type TSMoveInfomi1:TSMoveInfo;i:integer;b:boolean;s:string;beginni := TSNodeInfo.Create('r1b2k1r/5pbp/p1pqp3/3P1p2/5P2/2N3R1/P1PQB1PP/1R5K w - - ');ni.AddMove('Qd3');ni.AddMove('Qe3');mi := ni.AddMove('Qe1');//here added three moves. white queen <strong>from</strong> d2 to d3, to e3, to e1print(ni.Moves[1].Move);//print move with number 1. Note, <strong>the</strong> numeration started by 0, <strong>the</strong>n first move isni.Delete(1) //delete move with number 1.print(ni.Moves[1].Move);//print move with number 1. First move is white queen <strong>from</strong> d2 to e1, now.i := ni.IndexOf(mi); //save in i index <strong>of</strong> last move (white queen <strong>from</strong> d2 to e1)print(i);print( ni.IndexOf( ni.Moves[0].Move )); //print index <strong>of</strong> zero turn (white queen <strong>from</strong> d2 to d3)mi1 := TSMoveInfo.Create;i := ni.LocateMove('a7a5');//does it exist in treeprint(i);//print -1 if exists, 0 if it doesn'tmi := ni.SearchMove('a3a4');s :=ni.NewPosition(mi);print (ni.Pos);print (ni.Moves[4].Move);print (inttostr(ni.Sorted[4]));print (ni.Moves[ni.Sorted[0]]);//bestmove!print (ni.Move);//main move!print (ni.AllMoves[7]);//seventh move <strong>from</strong> all that can be done <strong>from</strong> this posprint (inttostr(ni.Count));//number <strong>of</strong> played movesprint (inttostr(ni.TotalCount));//number <strong>of</strong> <strong>the</strong>oretically available movesprint (booltostr(ni.IsWhite));print (inttostr(ni.VarLevel));//Level <strong>of</strong> variationprint (inttostr(ni.Positions));//how many games with this positionprint (inttosr(ni.Score));//evaluation <strong>of</strong> nodesl := ni.AllBackPos;print (sl.Strings[0]);//first parentni.Free;end.4.3.1.2 Class TSMoveInfo↑ Is used in: TSNodeInfo↓ Uses: nothingDeclaration:
http://chessok.com/aqtiki/tiki-print_multi_pages.php61 <strong>of</strong> 144 26.05.2011 19:56varmi: TSMoveInfo;This class is used to store <strong>the</strong> information about a move.PropertiesMove: string – Move is a property that returns a string like 'e2e4'. This property is rewritable.Examples := mi.Move;//s is stringScore: integer – Score returns an absolute score <strong>of</strong> a move. Writable.Examplei := mi.Score;//i is IntegerRelScore: integer – RelScore returns a relative score <strong>of</strong> a move. WritableExamplemi1.RelScore := -(mi2.Score);CPScore: integer – CpScore returns an evaluation in centipawns. WritableExamplemi.CpScore := 50;Color: mcBlue – Color returns a move color and is also writable. Constants are: mcNone, mcRed, mcGreen, mcBlue, mcOrangeExamplemi.Color := mcOrange;print(mi.Color);//mcOrange is printedWins: integer – Wins is some statistics: how many wins were made <strong>from</strong> this position. Read‐only.ExamplePrint(mi.Wins);Loses: integer ‐ Losses is a number <strong>of</strong> losses <strong>from</strong> this position. Read‐only.Example
http://chessok.com/aqtiki/tiki-print_multi_pages.php62 <strong>of</strong> 144 26.05.2011 19:56if mi1.Losses > mi2.Lossesprint(mi1.Losses)elseprint(mi2.Losses);Draws: integer – Draws is a number <strong>of</strong> draws <strong>from</strong> a position.Examplemi.Draws;Stat: integer – Total number <strong>of</strong> times this move was played (according to a tree).Examplemi.Stat;Year: integer – tghe year this move was last played in.Examplemi.Year;ELO: integer – The ELO <strong>of</strong> a move.Examplemi.ELO;Level: integer – The evaluation level <strong>of</strong> a move. E.g. 0 means level is ‐+ and eval is <strong>from</strong> 0 to 9.Examplemi.ELO;Usage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php63 <strong>of</strong> 144 26.05.2011 19:56varni:TSNodeInfo;mi:TSMoveInfo;beginclearni := TSNodeInfo.Create('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -');mi := ni.AddMove('e2e4');mi.Score := 35;print('Move: ' + mi.Move);print('Score: '+ inttostr(mi.Score));print('RelScore:' + inttostr(mi.RelScore));print('CpScore: ' +inttostr(mi.CPScore));print('Color: '+inttostr(mi.Color));print('Wins: '+inttostr(mi.Wins));print('Loses: '+inttostr(mi.Loses));print('Draws: '+inttostr(mi.Draws));end.4.3.1.3 Class TSAnnotation^ Is used in: TSGamev Uses: NothingDeclaration:varAnnot:TSAnnotation;The objects <strong>of</strong> this class stores <strong>the</strong> annotations. Annotations are still in development, by now <strong>the</strong>y store information about <strong>the</strong> engine games, but anyMethodsGetAllComments: TStringList ‐ returns all comments in a stringlist. Types <strong>of</strong> comments are in objects.Examplesl := gam.Annot.GetAllComments;//sl is Stringlistif sl nil <strong>the</strong>nprint(sl.CommaText)elseprint ('No more comments');sl.Free;GetAllCommentsByType(AType: Type): TStringList ‐ returns all comments <strong>of</strong> a given type in stringlist.Examplesl := gam.Annot.GetAllCommentsByType(antEval); //sl is Stringlistif sl nil <strong>the</strong>nprint(sl.CommaText);sl.Free
http://chessok.com/aqtiki/tiki-print_multi_pages.php64 <strong>of</strong> 144 26.05.2011 19:56SetComment(AType: Type, AComment: String): integer ‐ sets a comment, returns it number (among comments <strong>of</strong> this type).Examplei := gam.Annot.SetComment(antEval, ScoreToString(20));print(i);SetAllComments(AComments: TStringList) ‐ sets all comments to a move. Types should be in objects.Examplesl := TStringList.Create;sl.AddObject('jeans', antShortBefore);sl.AddObject('fly', antShortAfter);sl.AddObject('tomato', antLongBefore);sl.AddObject('blue', antLongAfter);sl.AddObject(ScoreToString(4), antEval);gam.Annot.SetAllComments(sl);SetAllCommentsByType(AType: Type, AComments: TStringList) ‐ sets all comments <strong>of</strong> a given type.Examplesl := TStringList.Create;sl.Add('mama');sl.Add('papa');gam.Annot.SetAllCommentsByType(antShortBefore, sl);sl.Free;DeleteComment(AType: Type, Anumber: integer) ‐ deletes given comment.Examplegam.Annot.DeleteComment(antShortBefore, i);DeleteAllCommentsByType(AType:Type) ‐ deletes all comments <strong>of</strong> a given type.Examplegam.Annot.DeleteAllCommentsByType(antEval);DeleteAllComments ‐ simply deletes everything.Examplegam.Annot.DeleteAllComments;SearchComment(AType: Type, AComment: String): integer ‐ returns a number <strong>of</strong> a given comment among <strong>the</strong> comments <strong>of</strong> a givenExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php65 <strong>of</strong> 144 26.05.2011 19:56i := gam.Annot.SearchComment(antShortBefore, 'mama');ReplaceComment(Atype: Type, ANumber: Number, Acomment: string) ‐ replacing a comment with a given number with ACommenExamplegam.Annot.ReplaceComment(antShortAfter, i, 'swim');InsertComment(Atype: Type, ANumber: Number, Acomment: string) ‐ – inserting a given comment into a given place.Examplegam.Annot.InsertComment(antLongBefore, 0, 'swim');Usage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php66 <strong>of</strong> 144 26.05.2011 19:56//For Aq<strong>Scripter</strong> version 3.11vardb: TSDataBase;gam: TSGame;sl: TStringList;sl1: TStringList;ni: TSNodeInfo;i: Integer;ant: TSAnnotation;begincleardb := TSDataBase.Create('Data\ABases\Comment.cdp');if db.Opened <strong>the</strong>nbegingam := db.ReadGame(1, true);if gam nil <strong>the</strong>nbeginant := gam.Annot;//setting evaluation for first move (b1c3), printing itni := gam.LnGoTo(4, true);print (ni.Pos);mi := ni.Moves[0];print (mi.Move);ShowProgressBar(7);i := ant.SetComment(antEval, ScoreToString(4));print(i);sl := ant.GetAllCommentsByType(antEval);if sl nil <strong>the</strong>nbeginfor i := 0 to sl.Count - 1 doprint(IntToStr(StringToScore(sl.Strings[i])));sl.Free;end;SetProgress(1);//Deleting eval comment, printing all commentsAnt.DeleteAllCommentsByType(antEval);sl := Ant.GetAllComments;if sl nil <strong>the</strong>nbeginprint(sl.CommaText);sl.Free;endelseprint ('No more comments');SetProgress(2);//Setting all comments <strong>of</strong> 1 type, finding one <strong>of</strong> <strong>the</strong>m, deleting it//and printing what is leftsl := TStringList.Create;sl.Add('mama');sl.Add('papa');gam.Annot.SetAllCommentsByType(antShortBefore, sl);SetProgress(3);sl.Free;i := Ant.SearchComment(antShortBefore, 'mama');Ant.DeleteComment(antShortBefore, i);sl := Ant.GetAllComments;
http://chessok.com/aqtiki/tiki-print_multi_pages.php67 <strong>of</strong> 144 26.05.2011 19:564.3.1.4 Class TSSearchInfo↑ Is used in: Nothing↓ Uses: NothingDeclaration:varsi: TSSearchInfo;It is a very special class used to work with file system(FindFirst, FindNext). It can store <strong>the</strong> name <strong>of</strong> <strong>the</strong> file, <strong>the</strong> time it was last modified, <strong>the</strong> size <strong>of</strong> <strong>the</strong>PropertiesName: string – getting a filename.Examplesi.Name;Time: integer – getting <strong>the</strong> time when <strong>the</strong> file was last modifiedExamplesi.Time;Size: integer – getting a size <strong>of</strong> <strong>the</strong> fileExamplesi.Size;Attr: integer – returns file attributes: faReadOnly, faHidden, faSysFile, faVolumeID, faDirectory, faArchive.Examplesi.AttrMethodsCreate: TSSearchInfo – creates an objectExamplesi := TSSearchInfo.Create;
http://chessok.com/aqtiki/tiki-print_multi_pages.php68 <strong>of</strong> 144 26.05.2011 19:56Free() ‐ releasing an object.ExampleSi.Free;Usage examplevarsi: TSSearchInfo;beginsi := TSSearchInfo.Create;ChDir(InputPath(ExePath));if FindFirst('*.cdp', faAnyFile, si) = 0 <strong>the</strong>nbeginrepeatprint(si.Name);until FindNext(si) 0FindClose(si);end;si.Free;print('ok');end.4.3.2 Common functionsPrint (string) – printing a string on a command lineExampleprint('mama');Clear – clears consoleExampleclear;Assignfile(f: text, filename: string) ‐ opens a file with a given filenameExampleassignfile(f, 'Data\Text\Text1.txt');Reset(f: text) ‐ file opens for readingExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php69 <strong>of</strong> 144 26.05.2011 19:56Reset(f);Rewrite(f: text) ‐ file opens for writingExampleRewrite(f);ExePath: string – getting a path <strong>from</strong> where Aq<strong>Scripter</strong> is executedExamplename := ExePath + 'data\ABases\comment.cdp';InputQuery(StartPath: string): string – path dialogExampleInputQuery('Enter floating-point number', 'Number (e.g. 3,5 or 5.66)', s);FindFirst (Path: string; Attr: integer; Info: SearchInfo): integer – searching for <strong>the</strong> first instance <strong>of</strong> a file name with a given set <strong>of</strong> attributes incode.Exampleif FindFirst('*.cdp', faAnyFile, si) = 0 <strong>the</strong>n//si is TSSearchInfoFindNext(Info: TSSearchInfo): integer ‐ getting <strong>the</strong> next entry matching <strong>the</strong> name and attributes specified in a previous call to FindFirst. ReturExampleFindNext(si) 0FindClose(Info: TSSearchInfo) ‐ terminating a FindFirst/FindNext sequenceExampleFindClose(si);FindFirstInDbNotInTree(Game: TSDataBaseGame, Tree: TSTreeScanner):String Finds first node that exists only in <strong>the</strong> databaseExampleprint(FindFirstInDBNotInTree(dbg, tree));ToFullEPD(EPD: String):String converts EPD to FullEPD
http://chessok.com/aqtiki/tiki-print_multi_pages.php70 <strong>of</strong> 144 26.05.2011 19:56Exampleprint(ToFullEPD(EPD));IsIsolated(EPD: String, Square: String):boolean check if a figure is isolatedExampleif IsIsolated(epd, p) <strong>the</strong>nIsCentralBlocked(EPD: String):boolean check if a figure is blockedExampleif IsCentralBlocked(epd) <strong>the</strong>nMaterialDiff(EPD: String, DiffOptions: boolean):String returns difference between white and black. When DiffOptions is true, returns onlyExampleprint(MateriaDiff(EPD, true));RenameFile(OldFile, NewFile: String):renames <strong>the</strong> file.ExampleRenameFile('myoldfile.txt', 'mynewfile.txt');DeleteFile(Filename: String): deletes given fileExampleDeleteFile('myfile.txt');ForceDirectories(Path: String):boolean creates a new directory as specified in Path, which must be a fully‐qualified path name. If <strong>the</strong> directoriereturns True if it successfully creates all necessary directories, False if it could not create a needed directory.ExampleForceDirectories('c:/scripter/path');ParseEPD(EPD: String):TXMLTag returns an XMLTag, where 'FEN' value contains FEN, 'bm' ‐ bestmove, c0‐ evaluation and so on.Example
http://chessok.com/aqtiki/tiki-print_multi_pages.php71 <strong>of</strong> 144 26.05.2011 19:56epd := 'r2rqbk1/p1n3p1/1p1pPpPp/P1p2P2/6Q1/2N1B1P1/1P4K1/R6R w - - 0 1 bm Be3h6; c0 97;';TTAg := PArseEPD(epd);print(TTAg.Values['FEN']);print(TTag.Values['bm']);print(TTag.VAlues['c0']);TTag.Free;4.3.3 Classes for processing <strong>Aquarium</strong> data objects
http://chessok.com/aqtiki/tiki-print_multi_pages.php72 <strong>of</strong> 144 26.05.2011 19:56This is classes Aq<strong>Scripter</strong> was designed for ‐ <strong>Aquarium</strong> data classes. They have complicated hierarchy, described here:The links don't mean parent‐child relationship, but availabilityMutual availability exists between:TSDataBase(one instance) and TSDataBaseGame?(many instances)TSNodeInfo(one instance) and TSMoveInfo(many instances)TSMoveInfo(one instance) and TSAnnotation(one instance)One‐direction availability exist betweenTSDataBaseGame?(one instance) and TSHeader(one instance)TSDataBaseGame?(one instance) and TSNodeInfo(many instances)TSTreeScanner(one instance) and TSNodeInfo(many instances)Classes TSEngine, TSTreeJoiner and TSTreeConfiguration are unavailable <strong>from</strong> any o<strong>the</strong>r classes.
http://chessok.com/aqtiki/tiki-print_multi_pages.php73 <strong>of</strong> 144 26.05.2011 19:56Table <strong>of</strong> contents:Tree classesClass TSTreeScannerClass TSTreeJoinerClass TSTreeConfigurationDatabase classesClass TSDatabaseClass TSGameClass TSGameHeader4.3.3.1 Tree classesTrees is <strong>the</strong> most popular way for storing chess data. Aq<strong>Scripter</strong> has three classes working with trees.Table <strong>of</strong> contents:Class TSTreeScannerClass TSTreeJoinerClass TSTreeConfiguration4.3.3.1.1 Class TSTreeScanner↑ Is used in: Nothing↓ Uses: TSNodeInfoDeclaration:vart: TSTreeScanner;The most common class, that work provides most <strong>of</strong> <strong>the</strong> <strong>Aquarium</strong> tree functionality. The instances <strong>of</strong> this class can scan <strong>the</strong> tree consecutive or recursor whatever he or she wants. It also has a number <strong>of</strong> implemented methods and properties. Scanning is done on a event‐driven system.You can find here how tp work with currently opened treesPropertiesOpened: boolean – checking if <strong>the</strong> tree is opened.Exampleif t.Opened <strong>the</strong>nCurrentNode: TSNodeInfo – current node <strong>the</strong> scanner is positioned onExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php74 <strong>of</strong> 144 26.05.2011 19:56n := AScanner.CurrentNode;//n is TSNodeInfoName: string ‐ storing a path to a tree.Examples := t.Name; //s is stringScanOpt: integer – gets and sets Scan Options, that are tssMoves, tssStat, tssColor or its combination (that means which <strong>of</strong> <strong>the</strong>m wiExamplet.ScanOpt := tssMoves;MinValue: integer – minimal value (in percents) for move selection in scanning, 0 by default.Examplet.MinValue := 45;PosLoc: position selection for precessing (only internal nodes, leaves, all). Correspondent values are: plInternal, plConcluding, plInterExamplet.PosLoc := plInternal;MaxValue: integer – maximal value (in percents) for move selection in scanning, 100 by default. (MinValue:= 0; MaxValue:=100 meansExamplet.MaxValue := 55;GameExists: boolean – returns true if <strong>the</strong>re's a game attached to <strong>the</strong> Current positionExampleif t.GameExists <strong>the</strong>nMethodsCreate(Path: string; ReadOnly:boolean = true; CanCreate:boolean = false; AMemory:integer=64) – create <strong>the</strong> object (PathExample// Opening tree to create:t := TSTreeScanner.Create('cap.hsh', false, true);// Opening tree as read-onlyt := TSTreeScanner.Create('cap.hsh');
http://chessok.com/aqtiki/tiki-print_multi_pages.php75 <strong>of</strong> 144 26.05.2011 19:56Free() ‐ releasing an objectExamplet.Free;Reset() – resetting a tree.Examplet.Reset;StartRecursive (StartPos: string = '') – making a recursive scan <strong>from</strong> a given position (start position by default)Examplet.ScanRecursive('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -');StartConsecutive() – making successive scan (faster than recursive)Examplet.ScanConsecutive;StopScan() ‐ stopping scan.Examplet.StopScan;AbortNode() ‐ stops scanning <strong>the</strong> current node and goes to <strong>the</strong> next one.Examplet.AbortNode;Search(TSNodeInfo): TSNodeInfo ‐ searching for a node (returns TSNodeInfo)Exampleni1 := t.Search(ni2)// ni1, ni2 is TSNodeInfoSearchFEN(string): TSNodeInfo – searching for a node by EPD string (returns TSNodeInfo)Exampleni := t.SearchFEN('rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -');// ni is TSNodeInfo
http://chessok.com/aqtiki/tiki-print_multi_pages.php76 <strong>of</strong> 144 26.05.2011 19:56Locate(TSNodeInfo) boolean – Locating a node (returns boolean, true found)Exampleif t.Locate(ni) <strong>the</strong>n// ni is TSNodeInfoLocateFEN(string):boolean – Locating a node by EPD (returns Boolean, true if found)Exampleif t.LocateFEN('rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -') <strong>the</strong>n// ni is TSNodeInfoDoMove(string):boolean – makes a move <strong>from</strong> <strong>the</strong> current position. Works like NewPosition, but for a tree.Exampleif t.DoMove(mi) <strong>the</strong>n//mi is TSMoveInfoAdd(TSNodeInfo):boolean ‐ adds a position into <strong>the</strong> tree.Exampleb := t.Add(ni);//b is boolean, ni is TSNodeInfoAddFen(string): boolean – adding a node by EPD (returns TSNodeInfo)Exampleb := t.AddFen('rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -');//b is boolean, ni is TSNodeInfoAddMove(string): boolean – adding a move (returns a true if added)Exampleif t.AddMove(mi) <strong>the</strong>n//mi is TSMoveInfoDeleteMove (string): Boolean – deleting a move (return true if deleted)Exampleif t.DeleteMove(mi) <strong>the</strong>n//mi is MoveInfoUpdateMove(TSMoveInfo): Boolean ‐ updating move, need to be called if a move was edited (e.g. its Score)Examplet.UpdateMove(mi);//mi is TSMoveInfo
http://chessok.com/aqtiki/tiki-print_multi_pages.php77 <strong>of</strong> 144 26.05.2011 19:56GenerateMoves(TSNodeInfo): boolean ‐ generating all possible moves <strong>from</strong> a given position. Node: adds all possible moves that are nExamplet.GenerateMoves(ni);//ni is TSNodeInfoGenerateBackMoves(TSNodeInfo): boolean – generating all backward moves <strong>from</strong> current position.Examplet.GenerateBackMoves(ni);// ni is TSNodeInfoGetRootNodes: TStringList – finding root nodes.Examplesl := t.GetRootNodes;//sl is StringListIsEndNode(TSNodeInfo): boolean – checking if a given node is an endnodeExampleif t.IsEndNode(ni) <strong>the</strong>n//ni is TSNodeInfoMarkNode(TSNodeInfo): boolean – marking a given moveExamplet.MarkNode(ni);//ni is TSNodeInfoIsMarked(TSNodeInfo): boolean – checking if a move is markedExampleif t.IsMarked(ni) <strong>the</strong>n//ni is TSNodeInfoSetNodeScore(integer) ‐ setting a score <strong>of</strong> a node (<strong>of</strong> a node that is located)Examplet.SetNodeScore(25);//ni is TSNodeInfoGetGame:TSGame ‐ returns <strong>the</strong> game attached to <strong>the</strong> Current position and nil o<strong>the</strong>rwiseExamplegam := t.GetGame;
http://chessok.com/aqtiki/tiki-print_multi_pages.php78 <strong>of</strong> 144 26.05.2011 19:56Check checks if <strong>the</strong> tree is not corruptedExampleif t.Check <strong>the</strong>n<strong>Aquarium</strong> Tree Utils functionalityExportEPD(AEPD: string)integer ‐ Exporting tree into a epd file (only posotions)Exampleepd := 'Data\epd\export.epd';//filei := t.ExportEPD(epd);print(i);//number <strong>of</strong> positions//t is any tree you likeImportEPD(AEPD: string)integer ‐ Importing tree <strong>from</strong> a epd file (positions, moves and evaluations)Exampleepd := 'Data\epd\exported2.epd'//epd filei := t.ImportEPD(epd);print(i);//number <strong>of</strong> positions//t is any tree you likeFilterEPD(ASourceEPD, ADestinationEPD, AposControl: string): integer‐ Filtering a epd file. Compares a epd file and a tree and writnot in treeExamples := 'data\Atrees\d2m.hsh';\\tree to compareepd := 'Data\epd\exported2.epd';\\source filefiltered := 'Data\epd\filtered2.epd';\\output file\\APosControl are 'pExclude' or 'pPreserve't := TSTreeScanner.Create(s);t.FilterEPD(epd, filtered, 'pExclude');ShowMessage(Format('Filter done see %s', [filtered]))DedupeEPD(inputfile, outputfile: string) ‐ eliminating duplicate nodes. Output parameter can be omitted, so it will be generExamplet.DedupeEpd(inputepd, outputepd);//inputepd, outputepd – path to files// ort.DedupeEpd(inputepd);ImportTreeDifference(InputTree, SubtractedTree: string)boolean ‐ subtracting trees, returns a tree that has nodes <strong>from</strong> Input tree anExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php79 <strong>of</strong> 144 26.05.2011 19:56t := TSTreeScanner.Create('Data\Atrees\out4.hsh', false, true);if t.Opened <strong>the</strong>nbeginif t.ImportTreeDifference('DATA\ATrees\cap.hsh', 'Data\Atrees\idea.hsh') <strong>the</strong>nprint('Subtract Done')elseprint('Subtract not done');end;ImportTreeComparison(InputTree, ComparedTree: string)boolean ‐ subtracting trees, returns a tree that has nodes <strong>from</strong> Input tree aExamplet := TSTreeScanner.Create('Data\Atrees\out1.hsh', false, true);if t.Opened <strong>the</strong>nbeginif t.ImportTreeComparison('Data\Atrees\nnt.hsh', 'Data\Atrees\idea.hsh') <strong>the</strong>nprint ('Compare done')elseprint ('Compare not done');end;CompressTrees(InputTree:string)integer ‐ rebuilds tree if its neededExamplet := TSTreeScanner.Create('Data\Atrees\cap_compressed2.hsh', false, true);if t.Opened <strong>the</strong>nbeginif t.CompressTree('Data\Atrees\cap.hsh') = 0 <strong>the</strong>nprint ('Compress done')elseprint ('Compress not done');end;ExportSubtree(AInputTree, AFEN:string)integer ‐ Saves a subtree <strong>from</strong> a given position into ano<strong>the</strong>r tree, returns number <strong>of</strong> positiExamplet := TSTreeScanner.Create('Data\Atrees\out2.hsh', false, true);if t.Opened <strong>the</strong>nprint(t.ExportSubtree('Data\Atrees\cap.hsh', 'r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -' ));ExportSubTreeToEPD(AFEN, AEPD:string; AAllLines:boolean; ExpSet:string; MinValue, MaxValue:integer)boolean ‐ Exports a submainline, ExpSet sets whe<strong>the</strong>r all leaves ('EsAll'), internal ('exInternal') or endnodes (exConcluding) are processed and MinValue and MExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php80 <strong>of</strong> 144 26.05.2011 19:56t := TSTreeScanner.Create('Data\Atrees\out1.hsh', false, true);if t.Opened <strong>the</strong>nbegins := 'data\Atrees\cap.hsh';Afen := 'rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -';epd := 'Data\epd\subepd2.epd'i := t.ExportSubtreeTOEPD(AFEn, epd, true, 'exAll', -30000, 30000);if i <strong>the</strong>nShowMessage(Format('Export done, see %s', [epd]))elseShowMessage('Export not done');end;JoinTrees(AJoinTreePath: string; AOutputTreePath: string; Stat, Eval, Move, Ant, Avar:TJoinType; Pos: TAddPositionsModeto take this info. Constants are: jrNo (<strong>from</strong> nowhere), jrJoin(Join), jrSrc(source tree), jrAtt(Attached tree), jrSrcPrior(priority to source),apInter(Intersection). You cannot join Moves and Stat with jrSrcPrior and jrAttPrior.Examplesrc.JoinTrees(att, dst, jrJoin, jrJoin, jrJoin, jrJoin, jrJoin, apInter);Minimax(AFen: string) ‐ minimaxing a tree.Examplet.Minimax(''); // minimaxes all <strong>the</strong> treet.Minimax('8/8/8/8/5K2/8/2k5'); // minimaxes <strong>from</strong> FENMultipleMinimax(sl:TStringList) ‐ minimaxing a tree <strong>from</strong> all positions in StringList.Examplet := TSTreeScanner.Create('Data\Atrees\cap.hsh', false);if t.Opened <strong>the</strong>nbeginsl := TStringList.Create;sl.LoadFromFile('Data\EPD\minimax.epd');t.MultipleMinimax(sl);sl.Free;ShowMessage('Minimaxed');end;ImportSubtree(outputtree, FEN: string):integer ‐ generating Subtree <strong>from</strong> a given node (as a EPD line) and writes it to a .hsh‐fileExampleprint(t.ImportSubtree('out.hsh', 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -'));EventsOnInit – The procedure that should be called before scanning start. Pr<strong>of</strong>ile: function(): boolean; if result is False – scanning will not be
http://chessok.com/aqtiki/tiki-print_multi_pages.php81 <strong>of</strong> 144 26.05.2011 19:56Examplet.OnInit := 'DoBeforeScanning';OnTerminate – The procedure that should be called after scanning finish. Pr<strong>of</strong>ile: procedure().Examplet.OnTerminate := 'DoAfterScanning';OnProcessNode – The procedure that should be called for every scanning position. Pr<strong>of</strong>ile: procedure(Info: TSTreeScanner). Fills <strong>the</strong> fall moves <strong>from</strong> <strong>the</strong> current position, presented in <strong>the</strong> tree. Fields Move, Score, RelScore, Color are automatically filled with proper infoExamplet.OnProcessNode := 'OnScan';OnProcessTransposition – <strong>the</strong> procedure is called in case <strong>of</strong> reentering to a position, i.e. in case <strong>of</strong> reaching position by ano<strong>the</strong>r path.Examplet.OnProcessTransportation := 'DoIfReenter';OnProcessStartBranch ‐ The procedure is called at <strong>the</strong> start <strong>of</strong> processing some move and line after it. Pr<strong>of</strong>ile: procedure(Move:Examplet.OnProcessStartBranch := 'DoWhenBranchStart';OnProcessEndBranch ‐ The procedure is called at <strong>the</strong> end <strong>of</strong> line scanning starting with some move. Pr<strong>of</strong>ile: procedure(Move:Examplet.OnProcessEndBranch := 'DoWhenBranchEnd';OnProcessBacksolve ‐ The procedure is called in case <strong>of</strong> processing all lines for <strong>the</strong> position. Pr<strong>of</strong>ile: procedure().Examplet.ProcessBacksolve := 'DoWhenAllLines';OnProcessEndLine ‐ The procedure is called in case if <strong>the</strong> current position is not found. Pr<strong>of</strong>ile: procedure().Examplet.OnProcessEndLine := 'DoWhenNotFound';Usage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php82 <strong>of</strong> 144 26.05.2011 19:56vart: TSTreeScanner;AFen: String;i: integer;procedure OnScan(Ascanner: TStreeScanner)varnn: TSNodeInfo;beginnn := Ascanner.CurrentNode;inc(i);end;begint:=TSTreeScanner.Create('Data/Atrees/cap.hsh')if t.Opened <strong>the</strong>nbegini := 0;t.OnProcessNode := 'OnScan';Afen := 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -';t.StartRecursive;print (inttostr(i) + ' positions')//Nodes in <strong>the</strong> whole treet.Free;end.4.3.3.1.2 Class TSTreeJoiner↑ Is used in: Nothing↓ Uses: NothingDeclaration:varTJoiner: TSTreeJoinerA very special class, that does only one, but important procedure – it joins and minimaxes a very big and a very small tree, and does it much faster thanMethodsSmartJoin(bigtree, smalltree: string) ‐ smart join.ExamplevarTJoiner: TSTreeJoiner;beginTJoiner := TStreeJoiner.Create('Data\Atrees\output.hsh');//Creating an objectTJoiner.SmartJoin('Data\Atrees\Cap.hsh', 'Data\ATrees\Idea.hsh');//bigtree, smalltreeShowMessage('ok');end.4.3.3.1.3 Class TSTreeConfiguration
http://chessok.com/aqtiki/tiki-print_multi_pages.php83 <strong>of</strong> 144 26.05.2011 19:56↑ Is used in: Nothing↓ Uses: NothingDeclaration:varConfig: TSTreeConfigurationA special class used to work with tree configurations <strong>of</strong> <strong>Aquarium</strong>. By now only several functions are available, <strong>the</strong>y are getting and setting play probabTo get it work, copy files tree_configurations.xml and RBaseTrees.xml <strong>from</strong> Config folder <strong>of</strong> <strong>Aquarium</strong> to <strong>the</strong> Config folder <strong>of</strong> Aq<strong>Scripter</strong>, andMethodsCreate(string): TSTreeConfiguration ‐ creating a configuration: takes <strong>the</strong> <strong>Aquarium</strong> name <strong>of</strong> a configuration (here 'NarrowBook')ExampleTSConfig := TSTreeConfiguration.Create('NarrowBook');//OpenConfigGetPlayProbabilityPercents(TSNodeInfo, MoveNumber: integer): integer ‐ getting play probability (in percents). Gets TSNodeInfo, fExampleTSConfig.GetPlayProbabilityPercents(ni, 1);//ni is ModeInfo, 1 is numberSetManualPercent(Percents: Integer, TSNodeInfo, MoveNumber: integer): boolean ‐ setting play probability (in percents). Gets PeExampleTSConfig.SetManualPercent(12, ni, 1);//12 is percents, ni is NodeInfo, 1 is Move numberGetMoveColor(TSNodeInfo, TSMoveInfo): string ‐ getting colors <strong>of</strong> <strong>the</strong> move (as strings). Gets TSNodeInfo, <strong>from</strong> where to take a moExampleTSConfig.GetMoveColor(ni, mi);//ni is NodeInfo, mi is MoveInfoSetMoveColor(TSNodeInfo, TSMoveInfo, movecolor: TSMoveColor): boolean ‐ setting colors <strong>of</strong> <strong>the</strong> move (also as strings. Constantsmove number and color constant.ExampleTSConfig.SetMoveColor(ni, mi, tmcRed);//ni is NodeInfo, mi is MoveInfo, tmcRed is constantSearchFEN(string): TSNodeInfo ‐ returns <strong>the</strong> node with all moves for <strong>the</strong> given string and nil if it doesn't exist. Should be freed after u
http://chessok.com/aqtiki/tiki-print_multi_pages.php84 <strong>of</strong> 144 26.05.2011 19:56Exampleni := TSConfig.SearchFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -');Usage example//For Aq<strong>Scripter</strong> version beta 4.0.2//Works with TreeConfigurations <strong>of</strong> <strong>Aquarium</strong>//To get it work, copy config and atrees folders <strong>of</strong> <strong>Aquarium</strong> into <strong>the</strong> directory <strong>of</strong> Aq<strong>Scripter</strong>.exevarTSConfig: TSTreeConfiguration;t: TStreeScanner;ni: TSNodeInfo;beginTSConfig := TSTreeConfiguration.Create('NarrowBook');//OpenConfigni := TSConfig.SearchFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -');if ninil <strong>the</strong>nbeginTSConfig.SetManualPercent(12, ni, 1);//Set Play Propability percents: percents, nodeinfo, number <strong>of</strong> moveTSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[0]], tmcRed); //Set ColorsTSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[1]], tmcBlue);//nodeinfo, moveinfo, colorTSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[2]], tmcOrange);TSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[3]], tmcGreen);TSConfig.SetMoveColor(ni, ni.Moves[ni.Sorted[4]], tmcPurple);ni := TSConfig.SearchFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -');if ni nil <strong>the</strong>nbeginprint(inttostr(TSConfig.GetPlayProbabilityPercents(ni, 1)));// get play probability percentprint(inttostr(TSConfig.GetPlayProbabilityPercents(ni, ni.Sorted[0]))); //nodeinfo, move numbverprint(ni.Moves[ni.Sorted[0]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[0]]));//get colorprint(ni.Moves[ni.Sorted[1]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[1]]));//nodeinfo, moveinfoprint(ni.Moves[ni.Sorted[2]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[2]]));print(ni.Moves[ni.Sorted[3]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[3]]));print(ni.Moves[ni.Sorted[4]].Move +': ' +TSConfig.GetMoveColor(ni, ni.Moves[ni.Sorted[4]]));end;ni.Free;endelseShowMessage('No position!');TSConfig.Free;end;4.3.3.2 Database classes<strong>Aquarium</strong> provides many instruments to work with chess databases, <strong>the</strong> most important and useful <strong>of</strong> <strong>the</strong>m are also available <strong>from</strong> Aq<strong>Scripter</strong>.Table <strong>of</strong> contents:Class TSDatabaseClass TSGameClass TSGameHeader
http://chessok.com/aqtiki/tiki-print_multi_pages.php85 <strong>of</strong> 144 26.05.2011 19:564.3.3.2.1 Class TSDatabase↑ Is used in: Nothing↓ Uses: TSGameDeclaration:vardb: TSDataBase;This class operated with <strong>the</strong> database itself. The main functionality is to read and write or re‐write games.Also, look here for how to work with currently opened base in <strong>Aquarium</strong>.MethodsCreate(Path: string): TSDatabase – creating a database object <strong>from</strong> a given path (and creates an empty database if it doesn't exist)Exampledb := TSDataBase.Create('Data/ABases/comment.cdp');ReadGame(Index: integer, AWithFlags: boolean): TSGame – reading a game with a given number, returns a TSGame objectTSGame works.Examplegam := db.ReadGame(2, true);//Reading a game Number 2 with flags, gam is TSGameNewGame: TSGame – creating a new game that will be <strong>the</strong> last in <strong>the</strong> list <strong>of</strong> <strong>the</strong> games, returns a TSGame objectExamplegam := db.NewGame;//Creating a new gamedbg.AddMove('e2e4'); //adding a new moveWriteGame(Game: TSGame):boolean – writing a gameExampledb.WriteGame(gam);Free() – release database object. Note, that since <strong>the</strong>re's no garbage collector in <strong>Scripter</strong>, <strong>the</strong> object must always be released to free thExampledb.Free;
http://chessok.com/aqtiki/tiki-print_multi_pages.php86 <strong>of</strong> 144 26.05.2011 19:56CommentGame(Game: TSGame): – Adds to a game a comment "Novelty" sicut Hugebase and inserts a game(s) with a move(s) that wExampledb.CommentGame(gam);PropertiesCount: integer ‐ number <strong>of</strong> games in <strong>the</strong> database.Exampledb.Count;Opened: boolean ‐ <strong>the</strong> database was opened.Exampleif db.Opened <strong>the</strong>nUsage example #1vardb: TSDatabase; // Declare database objectbegin// Create database object// ExePath contains <strong>the</strong> <strong>Scripter</strong> folder pathpath := ExePath + 'data\ABases\comment.cdp';db := TSDatabase.Create(path);// if database existsif db.Opened <strong>the</strong>nbegin// Print text message in <strong>Scripter</strong> consoleprint('opened');// Show message box with number <strong>of</strong> games in <strong>the</strong> databaseShowMessage(format('%d',[db.Count])+' games');// Free memory for database objectdb.Free;end;end.4.3.3.2.2 Class TSGameIs used in: TSDataBaseUses: TSGameHeader, TSNodeInfo, TSAnnotationDeclarationvargam: TSGame;
http://chessok.com/aqtiki/tiki-print_multi_pages.php87 <strong>of</strong> 144 26.05.2011 19:56This is <strong>the</strong> main class working with a database game. The games in <strong>the</strong> database can be scanned forward and backward, same as tree, with opportunievaluation and text comment – to a chosen move. The game header is also stored in this class. The game has no Create method, it is read by ReadGamLook here to find how to work with currently opened game in <strong>Aquarium</strong>PropertiesCurrentNode: TSNodeInfo – current node <strong>the</strong> game is positioned onExampleni := gam.CurrentNode;Header: TSGameHeader – contains header <strong>of</strong> <strong>the</strong> game in TSGameHeader object.Exampleprint(gam.Header.Result);Annot: TSAnnotation – provides access to <strong>the</strong> annotation. Works with current move.Exampleprint(gam.Annot.GetAllComments);Flags: integer – provides access to <strong>the</strong> flags.Exampleprint(gam.Flags);TotalCount: integer – number <strong>of</strong> moves in <strong>the</strong> whole gameExamplefor i:=0 to gam.TotalCount-1 doLineCount: integer ‐ getting <strong>the</strong> number <strong>of</strong> moves in <strong>the</strong> current lineExamplei := gam.LineCount;TotalCount: integer ‐ getting <strong>the</strong> number <strong>of</strong> moves in <strong>the</strong> whole gameExamplei := dbg.TotalCount;
http://chessok.com/aqtiki/tiki-print_multi_pages.php88 <strong>of</strong> 144 26.05.2011 19:56VariationsCount: integer ‐ getting <strong>the</strong> number <strong>of</strong> variations <strong>from</strong> current moveExamplei := dbg.VariaitonsCount;IsInVariant:Boolean ‐ checking whe<strong>the</strong>r current line is a variationExampleif dbg.IsInVariant <strong>the</strong>nIsAfterMove:Boolean ‐ returns true, when we stay after <strong>the</strong> current move, and false o<strong>the</strong>rwiseExampleif dbg.IsAfterMove <strong>the</strong>nTotalIndex:integer ‐ returns <strong>the</strong> number <strong>of</strong> <strong>the</strong> current move.Examplek := gam.TotalIndex;MethodsCreate:TSNodeInfo– Creates a new empty game.Examplegam := TSGame.Create;LoadFromPGN(PGN: String):– creates a game <strong>of</strong> a pgn‐string, e.g. copied <strong>from</strong> <strong>Aquarium</strong> using right‐clicl on Notation>Copy>Copy gaExamplegam.LoadFromPGN(PasteFromClipboard)SetStartPos(AFEN:String)– Sets a given position as a start position <strong>of</strong> a game.Examplegam.SetStartPos('r2rqbk1/p1n3p1/1p1pPpPp/P1p2P2/6Q1/2N1B1P1/1P4K1/R6R w - -');LoadUCIString(UCIString:String)– loads into a game a string in uci‐format, like this'position startpos moves e2e4 e7e5'or this
http://chessok.com/aqtiki/tiki-print_multi_pages.php89 <strong>of</strong> 144 26.05.2011 19:56'position fen r2rqbk1/p1n3p1/1p1pPpPp/P1p2P2/6Q1/2N1B1P1/1P4K1/R6R w ‐ ‐ moves d5d6'Examplegam.LoadUCIString('position startpos moves e2e4 e7e5');ScanGameForward(AMainOnly: boolean = True) – scan game starting <strong>from</strong> <strong>the</strong> first move. If AMainOnly is not specified or is set toevent on every position.Exampledbg.ScanGameForward(False);ScanGameBackward() – scan game in backward direction starting <strong>from</strong> <strong>the</strong> end (scans only main variation). Invokes OnScanExampledbg.ScanGameBackward;StopScan() – stop <strong>the</strong> ongoing scan <strong>of</strong> <strong>the</strong> game.Exampledbg.StopScan;It's a number <strong>of</strong> GoTo procedures. Note, that moves are now always counted <strong>from</strong> 1!!So, if you type LnGoTo(2, true) you'll get FEN after <strong>the</strong> second move and player will be white. if you type LnGoTo(2, false), you'll get FEN after <strong>the</strong> firstsecond move (including it).LnGoTo(Index: integer, AAfter: boolean): TSNodeInfo – going to a move number Index within current line. When AAfter is false, we sExampleni := gam.LnGoTo(1, true);//after move number 1, moves are counted <strong>from</strong> 1ni := gam.LnGoTo(1, false);//to start positionTotalGoTo(Index: integer, AAfter: boolean): TSNodeInfo – going to a move number Index in <strong>the</strong> whole game. When AAfter is false, wExampleni := gam.TotalGoTo(1, true);//after move number 1, moves are counted <strong>from</strong> 1ni := gam.TotalGoTo(1, false);//to start positionLnGoToFEN(AFEN: String): TSNodeInfo ‐ going to a certain FEN position within current line.Exampleni := gam.LnGoToFEN(12);//ni is TSnodeInfo
http://chessok.com/aqtiki/tiki-print_multi_pages.php90 <strong>of</strong> 144 26.05.2011 19:56MainLineGoTo(AMoveNumer: integer, AAfter: boolean): TSNodeInfo ‐ going to a move number Index within <strong>the</strong> mainline. When AAExampleni := gam.MainLineGoTo(12, false);// ni is TSNodeInfo;MainLineGoToFEN(AFEN: String): TSNodeInfo ‐ going to a certain FEN position within mainline.Exampleni := dbg.MainLineGoToFEN(' rnbqkbnr/p1pppppp/8/1p6/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -', false);//ni is TSNodeInfo;NewLine(AMoves: String): integer ‐ adding a new variation to a current move. Adding moves is compulsory! If <strong>the</strong>re's more than oneExamplei := gam.NewLine('b7b5 h2h4');AddMove(AMove: String) ‐ adding move to a current line.Examplegam.AddMove('a7a5');AddMoves(Amoves: String; AMoveTypes: TSMoveType) ‐ adding number <strong>of</strong> move to a current line. It might be <strong>of</strong> three MoveTypes:tsNumbers means, that <strong>the</strong>re're numbers <strong>of</strong> moves.Examplegam.AddMoves('1.h6h5 2.g2g4', tsNumbers);DeleteMoves ‐ deletes current move and all that's after it.Examplegam.DeleteMove;ReturnToUpperLine: TSNodeInfo ‐ going back <strong>from</strong> variation to upper level, where a variation startsExampleni:=gam.returnToUpperLine;//ni is TSNodeInfoReturnToMainLine: TSNodeInfo ‐ going back to mainline, where <strong>the</strong> current variation or its parent(s) startExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php91 <strong>of</strong> 144 26.05.2011 19:56ni := gam.ReturnToMainLine;//ni is TSNodeInfoGoToStartPos: TSNodeInfo ‐ going to start position. Same as dbg.MainLineGoToMove(0);Exampleni := gam.GoToStartPos;//ni is NodeInfo;SelectLine(AlineNumber: integer):TSNodeInfo ‐ selecting a variation. To do it, you should be positioned on a move <strong>from</strong> which vaExampleni := gam.SelectLine(0);PushLocation ‐ "remembers" current locationExamplegam.PushLocationPopLocation ‐ positions on <strong>the</strong> location, remembered in PushLocation.Examplegam.PopLocationInvertPlayer: TSNodeInfo ‐ inverts <strong>the</strong> position upside down, so that black pieces become white and vice versa. The whole line, includExampleni := gam.InvertPlayer;Free() – Release <strong>the</strong> created game object.Exampledbg.Free;EventsOnScan procedure(Info: TSNodeInfo) – Procedure that is done while scanning. Pr<strong>of</strong>ile: procedure (AInfo: TSnodeInfo). The following fiLevel, VarLevel, IsWhite. Currently Moves contains only one move, and only Move field is filled with <strong>the</strong> value.OnScan event is invoked <strong>from</strong> ScanGameForward / ScanGameBackward and should be reloaded with a custom procedure to process <strong>the</strong> node:Reloading OnScan
http://chessok.com/aqtiki/tiki-print_multi_pages.php92 <strong>of</strong> 144 26.05.2011 19:56procedure OnScan1(node: TSNodeInfo);beginPrint( Node.Move);// ... do something with nodeend;// ...gam.OnScan := 'OnScan1';gam.ScanGameForward(true);// ...Scanning <strong>the</strong> game is also possible with step‐by‐step GoTo procedure:Alternative scanningfor i := 0 to dbg.LineCount - 1 dobeginnode := dbg.GoTo(i, true);print(node.Move);// ... do something else with nodeend;An example <strong>of</strong> a scriptUsage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php93 <strong>of</strong> 144 26.05.2011 19:56vardb: TSDatabase; // Database objectgam: TSGame; // Game objectf: text; // Text file objects: TStringList;h: TSGameHeader;// Printing information about a move// This procedure is assigned for processing moves in ScanGameForward procedureprocedure OnScan1(si: TSNodeInfo);begin// si.Level - ply number// si.VarLevel - 0 - main line; 1 - variant for main line; ...// si.Move - notation <strong>of</strong> <strong>the</strong> moveWriteLn(f, Format('fwd: %.3d [%d]: %s (%s)', [si.Level, si.VarLevel, si.Pos, si.Move]));end;// Printing information about a move// This procedure is assigned for processing moves in ScanGameBackward procedureprocedure OnScan2(si: TSNodeInfo);beginWriteLn(f, Format('bwd: %.3d [%d]: %s (%s)', [si.Level, si.VarLevel, si.Pos, si.Move]));end;begin// Create database object and open databasepath := ExePath + 'data\ABases\comment.cdp';if FileExists(path) <strong>the</strong>nprint ('Database found')elseprint ('Database not found');db := TSDatabase.Create(path);// If database is foundif db.Opened <strong>the</strong>nbegin// Create db_script.log fileAssignFile(f, 'db_script.log'); Rewrite(f);s := TStringList.Create;// Inform about number <strong>of</strong> games in <strong>the</strong> databaseShowMessage(format('%d',[db.Count])+' games');// Read game #19gam:= db.ReadGame(19, true);if gam.Opened <strong>the</strong>nbeginh:= gam.Header;print (h.Result);// Scan forwardgam.OnScan := 'OnScan1';gam.ScanGameForward(False);// Scan backwardsgam.OnScan := 'OnScan2';gam.ScanGameBackward;gam.Free;gam:= db.ReadGame(20, true);
http://chessok.com/aqtiki/tiki-print_multi_pages.php94 <strong>of</strong> 144 26.05.2011 19:564.3.3.2.3 Class TSGameHeaderIs used in: TSGameDeclarationvarh:TSGameHeader;This is a small class that contains a header <strong>of</strong> a game – such as who played black and white, where and when did this game take place, and its result.All properties are writable.PropertiesEvent: String ‐ A tournament/match where <strong>the</strong> game was playedExamplegam.Header.Event := 'Memorial Rosenwald';Site: String ‐ place where a game took placeExamplegam.Header.Site := 'New York (USA)';Date: String ‐ Date <strong>of</strong> <strong>the</strong> gameExamplegam.Header.Date := '1956.03.25';Black: String ‐ Who played blackExamplegam.Header.Black := 'Fischer Robert J (USA)';White: String ‐ Who played whiteExamplegam.Header.White := 'Bisguier Arthur B (USA)';Result: String ‐ The result <strong>of</strong> <strong>the</strong> gameExamplegam.Header.Result := '1-0';
http://chessok.com/aqtiki/tiki-print_multi_pages.php95 <strong>of</strong> 144 26.05.2011 19:56GameNo: integer ‐ <strong>the</strong> number <strong>of</strong> a gameExamplegam.Header.GameNo := 19;Round: String ‐ <strong>the</strong> round in a tournamentExamplegam.Header.Round := '?';WhiteELO: integer ‐ ELO rating <strong>of</strong> white playerExamplegam.Header.WhiteELO := 2256;BlackELO: integer ‐ ELO rating <strong>of</strong> black playerExamplegam.Header.BlackELO := 2780;** ECO: string ‐ returns ECO <strong>of</strong> a game.Examplegam.Header.ECO := 'E78';Some codeUsage exampleif gam nil <strong>the</strong>nbeginh:= gam.Header;print (h.White);end;4.3.4 Classes for working with <strong>the</strong> enginesTable <strong>of</strong> contents:Class TSEngine4.3.4.1 Class TSEngineIs used in: NothingUses: Nothing
http://chessok.com/aqtiki/tiki-print_multi_pages.php96 <strong>of</strong> 144 26.05.2011 19:56Declarationvar:e: TSengine;This is <strong>the</strong> class that works with engines. The analysis can be started by uci command and stopped ei<strong>the</strong>r directly (used when you want every line to becan set an analysis position and process <strong>the</strong> response, as it is returned both as a whole line or parsed.MethodsCreate(Path: string, Log:boolean) – create engine object (Path – <strong>the</strong> path to engine, Log ‐ whe<strong>the</strong>r to hold an engine log).Examplee:=TSEngine.Create('data\Engines\<strong>Rybka</strong> v2.3.2a.exe', true);Free() – Release <strong>the</strong> created engine object.Examplee.Free;AnalyseToTime(Time: integer) – Start position analysis; Time – time in milliseconds for analysisExamplee.AnalyseToTime(1000);AnalyseToTime(Depth: integer) – Start position analysis; Depth – up to which depth to analyzeExamplee.AnalyseToDepth(9);SendUCICommand(Cmd: string) – send UCI‐command for <strong>the</strong> engine. It is not supposed that sending UCI commands is <strong>the</strong> commonscripts.Examplee.SendUciCommand('setoption name hash value 32');SetPosition(Position: string) – set <strong>the</strong> position specified in <strong>the</strong> full UCI – format (for example, 'startpos moves e2e4' or 'fen rnbqkbnr/Examplee.SetPosition('startpos moves c2c4 e7e5');SetFEN(FEN: string) – set <strong>the</strong> position specified as EPD string.Example
http://chessok.com/aqtiki/tiki-print_multi_pages.php97 <strong>of</strong> 144 26.05.2011 19:56e.SetFen('rnbqkbnr/8/8/8/8/8/8/RNBQKBNR w KQkq -');SetIgnoreMoves(Moves: string) – specify <strong>the</strong> ignored moves, comma is <strong>the</strong> separator between moves (for example 'e2e4,d7d8q'Examplee.SetIgnoreMoves('e2e4');Stop – stops <strong>the</strong> analysisExamplee.Stop;TestSuite(TestType:TSTestType; epd, Move: string; mintime, maxtime, mindepth, delay, evaluation: integer) – Creating a Test SuiTestType(tsBestMove, tsBadMove, tsbestEval, tsBestMoveAndEval), which sets what to check: whe<strong>the</strong>r it finds <strong>the</strong> best move, or bmove is move to analyze, mintime, maxtime (in seconds) and mindepth are parameters <strong>of</strong> engine. Delay is for how long should <strong>the</strong> ancan be set as ‐1 – if so, <strong>the</strong>y won't be taken in accountExamplee.TestSuite(tstBestMoveAndEval, s, 'e2e4', 5, 20, 7, 4, 9);print(e.TestRes);PropertiesStarted: boolean – it is TRUE if <strong>the</strong> engine started successfully.Exampleif e.Started <strong>the</strong>nEval: integer – The evaluation <strong>of</strong> last analyzed position (absolute).Examplee.Eval;Depth: integer – The depth <strong>of</strong> <strong>the</strong> last analyzed positionExamplee.Depth;Time: integer – The time <strong>of</strong> <strong>the</strong> last analyzed positionExamplee.Time;
http://chessok.com/aqtiki/tiki-print_multi_pages.php98 <strong>of</strong> 144 26.05.2011 19:56Nodes: integer – The number <strong>of</strong> nodes <strong>of</strong> <strong>the</strong> last analyzed positionExamplee.Nodes;NPS: integer – Nodes per second <strong>of</strong> <strong>the</strong> last analyzed positionExamplee.NPS;PV: string – Principal variationExamplee.PV;LastResponse: string – Last response <strong>from</strong> <strong>the</strong> engine.Examplee.LastResponse;LastPV: string – <strong>the</strong> last pv received <strong>from</strong> <strong>the</strong> engine.Examplee.LastPV;Bestmove: string – Best move calculated by engine after Stop command or after end <strong>of</strong> analysisExamplee.BestMove;Ponder: string – Ponder calculated by engine after Stop command or after end <strong>of</strong> analysisExamplee.Ponder;TestRes: string –Result <strong>of</strong> test suiteExamplee.TestRes;
http://chessok.com/aqtiki/tiki-print_multi_pages.php99 <strong>of</strong> 144 26.05.2011 19:56EevntsOnEngMsg procedure(Info: TSNodeInfo) – For determining procedures done with every engine response. Pr<strong>of</strong>ile: procedure OnExamplee.OnEngMsg := 'OnEngMsg';Some useful codeUsage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php100 <strong>of</strong> 144 26.05.2011 19:56vare: TSEngine; // Engine objects: string;procedure OnEngMsg(Sender: TSEngine; AResponse: integer; AValues: TStringList; ACommand: string);beginif Pos('depth 6', ACommand) > 0 <strong>the</strong>nSender.Stop;print(ACommand);{ case AResponse <strong>of</strong>rcId, rcUciOk, rcReadyOk, rcCar3Ok, rcCbr3Ok: print('ok command');rcOption: print('opt command');//rcBestMove, rcCopyProtection, rcRegistration, rcInfo, rcResponse,elseprint('o<strong>the</strong>r command');end; }end;if AValues.Values['depth'] '' <strong>the</strong>nprint('DP: ' + AValues.Values['depth']);beginclear;// Search engine and load itname := 'data\Engines\<strong>Rybka</strong> 3 1-cpu w32.exe'e := TSEngine.Create(name, true);e.OnEngMsg := 'OnEngMsg';if e.Started <strong>the</strong>nbegin// You may use low level UCI commandse.SetPosition('startpos moves c2c4 e7e5');e.SendUciCommand('setoption name hash value 32');e.SetFen('rnbqkbnr/8/8/8/8/8/8/RNBQKBNR w KQkq -');e.SetIgnoreMoves('');e.AnalyseToDepth(8);print('Last response: '+ e.LastResponse);print('Last PV: '+ e.LastPV);print('Last TimeLine: '+ e.LastTime);//last line with time updateprint('Last DepthLine: '+ e.LastDepth);//last line with depth updateprint('Last Eval: ' + IntToStr(e.Eval));print('Last Depth: ' + IntToStr(e.Depth));print('Last Time: ' + IntToStr(e.Time));print('Last Nodes ' + IntToStr(e.Nodes));print('Last NPS: ' + IntToStr(e.NPS));print('Last PV: ' + e.PV);//string!endelsebeginShowMessage('Engine was not started. Please check <strong>the</strong> path '+name);end;e.Free;end.4.3.5 IDeA classes
http://chessok.com/aqtiki/tiki-print_multi_pages.php101 <strong>of</strong> 144 26.05.2011 19:56There're three IDeA classes: TIDeATask, TIDeAQuality, and TIdeaProjectInfoTIDeATaskTIDeAQualityTIdeaProjectInfoTIdeaTreeExpandOptionsTIdeaProlongationOptionsTIdeaRootNodeTIdeaProjectNoteFunctions that work only in IDeAFunctions that work only in IDeA Project view4.3.5.1 TIDeATask↑ Is used in: Nothing↓ Uses: TIDeAQuality, __TBackgroundEvent?__This is a special task class, that is provides an easy way to make tasks and add <strong>the</strong>m to IDeA.Declaration:vartask: TIDeATask;ProperiesFEN:String ‐ getting and setting a FEN <strong>of</strong> a taskExampletask.FEN;ProlongDepth: integer ‐ for how many moves <strong>the</strong> branch is played fur<strong>the</strong>rExampletask.prolongDepth := 10;AltCount: integer ‐ how many alternatives to findExampletask.AltCount := 2;AltMinScore: integer ‐ <strong>the</strong> lower bound <strong>of</strong> <strong>the</strong> score <strong>of</strong> an alternative (or in autoplay)Example
http://chessok.com/aqtiki/tiki-print_multi_pages.php102 <strong>of</strong> 144 26.05.2011 19:56task.AltMinScore := 300;AltMaxScore: integer ‐<strong>the</strong> upper boundExampletask.AltMaxScore := 450;UserTask: booleanif true, task gets higher proirityExampletask.UserPriority := true;IgnoreMoves: stringline <strong>of</strong> moves to ignore, such as 'e2e4,d2d4,c1d3'Exampletask.IgnoreMoves := 'e2e4 d7d5';Quality: TIdeaQuality ‐ an TIDeAQuality objectExampletask.Quality := AQuality;Event: TBackGroundEvent ‐ a TBackgroundEvent object?Exampletask.Event := ev;//see example for background eventMethodsCreate ‐ creates a task object.Exampletask := TIDeATask.Create;SetUciPosition(APosition: string) loads UCI string into a task.
http://chessok.com/aqtiki/tiki-print_multi_pages.php103 <strong>of</strong> 144 26.05.2011 19:56Exampletask.SetUCIPosition('startpos e2e4');SetQuality(ATime: integer; ADepth: integer; AOp: integer; AWaitNextDepth: boolean; AMaxTime: integer) ‐ sets Task qualityExampleSetQuality(1000, 14, 1, false, 1300)4.3.5.2 TIDeAQuality↑ Is used in: TIDeATask, TIDeAProjectInfo↓ Uses: nothingThis is a quality <strong>of</strong> IDeA task. It has only propertiesDeclaration:varq: TIDeAQuality;PropertiesTime: integer ‐ getting and setting time for a task;Exampleq.Time := 1000;Depth: integer ‐ getting and setting Depth for a task;Exampleq.Depth := 14;Op: integer ‐ getting and setting options <strong>of</strong> a task: 0 ‐ Time OR Depth; 1 ‐ Time AND DepthExampleq.Op := 1;WaitNextDepth: boolean ‐ sets whe<strong>the</strong>r to wait for next depth in analysis or notExampleq.WaithNextDepth := true;MaxTime: integer ‐ getting and setting max time for a task;
http://chessok.com/aqtiki/tiki-print_multi_pages.php104 <strong>of</strong> 144 26.05.2011 19:56Exampleq.MaxTime := 2000;4.3.5.3 TIdeaProjectInfo↑ Is used in: Nothing↓ Uses: TIDeAQuality, TIdeaTreeExpandOptions, TIdeaProjectNoteDeclaration:varIdPr: TIDeAProjectInfo;This is a class that contains all information about <strong>the</strong> IDeA project.PropertiesID: integer ‐ <strong>the</strong> unique ID <strong>of</strong> <strong>the</strong> project. It's read‐onlyExampleprint(IdPr.ID);Active: boolean ‐ returns true, if project is activeExampleif IdPr.Active <strong>the</strong>nDescription: String ‐ <strong>the</strong> description <strong>of</strong> a project. It's also read‐onlyExampleprint(IdPr.Description);ProjectState: TProjectState ‐ returns <strong>the</strong> state <strong>of</strong> <strong>the</strong> project. Can be: ipsIdle, ipsWaitingTaskGeneration, ipsWaitingAnalysis, ipsWaitiExampleif IdPr.ProjectState = ipsIdle <strong>the</strong>nProjectType: TprojectType ‐ returns <strong>the</strong> type <strong>of</strong> <strong>the</strong> project. Can be iptLocal, iptRemoteExampleif Idpr.projectType = iptRemote <strong>the</strong>n
http://chessok.com/aqtiki/tiki-print_multi_pages.php105 <strong>of</strong> 144 26.05.2011 19:56CpuUsage: integer ‐ <strong>the</strong> per cent <strong>of</strong> CPU used.ExampleIdPr.CpuUsage := 50;AutoProlongation: Boolean ‐ Should <strong>the</strong> analysis queue be expanded (using IDEA methods) or notExampleIdPr.AutoProlongation:= true;AnalysisTreeName: Boolean ‐ <strong>the</strong> name <strong>of</strong> <strong>the</strong> current IDeA tree.ExampleIdPr.AnalysisTreeName:= 'Mytree';MasterTreeName: Boolean ‐ <strong>the</strong> name <strong>of</strong> <strong>the</strong> current Maser tree(if exists).ExampleIdPr.MasterTreeName:= 'Mytree';StorageFileName: String ‐ <strong>the</strong> name <strong>of</strong> <strong>the</strong> XML‐file, read‐onlyExampleIdPr.StorageFileName:= 'file.xml';TreeConfigName: String ‐ <strong>the</strong> name <strong>of</strong> <strong>the</strong> tree configuration used for <strong>the</strong> projectExampleIdPr.TreeConfigName:= 'IDEA';QualitySettings: TIdeaQuality ‐ <strong>the</strong> setting <strong>of</strong> <strong>the</strong> project (default)ExampleIdPr.QualitySettings.Time:= 1000;RootNodes: TStringList ‐ <strong>the</strong> list <strong>of</strong> <strong>the</strong> project root nodes. Objects in RootNodes stringlist are integers <strong>of</strong> node state: 0 is disabled, 1 isExampleprint(IdPr.RootNodes.Strings[0]);//first root
http://chessok.com/aqtiki/tiki-print_multi_pages.php106 <strong>of</strong> 144 26.05.2011 19:56TreeExpandOptions:TIdeaTreeExpandOptions ‐ options <strong>of</strong> tree expand.Exampleprint(IdPr.TreeExpandOptions.TreeWidth);//first rootProjectNotes: TObjectList ‐ <strong>the</strong> list <strong>of</strong> notes. Notes are TIdeaProjectNoteExamplevarol: TObjectList;beginend;ol := IdPr.ProjectNotes['Good'];4.3.5.4 TIdeaTreeExpandOptionsIs used in: TIDeAProjectInfoUses: TIdeaProlongationOptions,DeclarationvarTrEx: TIDeATreeExpandOptionsPropertiesTreeWidth: integer ‐ Tree width percentage, 0‐100. 0 meas <strong>the</strong> narrowest tree, 100 ‐ <strong>the</strong> widest.ExampleTrEx.TreeWidth := 56;WhiteAlternativesLimit: integer ‐ Alternatives limit for White. When set, disables alternative search when <strong>the</strong> appropriate limit is reachExampleTrEx.WhiteAlternativesLimit:= 4;BlackAlternativesLimit: integer ‐ Alternatives limit for Black. When set, disables alternative search when <strong>the</strong> appropriate limit is reachExampleTrEx.BlackAlternativesLimit:= 4;VariationLengthLimit: integer ‐ No variation is prolongated if its length is above (or equal to) this number. Zero setting disables <strong>the</strong> lim
http://chessok.com/aqtiki/tiki-print_multi_pages.php107 <strong>of</strong> 144 26.05.2011 19:56ExampleTrEx.VariationLengthLimit:= 14;ProjectMinScore: integer ‐ Score bounds for <strong>the</strong> project. Any leaves with score outside <strong>of</strong> <strong>the</strong> bounds are not considered.ExampleTrEx.ProjectMinScore:= 7;ProjectMaxScore: integer ‐ Score bounds for <strong>the</strong> project. Any leaves with score outside <strong>of</strong> <strong>the</strong> bounds are not considered.ExampleTrEx.ProjectMaxScore:= 15;FalseAlarmCheckEnabled: Boolean ‐ Shows whe<strong>the</strong>r <strong>the</strong> 'false alarm check' is enabled or notExampleTrEx.FalseAlarmCheckEnabled := true;FalseAlarmCheckDepth: Integer ‐ Number <strong>of</strong> plies <strong>the</strong> 'better' alternative is prolongated when false alarm check is on.ExampleTrEx.FalseAlarmCheckDepth := 6;FalseAlarmCheckMaxDelta: Integer ‐ If cumulative score difference > FalseAlarmCheckMaxDelta, <strong>the</strong>n FA check is not performedExampleTrEx.FalseAlarmCheckMaxDelta:= 3;ThematicMovesString: Integer ‐ Additional string setting for <strong>the</strong>matic moves. Both moves and additional parameters are set in it.ExampleTrEx.ThematicMovesString:= 'e2e4';MainlineVerificationEnabled: Integer ‐ Shows whe<strong>the</strong>r <strong>the</strong> mainline verification is enabled.ExampleTrEx.MainlineVerificationEnabled:= true;OnEndOfStageScript: string ‐ Path to outer script which is used to generate tasks
http://chessok.com/aqtiki/tiki-print_multi_pages.php108 <strong>of</strong> 144 26.05.2011 19:56ExampleTrEx.OnEndOfStageScript:= true;OnEndOfStageScriptEnabled: boolean ‐ returns true if a script for <strong>the</strong> end‐<strong>of</strong>‐state is enabledExampleTrEx.OnEndOfStageScriptEnabled:= true;ProlongationOptions: TIdeaProlongationOptions ‐ Prolongation optionsExampleTrEx.ProlongationOptions.ProlongationNodesFraction:= 4,5;4.3.5.5 TIdeaProlongationOptions↑ Is used in: TIdeaTreeExpandOptions↓ Uses: nothingThis is a quality <strong>of</strong> IDeA task. It has only propertiesDeclaration:varPrOp: TIdeaProlongationOptions;PropertiesProlongationNodesFraction: Double ‐ fraction <strong>of</strong> all leaf nodes that are prolongatedExamplePrOp.ProlongationNodesFraction := 6,7;ProlongationCount0: Integer Maximum number <strong>of</strong> nodes to prolongate, with width=0.ExamplePrOp.ProlongationCount0 := 3;ProlongationCount100: Integer Maximum number <strong>of</strong> nodes to prolongate, with width=100. O<strong>the</strong>r values are linearly interpolated betwExamplePrOp.ProlongationCount100 := 14;ScoreCategoryLevel0: Integer Score category level: <strong>the</strong> leaves with lower category are picked first.
http://chessok.com/aqtiki/tiki-print_multi_pages.php109 <strong>of</strong> 144 26.05.2011 19:56ExamplePrOp.ScoreCategoryLevel0:= 4;ScoreCategoryLevel100: Integer Score category level: <strong>the</strong> leaves with lower category are picked first. O<strong>the</strong>r values are linearly interpoExamplePrOp.ScoreCategoryLevel100:= 16;PreferredSideMask: Integer 1*White + 2*Black. Don't prolongate suboptimal answers to preferred side's suboptimal moves.ExamplePrOp.PreferredSideMask:= 1;4.3.5.6 TIdeaRootNode↑ Is used in: TIDeAProjectInfo↓ Uses: TSGameDeclaration:varr1: TIDeARootNode;PropertiesEnabled: boolean – checking if <strong>the</strong> root is enabledExampleif r1.Enabled <strong>the</strong>nEval: integer – sets eval between ‐1 and 100.Exampler1.Eval := 100;Comment: string – checking if <strong>the</strong> root is enabledExampleprint (r1.Comment);FEN: string – checking if <strong>the</strong> root is enabledExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php110 <strong>of</strong> 144 26.05.2011 19:56print (r1.FEN);MethodsCreate – create <strong>the</strong> rootExampler1 := TIDeARootNode.Create;Assign(Ano<strong>the</strong>r: TIdeaRootNode) – assign a rootExampler1.Assign(r2);CopyToGame(Game: TSGame) – copies to a GameExampler1.CopyToGame(gam);FillFromGame(Game: TSGame) – takes roots <strong>from</strong> a gameExampler1.FillFromGame(gam)Usage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php111 <strong>of</strong> 144 26.05.2011 19:56varproj: TIdeaProjectInfo;r1, r2: TIdeaRootNode;roots: TObjectList;i: integer;gm: TSGame;beginclear;r1 := TIdeaRootNode.Create;r1.FEN := 'r1bqkb1r/ppp2ppp/2n5/3np1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq - 0 6';r1.Comment := 'Test 1';r1.Enabled := False;AddIdeaRootNode(r1); // deprecated methodproj := GetCurrentProject;if Assigned(proj) <strong>the</strong>nbeginr2 := TIdeaRootNode.Create;r2.Assign(r1);r2.Comment := 'Test 2';proj.RootNodes.Add(r2); // new methodgm := TSGame.Create;gm.AddMove('e2e4');gm.LnGoTo(gm.LineCount, True);gm.AddMove('e7e5');r2 := TIdeaRootNode.Create;r2.Comment := 'Test 3';r2.FillFromGame(gm);gm.Free;proj.RootNodes.Add(r2); // new methodend;UpdateCurrentProject(proj);gm := TSGame.Create;roots := proj.RootNodes; // just for conviniencefor i := 0 to roots.Count - 1 dobeginr1 := TIdeaRootNode(roots.Items[i]);r1.CopyToGame(gm);print(Format('%d: %s [%d] %s (%d)',[i, Copy(r1.FEN, 1, 20), r1.Eval,r1.Comment, gm.LineCount]));end;gm.Free;end.4.3.5.7 TIdeaProjectNoteIs used in: TIDeAProjectInfoUses: TSGameDeclaration
http://chessok.com/aqtiki/tiki-print_multi_pages.php112 <strong>of</strong> 144 26.05.2011 19:56varPrN: TIDeAProjectNote;PropertiesComment : string ‐ A comment itselfExamplePrN.Comment:= 'some comment';Date: string ‐ A date <strong>of</strong> a commentExamplePrN.Date:= '01.01.2001 12:34:24';MethodsCreate() – creating a noteExamplePrN := TIdeaProjectNote.Create;Assign(Ano<strong>the</strong>r: TIdeaProjectNote) – creating a noteExamplePrN.Assign(PrN2);//Prn2 is TIdeaProjectNote;FillFromGame(gam: TSGame) – loading notes <strong>from</strong> a gameExamplePrN.FillFromGame(gam);Usage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php113 <strong>of</strong> 144 26.05.2011 19:56varproj: TIdeaProjectInfo;notelist: TObjectList;i: integer;n1, n2: TIdeaProjectNote;beginclear;proj := GetCurrentProject;if Assigned(proj) <strong>the</strong>nbeginnotelist := proj.ProjectNotes['Good'];for i := 0 to notelist.Count - 1 dobeginn1 := TIdeaProjectNote(notelist.Items[i]);print(Format('%d: %s [%d - %d] %s (%s)',[i, Copy(n1.FEN, 1, 20), n1.InitEval, n1.CurrentEval,n1.Comment, n1.Date]));end;n1 := TIdeaProjectNote.Create;n1.Comment := 'test';n1.Date := '02.09.2010 14:29:07';notelist.Add(n1);n2 := TIdeaProjectNote.Create;n2.Assign(n1);n2.Comment := 'Test 2';proj.ProjectNotes['Critical'].Add(n2);gm := TSGame.Create;gm.AddMove('e2e4');gm.LnGoTo(gm.LineCount, True);gm.AddMove('e7e5');gm.LnGoTo(gm.LineCount, True);n2 := TIdeaProjectNote.Create;n2.Comment := 'Test 3';n2.FillFromGame(gm);gm.Free;notelist.Add(n2);end;end.UpdateCurrentProject(proj);4.3.5.8 Functions that work only in IDeAThese are so beloved functions that can add tasks to IDeA, or Root node, etcAddIdeaTask(ATask:TIdeaTask):boolean: adds IDeA TIDeATask.ExampleAddIdeaTask(MyTask)AddIdeaRootNode(root:TIdeARootNode): adds IDeA task.
http://chessok.com/aqtiki/tiki-print_multi_pages.php114 <strong>of</strong> 144 26.05.2011 19:56ExampleAddIdeaRootNode('1Q1q3r/1p1k1pp1/p7/n2p3p/r2P3P/2P5/5PP1/1R2R1K1 w', 'myIdeaRoot');GetIdeaTree:TSTreeScanner creates a tree <strong>from</strong> an IDeA projectExamplet := GetIDeATree;GetIdeaStage:integer: returns a stage Constants are tesProlong, tesAlternative, tesDeepProlong, tesMainlineVerificationExamplei := GetIDeAStage;AddIdeaTask(ATask:TIdeaTask): adds IDeA task.Exampleni1 := t.Search(ni2)// ni1, ni2 is TSNodeInfoGetIdeaActiveRootNodes:TStringList: returns a list <strong>of</strong> active IDeA root nodes in FEN strings;Examplesl := GetIDeAActiveRootNodes;GetIdeaTotalRootNodes:TStringList: returns a list <strong>of</strong> all IDeA root nodes in FEN strings;Examplesl := GetIDeATotalRootNodes;StopTaskGeneration stops IDeAExampleIdeaForceStop;ContinueTaskGeneration makes IDeA continue analysis.ExampleIdeaForceContinue;UpdateCurrentProj(AProject:#c30:TIdeaProjectInfo~~)~~ updates <strong>the</strong> project so <strong>the</strong> changes start working (allowed one time at <strong>the</strong>Example
http://chessok.com/aqtiki/tiki-print_multi_pages.php115 <strong>of</strong> 144 26.05.2011 19:56UpdateCurrentProj(IdPr);4.3.5.9 Functions that work only in IDeA Project viewIDEA_Running:Boolean– returns true is a project is runningExampleif IDEA_Running <strong>the</strong>nIDEA_Start– starts IDeAExampleIDEA_Start;IDEA_Stop(WaitTasksToFinish:Boolean, Minimax AfterFinish:Boolean, MakeAccuratePositionCount: Boolean)– Stops IDeA with givExampleIDeAStop(flase, true, false);//stops IDeA and minimaxes after finish4.3.6 Delphi classesTable <strong>of</strong> contents:Class TObjectListClass TStringList4.3.6.1 Class TObjectList↑ Is used in: Nothing↓ Uses: NothingDeclaration:varol: TObjectListIt is a list <strong>of</strong> objects. A Delphi object is any descendant <strong>of</strong> <strong>the</strong> class TObject. In this class any data not bigger than 4 bytes can be stored (note, that floatadd or remove items, clear <strong>the</strong> whole list, insert items into a certain place and get <strong>the</strong>ir indexes. For more information see any Delphi or Pascal manualMethods
http://chessok.com/aqtiki/tiki-print_multi_pages.php116 <strong>of</strong> 144 26.05.2011 19:56Create(OwnsObject: boolean): TObjectList – creating an objectObjectList should accept only boolean as parameter. String is treated as False.If <strong>the</strong> OwnsObjects property is set to True (<strong>the</strong> default), TObjectList controls <strong>the</strong> memory <strong>of</strong> its objects, freeing an object when its index is reassigned; wTObjectList instance is itself destroyed.If you store Integers in <strong>the</strong> list instead <strong>of</strong> objects, <strong>Scripter</strong> tries to free memory on deletion and causes access violation on this.Exampleol := TobjectList.Create(true);Add(TObject): integer – adding an item into a listExampleol.Add(AObject);Clear() – delete all <strong>the</strong> items <strong>from</strong> a list.Exampleol.Clear;Delete(integer) – deleting one item by its number.Exampleol.Delete(45);Remove(TObject) – removing an object <strong>from</strong> a list, returns its number.Examplei:= ol.Remove(Aobject);//I is integerIndexOf(TObject): integer – getting an index <strong>of</strong> an object.Examplei:=ol.IndexOf(AObject);Insert (Index: integer, Object: TObject) – inserting an object to a given place.Exampleol.Insert(12,AObject);PropertiesItems[Index: integer]: TObject – items <strong>of</strong> a list. Writable.
http://chessok.com/aqtiki/tiki-print_multi_pages.php117 <strong>of</strong> 144 26.05.2011 19:56ExampleAObject := ol.Items[2];ol.Items[4] := AObject;Count: integer – number <strong>of</strong> <strong>the</strong> objects.Examplefor i:=0 to ol.Count-1 doUsage examplevarol: TObjectList;i: integer;ni: TSNodeInfo;begin…ol := TObjectList.Create;for i:=0 to ni.Count-1 dool.Add(ni.Moves[i].Anot);for i:=0 to ol.Count-1 doprint (inttostr(TSAnnotation(ol.Items[i]).Eval));ol.Free;end.4.3.6.2 Class TStringList↑ Is used in: NONE↓ Uses: NONEDeclaration:varsl: TStringList;This very list contains, in <strong>the</strong> first place strings that are text lines. Also to every string an object can be added. You can carry <strong>the</strong> same operations as witValues, etc. For more information see any Delphi or Pascal manual.MethodsCreate: TStringList – creates an object.Examplesl := TobjectList.Create(true);Add(string): integer – adding a string into a list
http://chessok.com/aqtiki/tiki-print_multi_pages.php118 <strong>of</strong> 144 26.05.2011 19:56Examplesl.Add('aaa');AddObject(string, Tobject):integer – adding a string AND an object into a list.Examplesl.AddObject('aaa', Aobject);//Aobject is <strong>of</strong> class TObjectAssign(Ano<strong>the</strong>rList:TStringList) – Assigns one list to ano<strong>the</strong>r.Examplesl1.Assign(sl2);//sl1, sl2 - stringlistsDelete(integer) ‐ deleting an item by number.Examplesl.Delete(2);Clear – deleting all strings.Examplesl.Clear;GetText: boolean – getting stringlist as a text, delimited by CRLF.Examplesl.GetText//returns item1, item2, item3 each on its own lineExchange(AFirst: integer, ASecond: integer) ‐ exchange places <strong>of</strong> <strong>the</strong> strings.Examplesl.Exchange(7, 12);IndexOf(string): integer – getting Index <strong>of</strong> a string.Exampleif sl.IndexOf('mama') > 12 <strong>the</strong>nIndexOfName(string): integer ‐ getting index o a name.
http://chessok.com/aqtiki/tiki-print_multi_pages.php119 <strong>of</strong> 144 26.05.2011 19:56Exampleif sl.IndexOfName('bro<strong>the</strong>r') < 0//that means that <strong>the</strong>re's no item 'bro<strong>the</strong>r'Insert(Place: integer, Line: string) ‐Inserting a string into a given place.Examplesl.Insert(3, 'mama');//'mama' is put on <strong>the</strong> third placeInsertObject(Place: integer, Line: string, Object: TObject) – inserting a string AND an object into a given place.Examplesl.InserObject(3, 'mama', AObject);//AObject is TObjectLoadFromFile(FileName: string) – loading a stringlist <strong>from</strong> a file . The strings in <strong>the</strong> file should be separated with ‘;’Examplesl.LoadFromFile('strings.txt');SaveToFile(FileName:`string) – saving a stringlist, separated by ‘;’ to a file.Examplesl.SaveToFile('strings.txt');SetText(string) ‐ setting text.Examplesl.SetText('mama');//all stringlist consists <strong>of</strong> 'mama'Sort – sortes <strong>the</strong> strings alphabeticallyExamplesl.Sort;PropertiesDuplicates: dupIgnore, dupAccept, dupError – setting and getting what to do with duplicates. Constants are dupAccept (delete dupliExamplesl.Duplicates := dupIgnore;Sorted: boolean – gets and sets whe<strong>the</strong>r <strong>the</strong> list is sorted. It's false (unsorted) by default
http://chessok.com/aqtiki/tiki-print_multi_pages.php120 <strong>of</strong> 144 26.05.2011 19:56Examplesl.Sorted := true;CaseSensitive: boolean – making list case‐(in)sensitiveExamplesl.CaseSensitive := true;CommaText: string – returns all <strong>the</strong> elements in one string, separated by ‘;’.Exampleprint(sl.CommaText);Count: integer – returns <strong>the</strong> number <strong>of</strong> strings in a list.Examplefor i:=0 to sl.Count-1//cycle through all itemsDelimiter: char – setting a way to delimit stringsExamplesl.Delimiter := '%';//now when calling DelimitedText procedure you get strings delimited by '%'DelimitedText: string – creating a string with special delimitersExampleprint(sl.DelimitedText);Names[Index: integer]: string – getting and setting namesExampleprint (sl.Names[2]);//Name number 2Values[AName: string]: string – getting and setting valuesExampleprint(sl.Values[sl.Names[2]]);//Value <strong>of</strong> name number 2Strings[Index: integer]: string – getting and setting strings <strong>of</strong> a list
http://chessok.com/aqtiki/tiki-print_multi_pages.php121 <strong>of</strong> 144 26.05.2011 19:56Exampleprint(sl.Strings[3]); //string number 3Objects[Index: integer]: TObject – getting and setting objectsExamplesl.Objects[3];//returns TObjectText: string – getting all as a textExampleprint(sl.Text);Usage examplevart:TSTreeScanner;ni: TSNodeInfo;i: integer;str : TstringList;begint := TSTreeScanner.Create('data\ATrees\idea.hsh', False);//str := TStringList.Create;if t.Opened <strong>the</strong>nbeginprint ('opened');ni := t.SearchFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -');if ninil <strong>the</strong>nbeginstr := ni.AllBackPos;for i:=0 to Str.Count-1 doprint (str.Strings[i] +': '+TSMoveInfo(str.Objects[i]).Move);str.Free;end;ni.Free;end;t.Free;end.4.3.7 O<strong>the</strong>r ClassesTable <strong>of</strong> contents:Class TVariantListClass TPropertyListTCustomPropertyClass XMLParserClass TXMLTag
http://chessok.com/aqtiki/tiki-print_multi_pages.php122 <strong>of</strong> 144 26.05.2011 19:56Class TRegExprClass TBackgroundEvent4.3.7.1 Class TVariantList↑ Is used in: Nothing↓ Uses: NothingDeclaration:varvl: TVariantListIt is a special class used to store items that cannot be stored into ObjectList – I mean, that are bigger than 4 bytes. For instance, floating point numeralMethodsCreate: TVariantList – creating an instanceExamplevl := TVariantList.Create(true);Add(TVariant): integer – adding an item into a listExamplevl.Add(AVariant);Clear() – delete all <strong>the</strong> items <strong>from</strong> a list.Examplevl.Clear;Delete(integer) – deleting one item by its number.Examplevl.Delete(45);Remove(TVariant) – removing an item <strong>from</strong> a list, returns its number.Examplei:= vl.Remove(AVariant);//I is integer
http://chessok.com/aqtiki/tiki-print_multi_pages.php123 <strong>of</strong> 144 26.05.2011 19:56IndexOf(TVariant): integer – getting an index <strong>of</strong> an item.Examplei:=vl.IndexOf(AVariant);Insert (Index: integer, Avariant: TVariant) – inserting an item to a given place.Examplevl.Insert(12,AVariant);PropertiesItems[Index: integer]: TVariant – items <strong>of</strong> a list. Writable.ExampleAVariant := vl.Items[2];vl.Items[4] := AVariant;Count: integer – number <strong>of</strong> <strong>the</strong> items.Examplefor i:=0 to vl.Count-1 doExamplevarvl: TVariantList;i:integer;a: integer;c: variant;beginvl := TVariantList.Create;i:=9;c := i/2;vl.Add(12.5);for i:=1 to 10 dobeginvl.Add(i/2);end;print(FloatToStr(vl.Items[4]));for i:=0 to 10 doprint(FloatToStr(vl.Items[i]));vl.Free;end.4.3.7.2 Class TPropertyList↑ Is used in: Nothing
http://chessok.com/aqtiki/tiki-print_multi_pages.php124 <strong>of</strong> 144 26.05.2011 19:56↓ Uses: TCustomProperty, TStringList, TXMLTagDeclaration:varpr: TPropertyListThis is <strong>the</strong> list <strong>of</strong> engine propertiesMethodsCreate(OwnsObject: boolean): TPropertyList – creating an objectPropertyList should accept only boolean as parameter. String is treated as False.If <strong>the</strong> OwnsObjects property is set to True (<strong>the</strong> default), TPropertyList controls <strong>the</strong> memory <strong>of</strong> its objects, freeing an object when its index is reassignedTPropertyList instance is itself destroyed.If you store Integers in <strong>the</strong> list instead <strong>of</strong> objects, <strong>Scripter</strong> tries to free memory on deletion and causes access violation on this.Examplepr := TPropertyList.Create(true);Add(TCustomProperty): integer – adding an item into a listExamplepr.Add(AProperty);Clear() – delete all <strong>the</strong> items <strong>from</strong> a list.Examplepr.Clear;Delete(integer) – deleting one item by its number.Examplepr.Delete(45);Remove(TCustomProperty) – removing an object <strong>from</strong> a list, returns its number.Examplei:= pr.Remove(Property);//I is integerIndexOf(TCustomProperty): integer – getting an index <strong>of</strong> an object.Examplei:=pr.IndexOf(Property);
http://chessok.com/aqtiki/tiki-print_multi_pages.php125 <strong>of</strong> 144 26.05.2011 19:56Insert (Index: integer, Property: TCustomProperty) – inserting an object to a given place.Examplepr.Insert(12,Property);WriteToStringList (sl: TStringList) – writing a property list into a string listExamplepr.WriteToStringList(sl);WriteToXMLTag (t: TXMLTag) – writing a property list into a XMLTagExamplepr.WriteToXMLTag(t);ReadFromXMLTag (t: TXMLTag) – reading info <strong>from</strong> an XML tagExamplepr.ReadFromXMLTag(t);PropertiesItems[Index: integer]: TCustomProperty – items <strong>of</strong> a list. Writable.ExampleProperty:=pr.Items[2];pr.Items[4] := Property;Count: integer – number <strong>of</strong> <strong>the</strong> objects.Examplefor i:=0 to pr.Count-1 doName: string – a name <strong>of</strong> a listExamplepr.Name := 'test';Usage Example
http://chessok.com/aqtiki/tiki-print_multi_pages.php126 <strong>of</strong> 144 26.05.2011 19:56varroot, t: TXMLTag;i: integer;pl: TPropertyList;sl: TStringList;beginclear;root := LoadXML('e:\Temp\engines.xml');if Assigned(root) <strong>the</strong>ntryt := root.FindChild('Personalities');if Assigned(t) <strong>the</strong>nbeginpl := TPropertyList.Create;sl := TStringList.Create;for i := 0 to t.ChildCount - 1 dobeginpl.ReadFromXMLTag(t.Children[i]);if pl.Count > 0 <strong>the</strong>nif SetupPropertiesDlg(pl, pl.Name +' Setup') <strong>the</strong>nbeginpl.WriteToStringList(sl);print(sl.CommaText);Break;end;end;sl.Free;pl.Free;end;finallyroot.Free;end;end.4.3.7.3 TCustomProperty↑ Is used in: TPropertyList↓ Uses: TStringListAll <strong>the</strong> properties that can be set for <strong>the</strong> dialogues. It has a number <strong>of</strong> descendants with <strong>the</strong>ir own propertiesDeclaration:varprop: TCustomProperty;Of TCustomPropertyPropertiesName: string – Property nameExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php127 <strong>of</strong> 144 26.05.2011 19:56prop.Name := 'Custom';StringValue:Value: string – Getting and setting a string valueExampleprop.StringValue := 'true';ObjType: TPropTypes – reading a type <strong>of</strong> an object (read‐only!)Exampleprint (prop.ObjType);OwnerID: string – ID <strong>of</strong> an object (writable)Exampleprop.OwnerID := 'first prop';MethodsCreate(AOwnerID: string):TCustomProperty ‐ creating a propertyExampleprop := TCustomProperty.Create('property');ReadFromXMLTag(Tag: TXMLTag)Exampleprop.ReadFromXMLTag(ATag);WriteFromXMLTag(Tag: TXMLTag)Exampleprop.WriteToXMLTag(ATag);First descendantsTCustomProperty has a number <strong>of</strong> descendants. The first set <strong>of</strong> children are:TIntegerPropertyHas all <strong>the</strong> methods and properties <strong>of</strong> TCustomProperty, andValue: integer – any value. Can be read and writtenExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php128 <strong>of</strong> 144 26.05.2011 19:56prop.Value := 5;DefValue: integer – any value. Can be read and writtenExampleprop.DefValue := 8;TStringPropertyValue: string – any value. Can be read and writtenExampleprop.Value := 'aaa';DefValue: string – any value. Can be read and writtenExampleprop.DefValue := 'bbb';TBooleanPropertyValue: boolean – any value. Can be read and writtenExampleprop.Value := true;DefValue: boolean – any value. Can be read and writtenExampleprop.DefValue := false;Of TSliderPropertyDescendant <strong>of</strong> TIntegerProperty, has all its functions andMinValue:integer – Getting and setting <strong>the</strong> minimum valueExampleprop.MinValue := 4;MaxValue:integer – Getting and setting max valueExampleprop.MaxValue := 13;
http://chessok.com/aqtiki/tiki-print_multi_pages.php129 <strong>of</strong> 144 26.05.2011 19:56Of TCheckPropertyDescendant <strong>of</strong> TBooleanProperty, has all its properties. The most important isValue: boolean – Property valueExampleprop.Value:= true;Of TCombotextPropertyDescendant <strong>of</strong> TStringproperty, has all its properties andOptions: string – Property optionsExampleprop.Options := 'rare,seldom,"all <strong>the</strong> time"';Of TEditPropertyDescandant od TString property, has all its properties. Thne most important isStringValue:Value: string – Getting and setting a string valueExampleprop.StringValue := 'test';Note that only last four classes describe a dialogue, all o<strong>the</strong>rs are invisible!Usage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php130 <strong>of</strong> 144 26.05.2011 19:56varpl: TPropertyList;cp: TCustomProperty;t: TXmlTag;beginpl := TPropertyList.Create;pl.Name := 'test';cp := TSliderProperty.Create(pl.Name);cp.Name := 'Sample Slider';TSliderProperty(cp).Value := 7;TSliderProperty(cp).MinValue := 0;TSliderProperty(cp).MaxValue := 15;pl.Add(cp);cp := TCheckProperty.Create(pl.Name);cp.Name := 'Sample Checkbox';TCheckProperty(cp).Value := True;pl.Add(cp);cp := TComboTextProperty.Create(pl.Name);cp.Name := 'Sample Select';TComboTextProperty(cp).Options := 'rare,seldom,"all <strong>the</strong> time"';cp.StringValue := 'rare';pl.Add(cp);cp := TEditProperty.Create(pl.Name);cp.Name := 'Sample Edit';cp.StringValue := 'test';pl.Add(cp);if SetupPropertiesDlg(pl, pl.Name +' Setup') <strong>the</strong>nbegint := TXMlTag.Create;t.TagName := 'opt';pl.WriteToXmlTag(t);WriteXML(t, 'e:\temp\cp.xml');t.Free;end;pl.Free;end.4.3.7.4 Class XMLParser↑ Is used in: NONE↓ Uses: NONEDeclaration: no.This class works with XML tree. The most important functions are provided by <strong>the</strong> instances <strong>of</strong> TXMLTag class, while <strong>the</strong> Parser provides conversions oand reads XML tree <strong>from</strong> a file.Methods
http://chessok.com/aqtiki/tiki-print_multi_pages.php131 <strong>of</strong> 144 26.05.2011 19:56StringToBool(Line: string): boolean – converts string to booleanExampleStringToBool('0');//returns falseStringToInt(Line: string): integer – converts string to integerExampleStringToInt('4');//returns integer;Koi8ToWin(string) – converts KOI8 encoding to Win1251ExampleKoi8ToWin('mama');//returns 'mama' in Win1251CP866ToWin(string) – converts CP866 encoding to Win1251ExampleCp866ToWin('papa');//returns 'papa' in Win1251LoadXML(AFileName: string): TXMLTag – loading XML file into a tag (root tag)Exampleroot :=LoadXML('data\engines.xml');WriteXML(ARootTag: TXMLTag, AFileName: string, AEncoding: string, APreserveWhiteSpace: boolean) – writes a tag with all <strong>the</strong> c(default without).ExampleWriteXML(root,'engines-res.xml');//root is TXMLTagUsage example: look here4.3.7.5 Class TXMLTag↑ Is use in: XMLParser↓ Uses: NONEDeclaration:varTTag: TXMLTag
http://chessok.com/aqtiki/tiki-print_multi_pages.php132 <strong>of</strong> 144 26.05.2011 19:56The main class working with XML. It can run through <strong>the</strong> tree forward and backward, Find children tags and given values, and stores all XML data: tagMethodsCreate() – creating a tag.Exampleroot := TXMLTag.Create;TTag := TXMLTag.Create(root);//TTag is a chil od a root tagCreateCopy(ATag: TXMLTag) – creating a copy <strong>of</strong> a tag (result is ano<strong>the</strong>r object)Exampleroot.CreateCopy(ATag);//root is a copy <strong>of</strong> ATag; 2 objects were createdMakeCopy (ATag: TXMLTag) – making a copy <strong>of</strong> a tag (new index that indicates <strong>the</strong> same object)Exampleroot.MakeCopy(ATag);//root is a copy <strong>of</strong> ATag; 1 object was createdValuePresents(Value: string): boolean – checking if a value exists in <strong>the</strong> list <strong>of</strong> valuesExampleif TTag.ValuePresents('mama') <strong>the</strong>nGetNext: TXMLTag – getting <strong>the</strong> next tag ‐ a child or a bro<strong>the</strong>r with <strong>the</strong> bigger indexExampleATag := TTag.GetNext;//ATag is TXMLTagGetPrev: TXMLTag – getting <strong>the</strong> previous tag – a parent or bro<strong>the</strong>r with bigger indexExampleATag := TTag.GetNext;//ATag is TXMLTagFindChild(TagName: string, Index: integer): TXMLTag – finding a childExampleATag := root.FindChild('mama', 3);ClearChildren – clearing a list <strong>of</strong> <strong>the</strong> children
http://chessok.com/aqtiki/tiki-print_multi_pages.php133 <strong>of</strong> 144 26.05.2011 19:56Exampleroot.ClearChildren;DeleteValue(AName: string) – deleting a valueExampleTTag.DeleteValue('papa');PropertiesChildCount: integer – <strong>the</strong> number <strong>of</strong> childrenExamplefor i:=0 to root.ChildCount doTagName: string – a name <strong>of</strong> a tag (writable)ExampleATag.TagName := 'mama';Values[AName: string]: string – getting and setting a name <strong>of</strong> <strong>the</strong> field and its valueExampleATag.Values['parents'] := 'mama';IntValues[AName: string]: integer – getting and setting an integer valueExampleATag.IntValues['parents'] := 2;Children[Index: integer]: TXMLTag – a list <strong>of</strong> childrenExampleATag := ATag.Children[3];Parent: TXMLTag – a parent <strong>of</strong> <strong>the</strong> current tagExampleroot := ATag.Parent;Usage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php134 <strong>of</strong> 144 26.05.2011 19:56varroot: TXMLtag; //root tagengines: TXMLTag;//engine tagt: TXMLTag;e: TSEngine; //engine objectpath: string; //path to <strong>the</strong> engineAqPath: string;function GetPath (ATag: TXMLTag): string;beginengines := TXMLTag.Create; //Creating a child tagengines := ATag.FindChild('Engines'); //filling tags with datafor i:=0 to engines.ChildCount-1 dobegint := engines.Children[i];//search throgh all <strong>the</strong> childrenif t.Values['name'] = '<strong>Rybka</strong> 3 w32' <strong>the</strong>n // looking for <strong>the</strong> needed enginebegins := Copy(t.Values['path'], 3, Length(t.Values['path']));//creating a half <strong>of</strong> pathlineresult := AqPath + s;//making a path <strong>from</strong> <strong>the</strong> one found in XML and a special user variableend;end;Engines.Free;end;beginpath := '';AqPath := 'C:\ProgramFiles\<strong>Aquarium</strong>\';root := TXMLTag.Create;//creating a tagroot := LoadXML('data/engines.xml'); //loading an XML tree <strong>from</strong> fileif Assigned (root) <strong>the</strong>n //check that succeedpath := GetPath(root);if path '' <strong>the</strong>nbegine := TSEngine.Create(path); //creating an engine objectif e.Started <strong>the</strong>nbeginprint ('engine started');//Starting analyzes := e.AnalyseToDepth(12);//Inserting into an XML tagroot.ClearChildren; //clear <strong>the</strong> root tagroot.TagName := 'Analyse'; //setting a tagname//Creating a first childEngines := TXMLTAg.Create(root);Engines.TagName := 'Engine';Engines.Values['Path'] := path;//Setting values//Creating a "grandchild"t := TXMLTag.Create(Engines);t.Values['an_res'] := s;t.TagName := 'Data';//Setting valuest.Values['Eval']:=e.Eval;t.Values['Depth'] := e.Depth;t.Values['Nodes'] := e.Nodes;t.Values['NPS'] := e.NPS;t.Values['PV'] := e.PV;
http://chessok.com/aqtiki/tiki-print_multi_pages.php135 <strong>of</strong> 144 26.05.2011 19:564.3.7.6 Class TRegExpr↑ Is used in: NONE↓ Uses: NONEDeclaration:varRegExp: TRegExprUsing this class, you can append regular expressions to any string. You can execute your expression once or find all suitable occurrences, substitute maMethodsCreate() – creating an expressionExampleRegExp := TRegExpr.Create;Exec(string): boolean – execute a regular expressionExampleRegExp.Exec (s);//s is source stringExecNext(string): boolean – executing regular expression while it is possible (only after Exec procedure)Exampleuntil not RegExp.ExecNextSubstitute(string): string – substituting matchesExampleRegExp.Substitute('$3$2$1');Split(Input: string, Result: TStringList) – splitting matches and writing <strong>the</strong>m down into a StringListExampleRegExp.Split(s, sl);//s is input string, sl is a StringListPropertiesMatch[Index: integer]: string – returns <strong>the</strong> match itself.
http://chessok.com/aqtiki/tiki-print_multi_pages.php136 <strong>of</strong> 144 26.05.2011 19:56ExampleRegExp.Match[0]Expression: string – getting and setting expressionExampleRegExp.Expression := '(\d+)([.,])(\d+)';CaseInsensitive: boolean – switching case‐sensitive/insensitiveExampleRegExp.CaseSensitive := false;Token_S: string – making regular expression sensitive only to strings and numbersExampleRegExp.Token_S := true;InputString: string – getting and setting input string (which to process)ExampleRegExpr.InputString := s;Greedy: boolean – making Regulars greedy or non‐greedy (greedy by default)ExampleRegExpt.Greedy := false;Count: integer – <strong>the</strong> number <strong>of</strong> matchesExamplefor i:=0 to RegExpr.Count-1 doMatchPos: integer – <strong>the</strong> position where a match startsExamplei := RegExpr.MatchPos;//i is integerMatchLen: integer – a length <strong>of</strong> a match
http://chessok.com/aqtiki/tiki-print_multi_pages.php137 <strong>of</strong> 144 26.05.2011 19:56ExampleCopy(ReExpr.Match[0], 5, RegExpr.MatchLen);//copying a matched string <strong>from</strong> fifth character to <strong>the</strong> last oneUsage examplevarRegExp: TRegExpr;s: string;beginInputQuery('Enter floating-point number', 'Number (e.g. 3,5 or 5.66)', s);// creating objectRegExp := TRegExpr.Create;// guarantee to free memorytry// expressionRegExp.Expression := '(\d+)([.,])(\d+)';// do search; s - source stringif RegExp.Exec (s) <strong>the</strong>nrepeatprint('Whole number: '+ RegExp.Match[0]);print('Integer part: '+ RegExp.Match[1]);print('Divider : '+ RegExp.Match[2]);print('Fractional part: '+ RegExp.Match[3]);print(4);print(RegExp.Substitute('$3$2$1'));until not RegExp.ExecNextelseprint('Entered string doesn''t contain number in required format!');// just a test 1RegExp.Expression := '.* am (.*);.*';if RegExp.Exec('blablabla; am Ra1; bm e4') <strong>the</strong>nbeginprint('am:' + RegExp.Match[1]);end;// just a test 2RegExp.Expression := '.* am (.*)';if RegExp.Exec('blablabla; am Ra1') <strong>the</strong>nbeginprint('am:' + RegExp.Match[1]);end;finallyRegExp.Free;end;end.4.3.7.7 Class TBackgroundEvent
http://chessok.com/aqtiki/tiki-print_multi_pages.php138 <strong>of</strong> 144 26.05.2011 19:56↑ Is used in: nothing↓ Uses: nothingThis is a user‐defined eventDeclaration:varev: TBackgroundEventMethodsCreate: ‐ Creating an event;Exampleev := TBackgroundEvent.Create;ResetEvent: boolean ‐ prepares event to waiting.Exampleev.ResetEvent;SetEvent: boolean ‐ finishes event.Exampleev.SetEvent;WaitFor(integer): TEventState ‐ waits given time and <strong>the</strong>n checks if event has happenedExampleev.WaitFor(1000)States <strong>of</strong> <strong>the</strong> events (TEventState)wrSignaled The signal <strong>of</strong> <strong>the</strong> event was set.wrTimeout The specified time elapsed without <strong>the</strong> signal being set.wrAbandoned The event object was destroyed before <strong>the</strong> timeout period elapsed.wrError An error occurred while waiting.Usage example
http://chessok.com/aqtiki/tiki-print_multi_pages.php139 <strong>of</strong> 144 26.05.2011 19:56vart: TIdeaTask;ev: TBackgroundEvent;b: boolean;begint := TIdeaTask.Create;t.FEN := 'r1bqkb1r/ppp2ppp/2n2n2/3Pp1N1/2B5/8/PPPP1PPP/RNBQK2R b KQkq - 0 5';t.UserTask := True;t.Quality.Depth := 10;t.Quality.Time := 10;t.Quality.Op := 1;ev := TBackgroundEvent.Create;t.Event := ev;AddIdeaTask(t);IDEA_Start;repeatb := ev.WaitFor(1000)until not b;end.ev.Free;IDEA_Stop(False, False, False);4.4 Releasing objectsFor nearly any language, releasing objects is very important. It's your guarantee that you don't use more memory than necessary and that your script iAq<strong>Scripter</strong>.I'm making down a list <strong>of</strong> classes and write, which <strong>of</strong> <strong>the</strong>m should be released and when.1. TSNodeInfo should be released in three cases:you have created it and didn't add nei<strong>the</strong>r in tree, nor in database.you have copied it <strong>from</strong> ano<strong>the</strong>r NodeInfo using Copy function and didn' write anywhere.you have added it as an object to StringList and nowhere else. If so, you should write following code:Releasing objects <strong>of</strong> StringListsfor i:=sl.Count-1 downto 0 do//o<strong>the</strong>rwise it won't worksl.Objects[i].Free;sl.Free;2. TSSearchInfo should be released any time you use it (after usage, <strong>of</strong> course)3. TSDataBaseGame should be freed any time you've finished using it, but before TSDataBase.4. Should always be freed after using <strong>the</strong>m:TSDatabase;
http://chessok.com/aqtiki/tiki-print_multi_pages.php140 <strong>of</strong> 144 26.05.2011 19:56TSTreeScanner;TSTreeConfigurationTSTreeJoinerTSEngineTStringListTObjectListTSVariantListTRegExprTXMLTag5. Never freedTSMoveInfoTSAnnotationTSHeaderTXMLParser4.5 Procedures used in <strong>Aquarium</strong> onlyWe have 2 versions <strong>of</strong> Aq<strong>Scripter</strong> ‐ standalone and implemented in <strong>Aquarium</strong>. This second one works with trees and databases, and is very good in IDeneeded to provide links between <strong>Aquarium</strong> and A<strong>Scripter</strong>.Table <strong>of</strong> contentsFunctions that work everywhereFunctions that work only in IDeAFunctions that work only in IDeA Project viewFunctions working with GameViewFunctions working in database4.5.1 Functions that work everywhereThese functions work in any mode where you can use AqScipterUse<strong>Aquarium</strong>Tree(AName string; AReadOnly boolean = True): TSTreeScanner function returns given <strong>Aquarium</strong> tree or nil if not succet := Usq<strong>Aquarium</strong>Tree('statistics\d2m');Release<strong>Aquarium</strong>Tree(AName string) releases this tree.Release<strong>Aquarium</strong>Tree('cap')DataPath: string returns path to <strong>the</strong> <strong>Aquarium</strong> data folder (when used in standalone version, returns path to Aq<strong>Scripter</strong>.exe)
http://chessok.com/aqtiki/tiki-print_multi_pages.php141 <strong>of</strong> 144 26.05.2011 19:56print (Datapath());Usage examplevari: integer;procedure ProcessNode(Sender: TSTreeScanner);begininc(i);end;vartsc: TSTreeScanner;name: string;beginclear;name := 'statistics\d2m';tsc := Use<strong>Aquarium</strong>Tree(name, True);if Assigned(tsc) <strong>the</strong>nbegini := 0;tsc.OnProcessNode := 'ProcessNode';tsc.StartConsecutive;print(intToStr(i));tsc.Free;Release<strong>Aquarium</strong>Tree(name);endelseprint('tree not opened');print('ok');end.<strong>Aquarium</strong>Tree(statistics\d2m);{CODE}4.5.2 Functions that work only in IDeAThese are so beloved functions that can add tasks to IDeA, or Root node, etcAddIdeaTask(ATask:TIdeaTask):boolean: adds IDeA TIDeATask.ExampleAddIdeaTask(MyTask)AddIdeaRootNode(root:TIdeARootNode): adds IDeA task.ExampleAddIdeaRootNode('1Q1q3r/1p1k1pp1/p7/n2p3p/r2P3P/2P5/5PP1/1R2R1K1 w', 'myIdeaRoot');
http://chessok.com/aqtiki/tiki-print_multi_pages.php142 <strong>of</strong> 144 26.05.2011 19:56GetIdeaTree:TSTreeScanner creates a tree <strong>from</strong> an IDeA projectExamplet := GetIDeATree;GetIdeaStage:integer: returns a stage Constants are tesProlong, tesAlternative, tesDeepProlong, tesMainlineVerificationExamplei := GetIDeAStage;AddIdeaTask(ATask:TIdeaTask): adds IDeA task.Exampleni1 := t.Search(ni2)// ni1, ni2 is TSNodeInfoGetIdeaActiveRootNodes:TStringList: returns a list <strong>of</strong> active IDeA root nodes in FEN strings;Examplesl := GetIDeAActiveRootNodes;GetIdeaTotalRootNodes:TStringList: returns a list <strong>of</strong> all IDeA root nodes in FEN strings;Examplesl := GetIDeATotalRootNodes;StopTaskGeneration stops IDeAExampleIdeaForceStop;ContinueTaskGeneration makes IDeA continue analysis.ExampleIdeaForceContinue;UpdateCurrentProj(AProject:#c30:TIdeaProjectInfo~~)~~ updates <strong>the</strong> project so <strong>the</strong> changes start working (allowed one time at <strong>the</strong>ExampleUpdateCurrentProj(IdPr);
http://chessok.com/aqtiki/tiki-print_multi_pages.php143 <strong>of</strong> 144 26.05.2011 19:564.5.2.1 Functions that work only in IDeA Project viewIDEA_Running:Boolean– returns true is a project is runningExampleif IDEA_Running <strong>the</strong>nIDEA_Start– starts IDeAExampleIDEA_Start;IDEA_Stop(WaitTasksToFinish:Boolean, Minimax AfterFinish:Boolean, MakeAccuratePositionCount: Boolean)– Stops IDeA with givExampleIDeAStop(flase, true, false);//stops IDeA and minimaxes after finish4.5.3 Functions working with GameViewThese functions are working only in GameView. Their target is currently opened gameGet<strong>Aquarium</strong>Game: TSGame ‐ returns <strong>the</strong> game opened currently in <strong>Aquarium</strong>Examplegam := Get<strong>Aquarium</strong>Game;RefreshGame(AGame:TSGame) ‐ writes current game into a baseExampleRefreshGame(gam);4.5.4 Functions working in databaseThese functions work in a list <strong>of</strong> games. Yes, you can access <strong>Scripter</strong> <strong>from</strong> <strong>the</strong>re too!Get<strong>Aquarium</strong>Base: TSDataBase ‐ returns database currently opened in <strong>Aquarium</strong>.Don't forget to free <strong>the</strong> game(! not base!) after you've finished working with it, even if it's <strong>Aquarium</strong> baseExample
http://chessok.com/aqtiki/tiki-print_multi_pages.php144 <strong>of</strong> 144 26.05.2011 19:56db := Get<strong>Aquarium</strong>Base;RefreshBase ‐ refreshes current database. used, e.g. when you want to add a new game to a databaseExampleRefreshBase;5 Possible problemsWhen you create large scripts using uses option to attach o<strong>the</strong>r scripts to yours, note, that some problems may occur. It is very hard to debug <strong>the</strong>m, th