Not logged inRybka Chess Community Forum
Up Topic Rybka Support & Discussion / Aquarium / Scripter: Get best move score
- - By Dhanish (***) [in] Date 2011-01-29 07:20
I wrote a script to get the best move and its score from the current project. But I am not getting the correct value for the score. Any suggestions?
var
  t:TSTreeScanner;
  ni:TSnodeinfo;
  Pos:string;
  mi: TSMoveinfo;
begin
  RootList := GetCurrentProject.RootNodes;
  Pos:=RootList.Items[0].FEN;
  ideatree:=GetCurrentProject.AnalysisTreeName;
  fulltree:=DataPath+'ATrees\'+ideatree+'.hsh';
  t:= TSTreeScanner.Create(fulltree);
  if t.Opened then
    begin
      ni:=t.SearchFEN(Pos);
      mi:=ni.Move;
      Print('Best move: ' +mi);
      Print('Bestmove score: '+inttostr(mi.Score));
      Print('Bestmove cpscore: '+inttostr(mi.CPScore));
    end
  mi.Free();
  ni.Free();
  t.Free();
end.
Parent - - By buffos (Silver) [gr] Date 2011-01-29 07:50
if you look here you will see that for each node there is a Moves array. The .Move is for Notation.

You can simply write mi:= ni.Moves[ni.Sorted[0]] // there is an example in the above page too

