TMCI

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

TMCI

Postby Reinhard Scharnagl » 02 Feb 2008, 21:10

The truth is, that nobody is interested in programmer's results, which have been achieved by their own means. If such results are not top ten, or not usable in a common GUI, e.g. because 10x8 based, most people are too lazy or unmotivated to even notice. Thus it is easier and less frustrating to proceed projects purely private.
Reinhard Scharnagl
 
Posts: 608
Joined: 01 Oct 2004, 08:36
Location: Klein-Gerau, Germany

Re: Why so quiet

Postby H.G.Muller » 03 Feb 2008, 12:02

You paint a much too gloomy picture, Reinhard. It is true some people are only interested in playing engines like Rybka against Fruit. But enough people reamain that have interest in other engines as well.

That those people don't use your creations is more a consequence of that you seem to make it almost impossible for them to do so. I would be very interested to play automated engine-engine games of 10x8 variants with SMIRF, but I could not find any description of how to inteface SMIRF to other engines, and a clear definition of the protocol to use...
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Why so quiet

Postby YvesLejeail » 03 Feb 2008, 15:43

Some others forums have much more traffic, but the posts are kept only a few monthes. On Winboard your posts will be there forever :D
There is no interest if your post disappear rapidly from the net. Think about all the valuable informations you can find on the old ccc http://www.stmintz.com/ccc/
The winboard forum is already a great place to search good informations. So post there guys, come on ! :wink:
Yves
User avatar
YvesLejeail
 
Posts: 48
Joined: 03 Aug 2005, 17:36
Location: Pertuis, France

Re: Why so quiet

Postby Onno Garms » 03 Feb 2008, 15:58

I don't understand what you mean. All forums I read (talkchess.com, vplittlik, and CSS on parsimony) keep posts forever. Where do posts disappear?