** You SHOULD NOT write ni.FREE unless ni was created via COPY [ node1.Copy(node2); then node1 SHOULD be freed

i do not remember about TSMoveinfo objects (if you encounter an exception, then comment it out)

Below is the code corrected with changes highlighted
[hl=delphi]
var
  t:TSTreeScanner;
  ni:TSnodeinfo;
  Pos:string;
  mi: TSMoveinfo;
begin
//  RootList := GetCurrentProject.RootNodes; <-- Changed , you did not declare it.
  Pos:= GetCurrentProject.RootNodes.Items[0].FEN; //<-- Changed, just made it one line, so you will not declare RootList above
  ideatree:=GetCurrentProject.AnalysisTreeName;
  fulltree:=DataPath+'ATrees\'+ideatree+'.hsh';
  t:= TSTreeScanner.Create(fulltree);
  if t.Opened then
    begin
      ni:=t.SearchFEN(Pos);
      mi:=ni.Moves[ni.Sorted[0]]; // <---Changed
      Print('Best move: ' +mi.Move); // <---Changed
      Print('Bestmove score: '+inttostr(mi.Score));
      Print('Bestmove cpscore: '+inttostr(mi.CPScore));
    end
  mi.Free();
//  ni.Free(); <---Changed
  t.Free();
end.
Parent - - By Dhanish (***) [in] Date 2011-01-29 10:43 Edited 2011-01-29 10:47
Thank you Buffos, for correcting the script.

But   Pos:= GetCurrentProject.RootNodes.Items[0].FEN; //<-- Changed, just made it one line, so you will not declare RootList above gave an error.
But my earlier two lines worked, without the declaration! How should I declare rootlist?
Attachment: Errormessage.gif (14k)
Parent - By buffos (Silver) [gr] Date 2011-01-29 10:47
TObjectList .

I think Moz pointed that out in another thread (i dont remember the thread though)
Parent - - By buffos (Silver) [gr] Date 2011-01-29 10:49 Edited 2011-01-29 10:57
Look in the example here

look for roots: TObjectList and then

r1: TIDeaRootNode < ----Declare
r1:=  TIdeaRootNode(roots.Items[1]);

then you have r1.FEN and all other properties of TIdeaRootNode

Below is the corrected script ( i hope)
[hl=delphi]
var
  t:TSTreeScanner;
  ni:TSnodeinfo;
  Pos:string;
  mi: TSMoveinfo;
  root: TIDeaRootNode;
  RootList: TObjectList;
begin
  RootList := GetCurrentProject.RootNodes; //<-- Changed
  root:= TIdeaRootNode(RootList.Items[1]); //<-- Changed
  Pos:= root.FEN; //<-- Changed
  ideatree:=GetCurrentProject.AnalysisTreeName;
  fulltree:=DataPath+'ATrees\'+ideatree+'.hsh';
  t:= TSTreeScanner.Create(fulltree);
  if t.Opened then
    begin
      ni:=t.SearchFEN(Pos);
      mi:=ni.Moves[ni.Sorted[0]]; // <---Changed
      Print('Best move: ' +mi.Move); // <---Changed
      Print('Bestmove score: '+inttostr(mi.Score));
      Print('Bestmove cpscore: '+inttostr(mi.CPScore));
    end
  mi.Free();
//  ni.Free(); <---Changed
  t.Free();
end.
Parent - - By Dhanish (***) [in] Date 2011-01-29 14:22
Thank you very much, Buffos.

The script outputs the results correctly. But afterwards, lot of error messages pop up. Any idea why?
Parent - - By buffos (Silver) [gr] Date 2011-01-29 14:23
as i said before, comment out mi.free;
Parent - - By Dhanish (***) [in] Date 2011-01-30 01:56

> as i said before, comment out mi.free;


Thank you for the reply, but I had already deleted mi.Free().

I tried including root.Free(); and RootList.Free();, but still error messages keep coming. Should TSNodeinfo not be freed? I saw this http://aquariumchess.com/tiki/tiki-index.php?page=Releasing+objects&structure=Aquarium+Scripter, but it is not very clear.
Parent - - By buffos (Silver) [gr] Date 2011-01-30 07:48 Edited 2011-01-30 07:53

> Should TSNodeinfo not be freed?


It should NOT be freed, unless it was created by copy (which is not your case)

Ofcourse you should run that one in a IDEA project , not in sandbox . it runs fine here. Just copy pasted the code above and runs fine
Parent - - By Dhanish (***) [in] Date 2011-01-30 14:53

> you should run that one in a IDEA project


I am running in an IdeA project. Now, the first run, it runs OK. But the second run, this message comes up:
Parent - - By buffos (Silver) [gr] Date 2011-01-30 15:06
i really do not know what you are doing and what is your script.
Its works fine here (pasting the script below)

please tell me what are your differences (also place an ; at the end of end statement, although i do not thing it matters)
Maybe some other part of your code produces the problem.

If you paste the code below, it runs fine
[hl=delphi]
var
  t:TSTreeScanner;
  ni:TSnodeinfo;
  Pos:string;
  mi: TSMoveinfo;
  root: TIDeaRootNode;
  RootList: TObjectList;
begin
  RootList := GetCurrentProject.RootNodes; //<-- Changed
  root:= TIdeaRootNode(RootList.Items[1]); //<-- Changed
  Pos:= root.FEN; //<-- Changed
  ideatree:=GetCurrentProject.AnalysisTreeName;
  fulltree:=DataPath+'ATrees\'+ideatree+'.hsh';
  t:= TSTreeScanner.Create(fulltree);
  if t.Opened then
    begin
      ni:=t.SearchFEN(Pos);
      mi:=ni.Moves[ni.Sorted[0]]; // <---Changed
      Print('Best move: ' +mi.Move + ' ' + inttostr(mi.CPScore)); // <---Changed
      Print('Bestmove score: '+inttostr(mi.Score));
      Print('Bestmove cpscore: '+inttostr(mi.CPScore));
    end;
  t.Free();
end.
         
Parent - By Moz (****) Date 2011-01-30 19:26
It runs okay here too.
Parent - - By Dhanish (***) [in] Date 2011-01-31 04:26
I just copied and pasted the above code and the same error results. Maybe some files in my system are corrupt. I'll try a reinstall of Aq. Or is it because as Beta testers you are using the latest versions?
Parent - - By buffos (Silver) [gr] Date 2011-01-31 05:10
any chance you are running IDEA when you run the script?
Parent - - By Dhanish (***) [in] Date 2011-02-10 05:51
I installed Aq on another PC, upgraded to Build 386 and tried the above script. Still the same error message appears.

> any chance you are running IDEA when you run the script?


I have tried with and without, but no difference.

Is there any documentation on the changes in the recent builds? Any changes in script processing?
Parent - - By buffos (Silver) [gr] Date 2011-02-10 05:52
can you please attach in a post your script (the .tsc file)
Parent - - By Dhanish (***) [in] Date 2011-02-10 09:00
Here it is attached.
Attachment: Getbestmovescore.tsc (763B)
Parent - - By buffos (Silver) [gr] Date 2011-02-10 09:23
as i told you before, in the post above, remove mi.Free
Parent - - By Dhanish (***) [in] Date 2011-02-10 10:34
No difference...
Parent - - By buffos (Silver) [gr] Date 2011-02-10 11:11
did you recompile the code?
Parent - - By Dhanish (***) [in] Date 2011-02-11 05:35

> did you recompile the code?


Not clear what you mean. I just click on the run button (Green triangle) on the scripter window.

Could somebody with build 386 please try the above script and report the result?

Does it have anything to do with OS? I have used Win XP, both 32 bit and 64 bit.
Parent - - By buffos (Silver) [gr] Date 2011-02-11 12:20
ctrl+F9 OR right click over the code and select COMPILE
Parent - By Dhanish (***) [in] Date 2011-02-27 02:15
Of course, every time you edit a script, it is recompiled.
Parent - - By buffos (Silver) [gr] Date 2011-03-01 08:11
Just saw the titlebar of yours and have an idea.
You did put your code in Ascripts\Dhanish folder.

Try to move it to Ascripts and run it from their. (maybe i am just plain wrong, but i cannot see anything else different)
Parent - - By Dhanish (***) [in] Date 2011-03-01 10:47

> Try to move it to Ascripts and run it from their


Just tried it, no difference to the error message that appears. Must be something to do with the versions, I am waiting for 4.0.7 before I do further scripting.
Parent - - By Dadi Jonsson (Silver) [is] Date 2011-03-01 17:36

> Must be something to do with the versions


It has nothing to do with that. This is the result of careless programming and waiting for a new version won't fix it. You must anticipate all the conditions that can come up and deal with them in the script. Otherwise you will run into all kinds of "mysterious" errors where the script may work for some projects and not others. This has nothing to do with AqScripter. The same applies to all kinds of programming.

I went through the script and added some error checks. I also changed it so that it shows information about the first active root. I didn't test it much, so there may be some things that need to be fixed, but it shows the type of checks that you should do. They save you time in the long run. The comments I added should be helpful for those who are learning and want to understand the script.
[hl=delphi]
// Find the best move at the first active root position in an IDeA tree
// Run this script in IDeA project view
var
  proj: TIDeAProjectInfo;  // IDeA project information
  t:TSTreeScanner;         // For scanning/searching the IDeA tree
  ni:TSnodeinfo;           // Information about a node in the tree
  Pos:string;              // The FEN of the position we are searching for
  mi: TSMoveinfo;          // Move information
  root: TIDeARootNode;     // An IDeA root node
  RootList: TObjectList;   // A list of all root nodes in the project
  i : integer;
begin
  proj := GetCurrentProject;  // Information about the current project
  if not Assigned(proj) then Exit; // Shouldn't happen, but just in case

  RootList := proj.RootNodes; // All project root nodes (both active and inactive)
  if RootList = nil then   // Empty root node list
  begin
    print('There are no root nodes defined in this project');
    Exit;
  end;
  for i := 0 to RootList.Count - 1 do  // Search the root list for an active root
    if TIDeARootNode(RootList.Items[i]).Enabled then break;  // Active root found
  if i > RootList.Count - 1 then  // No active root
  begin
    Print('There are no active roots in this project');
    Exit;
  end;
  root:= TIDeARootNode(RootList.Items[i]); // The first active root node
  Pos:= root.FEN; // The FEN of the first active root node

  ideatree:=GetCurrentProject.AnalysisTreeName;  // The project tree name
  fulltree:=DataPath+'ATrees\'+ideatree+'.hsh';  // The fully qualified project tree name
  t:= TSTreeScanner.Create(fulltree);  // Used for scanning/searching the tree
  if t.Opened then  // Project tree successfully opened
    begin
      ni:=t.SearchFEN(Pos);  // Search for the root position in the tree
      if ni <> nil then      // Position found in the tree
        begin
          if ni.Count > 0 then  // There are moves available at this node
          begin
            mi:=ni.Moves[ni.Sorted[0]];  // The highest scoring move
            Print('Best move: ' + mi.Move);  // The move itself
            Print('Bestmove score: ' + inttostr(mi.Score));  // The percentage score
            Print('Bestmove cpscore: ' + inttostr(mi.CPScore));  // Centipawn score
          end;
          else
            Print('No moves available for this root node');
        end;
      else
        Print('Root node not found in tree');
    end;
  else
    Print('Couldn''t open project tree');
  t.Free();    
end.
Parent - - By Dhanish (***) [in] Date 2011-03-02 02:12 Edited 2011-03-02 02:38
Thank you, I will study and try it out.

But, if each script has to be so elaborate, then it is not a script but a program and beyond the capabilities of most users!

If these declarations and checks can be eliminated, then only will it be workable for the ordinary user. Can the scripting environment not be made simpler?
Parent - By Moz (****) Date 2011-03-02 03:52

> If these declarations and checks can be eliminated,


What Dadi added makes logical sense if you think about it and follow each statement through. That kind of detail will never be eliminated from programming - good housekeeping is a good habit to get into when you are scripting.
Parent - By buffos (Silver) [gr] Date 2011-03-02 08:35 Edited 2011-03-02 08:41

> If these declarations and checks can be eliminated, then only will it be workable for the ordinary user.


we are talking about programming. You choose how to code.
If you want to check or not special conditions its up to you.

There is no programming for "ordinary user".

Dadi's approach, is an example of perfect programming habbits. Many of those lines can be skipped, but then you do not know what a user will do.

I still cannot understand why the first code does not work for you. If you run it inside a project (idea) with a tree (not nill), which has roots (not nil), and there is an active root...(not nil)... etc then it should work.
But then Dadi's code, check's all those cases...Good habbits (which i do not have)
Parent - By Dhanish (***) [in] Date 2011-03-10 08:56
var
  t:TSTreeScanner;
  ni:TSnodeinfo;
  Pos:string;
  mi: TSMoveinfo;
  root: TIDeaRootNode;
  RootList: TObjectList;
begin
  RootList := GetCurrentProject.RootNodes; //<-- Changed
  root:= TIdeaRootNode(RootList.Items[1]); //<-- Changed
  Pos:= root.FEN; //<-- Changed
  ideatree:=GetCurrentProject.AnalysisTreeName;
  fulltree:=DataPath+'ATrees\'+ideatree+'.hsh';
  t:= TSTreeScanner.Create(fulltree);
  if t.Opened then
    begin
      ni:=t.SearchFEN(Pos);
      mi:=ni.Moves[ni.Sorted[0]]; // <---Changed
      Print('Best move: ' +mi.Move); // <---Changed
      Print('Bestmove score: '+inttostr(mi.Score));
      Print('Bestmove cpscore: '+inttostr(mi.CPScore));
    end
  mi.Free();
//  ni.Free(); <---Changed
  t.Free();
end.

Just realized the problem with the above script: My tree has only one root node, hence root:= TIdeaRootNode(RootList.Items[1]) should be root:= TIdeaRootNode(RootList.Items[0])! After trying Build 409, I got the same error as earlier, and I looked once more!
- - By Dhanish (***) [in] Date 2011-02-27 02:14

>Could somebody with build 386 please try the above script and report the result?


Looks like few people are interested in the Scripter? Another feature in Aquarium to remain unused...
Parent - By tano-urayoan (****) [pr] Date 2011-02-27 05:53

> Looks like few people are interested in the Scripter? Another feature in Aquarium to remain unused...


It could be a powerful feature but if you have zero experience programming it will not be a popular feature, same as ibooks it seems.
- - By Moz (****) Date 2011-02-27 21:06
It doesn't help that many correspondence players are secretive and slightly paranoid by nature. Great scripts probably remain in private hands.
Parent - By buffos (Silver) [gr] Date 2011-02-28 08:54
I agree. Not many people want to share scripts :sad:

I expected more people to share scripts. Hope it is just the beginning...
- - By Dhanish (***) [in] Date 2011-03-19 07:24
I modified the above script to work as End of Stage script to write the best move and score to a log file. While the script works OK in the IdeA window (whether IdeA runs or not) without ContinueTaskGeneration, after enabling it, IdeA is hanging without creating further tasks. I have been trying various things in the last few days, but have not been successful. Any suggestions?
Const
  Logname='AScripts\DATA\log.txt';
var
  f:text;
  t:TSTreeScanner;
  ni:TSnodeinfo;
  Pos:string;
  mi: TSMoveinfo;
  root: TIDeaRootNode;
  RootList: TObjectList;
  i:integer;
begin
  if not FileExists(LogName) then
    begin
      AssignFile(f,LogName); Rewrite(f);
    end;
  else
    begin
      AssignFile(f,LogName); Append(f);
    end;
  RootList := GetCurrentProject.RootNodes;
  root:= TIdeaRootNode(RootList.Items[0]);
  Pos:= root.FEN;
  ideatree:=GetCurrentProject.AnalysisTreeName;
  fulltree:=DataPath+'ATrees\'+ideatree+'.hsh';
  t:= TSTreeScanner.Create(fulltree);
  if t.Opened then
    begin
      ni:=t.SearchFEN(Pos);
      mi:=ni.Moves[ni.Sorted[0]];
      Write(f,'Best move: ' +mi.Move);
      WriteLn(f,':  '+inttostr(mi.CPScore));
    end;
  else
    begin
      WriteLn(f,'Tree could not be opened');
    end;
//  mi.Free();
  t.Free();
  Closefile(f);
//  ContinueTaskGeneration; //Enable to work as EoS script
end.
Parent - - By buffos (Silver) [gr] Date 2011-03-19 10:23
ContinueTaskGeneration statement is meant to be used only in EOS scripts.
Parent - - By Vempele (Silver) [fi] Date 2011-03-19 10:44
Is it possible to find out if the script is being run as an EOS script?
Parent - By buffos (Silver) [gr] Date 2011-03-19 10:45
i don't know (don't think so)
Parent - - By Dhanish (***) [in] Date 2011-03-19 10:50

> ContinueTaskGeneration statement is meant to be used only in EOS scripts.


That is known to me.

But the above script which works alright as an ordinary script without Continue Task Generation, does not work as an EoS with Continue Task Generation enabled!
Parent - By buffos (Silver) [gr] Date 2011-03-19 10:58
I have not played with EOS scripts at all. Try using the StopTaskGeneration  statement somwhere in the code. I am sure you will find a way.
Up Topic Rybka Support & Discussion / Aquarium / Scripter: Get best move score

Powered by mwForum 2.27.4 © 1999-2012 Markus Wichitill