talkchess has technical problems again and again (I couldn't post there for months), so I prefer to post here and read talkchess only. But on talkchess the traffic also declined.
User avatar
Onno Garms
 
Posts: 128
Joined: 17 Feb 2007, 11:17
Location: Bonn, Germany

Re: Why so quiet

Postby YvesLejeail » 03 Feb 2008, 16:12

At least it was the case some monthes ago ! Maybe it has been fixed now.
In the Talkchess programming corner the oldest post has only 10 monthes :shock:.
Of course I follow Talkchess though I agree the traffic has decreased.
Yves
User avatar
YvesLejeail
 
Posts: 48
Joined: 03 Aug 2005, 17:36
Location: Pertuis, France

Re: Why so quiet

Postby Reinhard Scharnagl » 03 Feb 2008, 17:09

H.G.Muller wrote:You paint a much too gloomy picture, Reinhard. It is true some people are only interested in playing engines like Rybka against Fruit. But enough people reamain that have interest in other engines as well.

That those people don't use your creations is more a consequence of that you seem to make it almost impossible for them to do so. I would be very interested to play automated engine-engine games of 10x8 variants with SMIRF, but I could not find any description of how to inteface SMIRF to other engines, and a clear definition of the protocol to use...

Well, I have made several approaches to discuss and define compatible extensions for UCI or Winboard protocols. It has not been possible. I suggested FRC-FEN, which has been ignored, later I designed X-FEN as a compromise covering all critic I could gather. Nevertheless incompatible Shredder-FEN and a matching UCI-extension were released and declared as "standard". Most engine programmers were happy to have a commercial Chess960 covering GUI, and do no longer care about compatibility.

Now it seems that the same thing is happening with 10x8 chess variant covering GUIs and protocols. There seem to be no interest in prior agreements on common and compatible protocols.

Before I wrote SMIRF, I dedicatedly tried to avoid any one-man modification of a protocol (I would have thought on UCI-2). Thus I have invented and published the TMCI (Third Millennium Chess Interface), which still is used for the communication between SMIRF and its GUI. Since nobody intended seriously to also use TMCI, there has been no need to rebuild the SMIRF GUI to become a multi-engine interface - and of course that has never been an intended goal. I always have suggested to compatibly extend existing GUIs and protocols.

Because today testing most is done by using GUIs supporting automated test-events, which rarely have other time frames than Blitz games, it is unintersting for me to release e.g. a UCI version of SMIRF. This is, because SMIRF is intended to be a positionally working engine, which is not doing well at small thinking time periods, and because it is a combined unique 8x8 and 10x8 engine, what will be ignored in tests against traditional 8x8 engines.
Reinhard Scharnagl
 
Posts: 608
Joined: 01 Oct 2004, 08:36
Location: Klein-Gerau, Germany

Re: Why so quiet

Postby Onno Garms » 03 Feb 2008, 17:17

Maybe you are right. I thought that the forum was not older than the oldest post. Note that several posts at talkchess got lost due to technical problems
User avatar
Onno Garms
 
Posts: 128
Joined: 17 Feb 2007, 11:17
Location: Bonn, Germany

Re: Why so quiet

Postby H.G.Muller » 03 Feb 2008, 19:36

Reinhard Scharnagl wrote:Before I wrote SMIRF, I dedicatedly tried to avoid any one-man modification of a protocol (I would have thought on UCI-2). Thus I have invented and published the TMCI (Third Millennium Chess Interface), which still is used for the communication between SMIRF and its GUI.

So where can I find the description of this TMCI, and what command do I have to give to run SMIRF without its GUI? The folder I downloaded from the link you gave me only contains two executables, the SmirfGUI, and what seems to be an uninstall.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Why so quiet

Postby Reinhard Scharnagl » 03 Feb 2008, 20:43

The TMCI is a specifiction for a DLL, which should be called by a GUI. Thus a conforming DLL is not able to act alone, it needs a caller. TMCI seperates the intelligence from the GUI, which itself is not even able to generate any move. Because the TMCI approach has been not spreaded, it has no future.

Anyway: here is the outdated TMCI proposal:

Code: Select all
//================================================
// PROJECT: SmirfEngine.dll (C) R. Scharnagl
//================================================

#ifndef SmirfEngineH
#define SmirfEngineH


// --- to be defined when included in its *.cpp ---
#ifdef  SmirfDLL
#define IMP_EXP dllexport
#else
#define IMP_EXP dllimport
#endif


#include "../Schach/Mov.h"
#include "../Schach/Hsh.h"

#ifdef __BCPLUSPLUS__
#define ENGINE_NAME "Smirf"
#else
#define ENGINE_NAME "SMIRF"
#endif

// the TMCI engine interface function: DoCmd()

extern "C" __declspec(IMP_EXP) const char * __cdecl DoCmd(
  char MainCmd, char SubCmd, int nrIn = 0, const char *pIn = 0L);

/*
  TMCI protocol (Third Millennium Chess Interface) [ incomplete draft ]

  The protocol is intended to keep the GUI realy silly. The GUI
  gets all its knowlegde on chess moves from the engines. This
  makes those GUIs much easier to be extended to new variants,
  and also allows an easier writing of such GUIs. 
 

  COMMANDS (please discuss planned extensions with R. Scharnagl)

  How to perform any command:

  (DoCmd args)      (DoCmd answer)

   '*' '*' ** ** => char string "<answer>" rsp. "ok" at success
                    (and stop any engine run task, if necessary)
                 => otherwise 0L, if impossible or after errors
                    (query last error reason by: DoCmd('I','R'))

  (ALREADY DONE)

  Query:
   '?' '*' -- -- => list of all sub commands to any main command '*'
   '?' '?' -- -- => list of all main commands

  Info:
   'I' 'A' -- -- => name of the author
   'I' 'E' -- -- => name of the engine
   'I' 'V' -- -- => version of the engine
   'I' 'R' -- -- => reason (of the last error situation)

  FEN-Position:
   'F' 'S' -- -- => produce the FEN char string matching the
                    current situation
   'F' '4' nr -- => produce the FEN char string to a numbered
                    Chess480 starting position (<nr> 1...960)
                    (or else 0L, when not FRC 8x8 aware)
   'F' '8' nr -- => produce the FEN char string to a numbered
                    chess960 8x8 starting position (<nr> 1...960)
                    (or else 0L, when not FRC 8x8 aware)
            0 -- => produce the FEN char string to
                    the classical 8x8 chess starting array
                    (or else 0L, when not standard 8x8 aware)
   'F' 'C' nr vv => produce the FEN char string to a numbered (not
                    selected) CRC 10x8 starting position (<nr> 1...48000)
                    (or else 0L, when not CRC 10x8 aware if vv != 0L)
            0 -- => produce the FEN char string to
                    the Capablanca 10x8 chess starting array
                    (or else 0L, when not Capablanca 10x8 aware)
           -1 -- => produce the FEN char string to
                    the MBC Chess 10x8 chess starting array
                    (or else 0L, when not MBC Chess 10x8 aware)
           -2 -- => produce the FEN char string to
                    the Janus Chess 10x8 chess starting array
                    (or else 0L, when not Janus Chess 10x8 aware)
           -3 -- => produce the FEN char string to
                    the Bird 10x8 chess starting array
                    (or else 0L, when not Bird 10x8 aware)
           -4 -- => produce the FEN char string (Pos. 25495) to
                    the Carrera 10x8 chess starting array
                    (or else 0L, when not Carrera 10x8 aware)
           -5 -- => produce the FEN char string (Pos. 25933) to
                    the GothicChess 10x8 chess starting array
                    (or else 0L, when not GothicChess 10x8 aware)
           -6 -- => produce the FEN char string (Pos. 27016) to
                    the Optimized Chess 10x8 chess starting array
                    (or else 0L, when not Optimized Chess 10x8 aware)
  Move:
   'M' 'A' nr -- => show the currently prepared move <nr> in
                    algebraic form (letter, digit, letter, digit, extra),
                    source before target, where extra is the lower promotion
                    piece code (English) or zero. When a King's castling
                    move does less than two elementary steps, the involved
                    Rook's coordinate will be used as target coordinate.
                    (or else 0L, if move <nr> does not exist)
                    This codes are sent back to the engine in case that
                    a move would be selected.
   'M' 'T' nr -- => show the currently prepared move <nr> as long text
                    (e.g. "e4xf5+", "O-O-O" or "Bc1-f4" using English)
                    (or else 0L, when move <nr> does not exist)
   'M' 'S' nr -- => show the currently prepared move <nr> as short text
                    (e.g. "ef5+", "O-O-O" or "Bf4" using English)
                    (or else 0L, when move <nr> does not exist)
   'M' 'V' nr -- => show the evaluation to currently prepared move <nr>
                    (or else 0L, when move <nr> does not exist)
   'M' 'L' nr -- => show the search level of currently prepared move <nr>
                    (or else 0L, when move <nr> does not exist)

  Enter:
   'E' 'F' -- fs => enter a FEN char string <fs> as position
                    (and prepare a list of actual moves)
   'E' 'M' -- mv => enter a move <mv>
                    (as been encoded before by DoCmd('M', 'A', nr))
                    (and prepare FEN and a list of actual moves)
   'E' '-' -- -- => take back last move
                    (and prepare FEN and a list of actual moves)

  Licensing: (to be set (once) before calculating or pondering)
   'L' 'N' -- nm => input the user name <nm>
                    (will answer a string truncated to < 255 chars)
   'L' 'K' -- ky => input the engine-key <ky>
                    (will answer "ok" when key matches or engine is not
                     protected at all, or 0L if necessary key was wrong)
                    (the procedure should not work after some bad trials)

  Timing: (to be set befor pondering or computing)
   'T' 'W' tm -- => Time Left White, in MSec, totale Restzeit
   'T' 'B' tm -- => Time Left Black, in MSec, totale Restzeit
   'T' '#' =1 -- => Time is for one move (=1) only or all (=0) moves

  Computing:
   'C' 'P' -- -- => let the engine start its Ponder-thinking
   'C' '+' -- -- => let the engine start its thinking
   'C' '-' -- -- => let the engine terminate its thinking
   'C' 'B' -- -- => busy? answer with "ok" or 0L
   'C' 'I' 00 -- => Info: answer with (last) actual move
   'C' 'I' 01 -- => Info: answer with (last) actual value
   'C' 'I' 02 -- => Info: answer with (last) actual PV
   'C' 'A' -- -- => request answer-move in algebraic notation
   'C' 'H' -1 -- => query hash size as a char string
   'C' 'H' mb -- => set new hash size in MB and query result

  (TODO)

   'T' 'F' tm -- => Fischerzeit pro Zug (falls geändert)

  Computing:

*/
//-------------------------------------------------------

Reinhard Scharnagl
 
Posts: 608
Joined: 01 Oct 2004, 08:36
Location: Klein-Gerau, Germany

Re: Why so quiet

Postby H.G.Muller » 03 Feb 2008, 22:09

OK, let me make sure I get this correctly:

The engine is in a DLL, and that DLL contains only one entry point which I can call, DoCmd. The arguments tell the engine what to do, and it will return a character string.

So basically, to play a game against the Smirf DLL, I have to send it the initial position through

DoCmd('E', 'F', 0, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");

Then for every move of the opponent (or external opening book) I have to enter it with (say):

DoCmd('E', 'M', 0, "e2e40");

And if I want the engine to produce a move I have to first tell it the time through:

DoCmd('T', 'W', 300000, NULL);
DoCmd('T', 'B', 300000, NULL);

Then set it thinking by

DoCmd('C', '+', 0, NULL);
move = DoCmd('C', 'A', 0, NULL);

and then the second call only returns after the engine has completed the search (using as much time as it thought wise), and move then contains the move string of the move the engine wants me to play.

Is that it? Would this work with the current Smirf DLL I have?

Only one thing I don't get yet: How does the engine know for how many moves the time was? Do I also have to call:

DoCmd('T', '#', 40, NULL);

at the beginning of the game if I want it to play 40 moves / 5 minutes? Or can I use that call only with 1 or 0 for "one move" or "rest of game"? Or is it mandatory I send this command before every move the engine should make? If it is for a finite number of moves, should the engine assume that it will get the same time per move after the number of moves specified initially has been played? Or can it be surprised after just finishing 40 moves in 2 hours by a command "... and now play the remainder of the game in 1 sec"?

Please correct me if I am wrong.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Why so quiet

Postby Reinhard Scharnagl » 03 Feb 2008, 23:10

Hmm, Harm, I am astonished about your interest, and I see you already have understood a lot, but some parts seem to be unclear. Nobody has ever asked such details before. Maybe I should produce a communication traffic protocol as an example, to illustrate its flow. But I rather would suggest not to invest too much thoughts into the understanding of that protocol.

Indeed it as a DLL with one single entry point, this is, because it should be easily to be modified or extended without having to redesign the DLL communication concept simply by introducing new command families or members.

Originally there has been the idea to provide events as an ActiveX DLL, but that seems not that universal for the beginning. In the current basic concept the DLL is repeatedly called during calculation to gather PV and evaluation informations and to notify the end of the move decision. There is a sligthly different way, if the engine is also used for permanent brain during pondering times. All that is done via this TMCI protocol.

The engine also will wait once for a user name and a valid key. This key set could be found in an initially created *.ini file by the GUI. The more current and superfast bonus-engine will need a personalized key set, the free basic donationware engine is happy with the generated keys from the GUI.

I said, this was my first concept, and it is outdated now. I intend now to detatch from that concept, which has been used for not to interfere with existing approaches. This time I would like to follow a different concept, which does not hesitate to attatch to the prior UCI-2 protocol and to extend that. But I plan to seperate all chess knowledge and PGN maintenance into a different referee modul to keep the GUI silly. That would allow me to write a GUI e.g. using QT maybe as an open source project, but to keep the referee and engine private in rather OS independent C++ code, each using the traditional STDIN STDOUT pipe.

The problem is, that I am very unmotivated this time. And it seems much too much to do for a single person, without a friendly resonance. Therefore that all is delayed and not yet begun. Instead I am currently following an approach to solve big TSPs pure combinatorically.
Reinhard Scharnagl
 
Posts: 608
Joined: 01 Oct 2004, 08:36
Location: Klein-Gerau, Germany

Re: Why so quiet

Postby H.G.Muller » 04 Feb 2008, 09:56

Well, I seem to get stuck, because the SmirfEngine.dll does not seem to contain the entry point 'DoCmd'. As I have no experience whatsoever in using DLLs, I just took the example provided by the MicroSoft developer network, using "SmirfEngine.dll" as the name of the DLL, and "DoCmd" for the name of the procedure. (Plus I had to change the declaration of MYPROC used in the example to allow for the extra and other arguments DoCmd is supposed to have.)

I can attach to the DLL, but when I try to get the address of DoCmd, it gives me error code 127, which, according to the manual, is ERROR_PROC_NOT_FOUND.

What am I doing wrong?

Code: Select all
// A simple program that uses LoadLibrary and
// GetProcAddress to access myPuts from Myputs.dll.
 
#include <windows.h>
#include <stdio.h>
 
typedef const char * (__cdecl *MYPROC)(char, char, int, LPWSTR);
 
int main(VOID)
{
    HINSTANCE hinstLib;
    MYPROC ProcAdd;
    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
    char buf[80]; const char *p;
 
    // Get a handle to the DLL module.
 
    hinstLib = LoadLibrary(TEXT("SmirfEngine.dll"));
    if(hinstLib == NULL) { printf("Smirf DLL not found\n"); exit(0); }
 
    // If the handle is valid, try to get the function address.
 
    if (hinstLib != NULL)
    {
        ProcAdd = (MYPROC) GetProcAddress(hinstLib, TEXT("DoCmd"));
 
        // If the function address is valid, call the function.
 
       if (NULL != ProcAdd)
        {
            fRunTimeLinkSuccess = TRUE;
            p = (ProcAdd) ('L', 'N', 0, L"H.G.Muller");
            printf("Smirf returned '%s'\n", p);
            (ProcAdd) ('L', 'K', 0, L"342f6f5e 026b3179");
            printf("Smirf returned '%s'\n", p);
        } else { printf("Bad entry point %d\n", GetLastError()); exit(0); }
 
        // Free the DLL module.
 
        fFreeResult = FreeLibrary(hinstLib);
    }
 
    // If unable to call the DLL function, use an alternative.
 
    if (! fRunTimeLinkSuccess)
        printf("Message printed from executable\n");
}

User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Why so quiet

Postby Reinhard Scharnagl » 04 Feb 2008, 10:08

Harm, I will supply an accessing example soon. But that would need some hours, because I am busy also at other places ... until then.
Reinhard Scharnagl
 
Posts: 608
Joined: 01 Oct 2004, 08:36
Location: Klein-Gerau, Germany

Re: Why so quiet

Postby Reinhard Scharnagl » 04 Feb 2008, 11:38

Code: Select all
//---------------------------------------------------------------------------

// --- System-Includes ---
#include <windows.h>
#include <iostream>

#pragma hdrstop
//---------------------------------------------------------------------------

// own datatype
typedef const char * __cdecl FEngine(
  char MainCmd, char SubCmd, int nrIn = 0, const char *pIn = 0L);

// the engine link
HMODULE HdEngine;
FEngine *Engine;

using namespace std;
#pragma argsused
int main(int argc, char* argv[])
{
    // load engine
    bool loadOk = false;
    if ((HdEngine = LoadLibrary("SmirfEngine.dll")) != 0) {
        // load engine flexibly on compiled version
        // using two different entry name patterns
        char *name[] = {
             "_DoCmd", "DoCmd"
        };
        int i;
        for (i = sizeof(name)/sizeof(*name); --i >= 0; ) {
            if ( ((FARPROC)Engine
                = GetProcAddress(HdEngine, name[i])) != 0
               ) {
                loadOk = true;
                break;
            }
        }
    }

    if (!loadOk) {
      // SmirfEngine.dll not in local folder
      cout << "DLL does not match" << endl;
    } else {
      // get name of engine example
      cout << (*Engine)('I', 'E') << endl;
      // get name of author example
      cout << (*Engine)('I', 'A') << endl;
    }

    system("pause");

    return 0;
}
//---------------------------------------------------------------------------
Reinhard Scharnagl
 
Posts: 608
Joined: 01 Oct 2004, 08:36
Location: Klein-Gerau, Germany

Re: Why so quiet

Postby H.G.Muller » 04 Feb 2008, 13:02

OK, of course. How stupid of me. Many C compilers prepend the user-defined variable names with an underscore. Now it works, and I can communicate with Smirf: set up an initial position, print the board, enter a move (which gets played) and set it thinking.

I don't seem to fetch the move in the correct way, though: it gives me "#0#0" for the reply move. So what is the proper protocol for after sending the "C+" command to have Smirf finish its search, and get to know its move?
Code: Select all
// A simple program that uses LoadLibrary and
// GetProcAddress to access myPuts from Myputs.dll.
 
#include <windows.h>
#include <stdio.h>
 
typedef const char * (__cdecl *MYPROC)(char, char, int, char *);
 
int main(VOID)
{
    HINSTANCE hinstLib;
    MYPROC ProcAdd;
    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
    char buf[80]; const char *p;
 
    // Get a handle to the DLL module.
 
    hinstLib = LoadLibrary(TEXT("SmirfEngine.dll"));
    if(hinstLib == NULL) { printf("Smirf DLL not found\n"); exit(0); }
 
    // If the handle is valid, try to get the function address.
 
    if (hinstLib != NULL)
    {
        ProcAdd = (MYPROC) GetProcAddress(hinstLib, TEXT("_DoCmd"));
 
        // If the function address is valid, call the function.
 
       if (NULL != ProcAdd)
        {
            fRunTimeLinkSuccess = TRUE;
            p = (ProcAdd) ('L', 'N', 0, "H.G.Muller");
            printf("Send name:   Smirf returned '%s'\n", p);
            p = (ProcAdd) ('L', 'K', 0, "342f6f5e 026b3179");
            printf("Send key:    Smirf returned '%s'\n", p);
            p = (ProcAdd) ('F', 'S', 0, NULL);
            printf("Print board: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('F', 'C', -5, NULL);
            printf("Ask FEN:     Smirf returned '%s'\n", p);
            p = (ProcAdd) ('E', 'F', 0, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
            printf("Enter FEN:   Smirf returned '%s'\n", p);
            p = (ProcAdd) ('F', 'S', 0, NULL);
            printf("Print board: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('E', 'M', 0, "e2e4");
            printf("Enter move:  Smirf returned '%s'\n", p);
            p = (ProcAdd) ('F', 'S', 0, NULL);
            printf("Print board: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('T', 'W', 300000, NULL);
            printf("Enter wTime: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('T', 'B', 300000, NULL);
            printf("Enter bTime: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('T', '#', 40, NULL);
            printf("Enter nrMov: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('C', '+', 0, NULL);
            printf("Search:      Smirf returned '%s'\n", p);
            p = (ProcAdd) ('C', 'A', 0, NULL);
            printf("Get move:    Smirf returned '%s'\n", p);
        } else { printf("Bad entry point %d\n", GetLastError()); exit(0); }
 
        // Free the DLL module.
 
        fFreeResult = FreeLibrary(hinstLib);
    }
 
    // If unable to call the DLL function, use an alternative.
 
    if (! fRunTimeLinkSuccess)
        printf("Message printed from executable\n");
}


Output is:
Code: Select all
Send name:   Smirf returned 'H.G.Muller'
Send key:    Smirf returned '(null)'
Print board: Smirf returned ''
Ask FEN:     Smirf returned 'rnbqckabnr/pppppppppp/10/10/10/10/PPPPPPPPPP/RNBQCKABNR w KQkq - 0 1'
Enter FEN:   Smirf returned 'ok'
Print board: Smirf returned 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
Enter move:  Smirf returned 'ok'
Print board: Smirf returned 'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1'
Enter wTime: Smirf returned 'ok'
Enter bTime: Smirf returned 'ok'
Enter nrMov: Smirf returned 'ok'
Search:      Smirf returned 'ok'
Get move:    Smirf returned '#0#0'
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Why so quiet

Postby Reinhard Scharnagl » 04 Feb 2008, 14:21

Well, you have do establish a loop, wherin you are polling until
'C' 'B' 0 gives NULL. Inside the loop you could sleep e.g. for about
1/10 sec and call for the current PV by 'C' 'I' 2, its value by 'C' 'I' 1.
'C' 'A' 0 will present the answer move then.
Reinhard Scharnagl
 
Posts: 608
Joined: 01 Oct 2004, 08:36
Location: Klein-Gerau, Germany

Re: Why so quiet

Postby H.G.Muller » 04 Feb 2008, 15:43

OK, I put the following, now, and it seems to work:
Code: Select all
            p = (ProcAdd) ('L', 'N', 0, "H.G.Muller");
            printf("Send name:   Smirf returned '%s'\n", p);
            p = (ProcAdd) ('L', 'K', 0, "");
            printf("Send key:    Smirf returned '%s'\n", p);
            p = (ProcAdd) ('F', 'S', 0, NULL);
            printf("Print board: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('F', 'C', -5, NULL);
            printf("Ask FEN:     Smirf returned '%s'\n", p);
            p = (ProcAdd) ('E', 'F', 0,

"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
            printf("Enter FEN:   Smirf returned '%s'\n", p);
            p = (ProcAdd) ('F', 'S', 0, NULL);
            printf("Print board: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('E', 'M', 0, "e2e4");
            printf("Enter move:  Smirf returned '%s'\n", p);
            p = (ProcAdd) ('F', 'S', 0, NULL);
            printf("Print board: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('T', 'W', 300000, NULL);
            printf("Enter wTime: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('T', 'B', 300000, NULL);
            printf("Enter bTime: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('T', '#', 40, NULL);
            printf("Enter nrMov: Smirf returned '%s'\n", p);
            p = (ProcAdd) ('C', '+', 0, NULL);
            printf("Search:      Smirf returned '%s'\n", p);
            do {
                p = (ProcAdd) ('C', 'B', 0, NULL);
                cnt++;
            } while(p != NULL);
            printf("%4d polls:  Smirf returned '%s'\n", cnt, p);
            p = (ProcAdd) ('C', 'I', 2, NULL);
            printf("Get PV:      Smirf returned '%s'\n", p);
            p = (ProcAdd) ('C', 'I', 1, NULL);
            printf("Get score:   Smirf returned '%s'\n", p);
            p = (ProcAdd) ('C', 'A', 0, NULL);
            printf("Get move:    Smirf returned '%s'\n", p);



This produces output:

Code: Select all
Send name:   Smirf returned 'H.G.Muller'
Send key:    Smirf returned '(null)'
Print board: Smirf returned ''
Ask FEN:     Smirf returned 'rnbqckabnr/pppppppppp/10/10/10/10/PPPPPPPPPP/RNBQCKABNR w KQkq - 0 1'
Enter FEN:   Smirf returned 'ok'
Print board: Smirf returned 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
Enter move:  Smirf returned 'ok'
Print board: Smirf returned 'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1'
Enter wTime: Smirf returned 'ok'
Enter bTime: Smirf returned 'ok'
Enter nrMov: Smirf returned 'ok'
Search:      Smirf returned 'ok'
29926817 polls:  Smirf returned '(null)'
Get PV:      Smirf returned '00:00.6 End of thinking (time eco lo)'
Get score:   Smirf returned '(07.02=) -0.141'
Get move:    Smirf returned 'b8c6'


The polling is still a source of inefficiency, as I still have to figure out how to do a sleep.

One question that still stands is: how should I use the time commands?
Is it OK if I send the number of moves per session to the engine at the beginning of the game, and then the white and black times left on the clock for this session before every move the engine should make? Will it automatically realize that after it made the first time control, the new times apply to the next session, with as many moves as the first? Or should I re-send the number of moves?

Another irregularity is that it seems to refuse the engine key no matter what I send it (it returns NULL in stead of "ok"). But it seems to work nonetheless...

[edit] OK, Sleep had to be spelled with a capital... :? So that is solved too. Tonight I will play Smirf against Joker80, for Gothic.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Why so quiet

Postby Reinhard Scharnagl » 04 Feb 2008, 16:10

The Smirf engine currently supports only 'T' '#' 0 and 'T' '#' 1, there is no precise time control for special move time controls depending on any awaited move number. It will then try to calculate an optimal timing depending on the current move number and the remaining time. The engine needs always the actually remaining time left. An engine Name/Key pair will individually be supplied by me personally. It then will work for the bonus engine version only. Nevertheless the engine will not block to work, instead it merely will refute e.g. big cache sizes or long thinking time periods. It is not recommended to publish ones personal key set.

P.S.: I think you will have a key set. If not write me an email. Do not mix up the key set for the GUI and the engine, both are different.
Reinhard Scharnagl
 
Posts: 608
Joined: 01 Oct 2004, 08:36
Location: Klein-Gerau, Germany

Re: Why so quiet

Postby H.G.Muller » 04 Feb 2008, 16:39

OK, so I can play sudden-death and incremental time control by giving DoCmd( 'T','#',0,NULL) at the beginning of the game, and then the remaining time on the clocks just before every move.

I will stay away from classical time controls then, for now. I could of course try to simulate classical time controls by just dividing the true time left on the clock by the number of moves that remain, and send that time to Smirf as time for a single move. Does Smirf always use the full time in that case, or does it on average think shorter? In the latter case it would be better to send it 1.2 or 1.5 times timeLeft/(movesLeft+4), or something like that.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Why so quiet

Postby Reinhard Scharnagl » 04 Feb 2008, 16:51

SMIRF will never exceed the remaining time, but maybe it will match it if the time is for a single move only. SMIRF will take more or less than the estimated average move time left, depending on how clear the decision could be made by Smirf. There is a current SMIRF Engine version MS-171a ready for download to key set owners at: http://www.10x8.net/down/SmirfEngine.dll.
Reinhard Scharnagl
 
Posts: 608
Joined: 01 Oct 2004, 08:36
Location: Klein-Gerau, Germany

Next

Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 34 guests