Symbolic vs tscp: more match results

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: Symbolic vs FairyMax

Post by sje »

The first 100 game, 5 minute time control match has completed. Symbolic's score vs FairyMax was 53-27-20 (+92 elo).

The games: https://dl.dropboxusercontent.com/u/316 ... 9-1.pgn.gz
User avatar
hgm
Posts: 27837
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Symbolic vs FairyMax

Post by hgm »

Well, Symbolic also clearly passed Fairy-Max in strength, although not yet by so much that testing against the latter has become meaningless. In any case it is confirmed that Fairy-Max is some 200 Elo stronger than TSCP. (Which is not bad for an AI of only some 150 lines of code.)

Should you tire of Fairy-Max, you could switch to the still stronger KingSlayer/Simple. The latest commit in my on-line repository has now also been tested under Linux. (Of course I fell for the SIGINT trick for the umptieth time, so previous versions were killed by XBoard...) It now also has a Makefile, complete with install target that should also work on OS X (no "cp -u", and install in /usr/local/bin). It even includes a logo!

Image
User avatar
hgm
Posts: 27837
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Symbolic vs FairyMax

Post by hgm »

100 games between King Slayer and Fairy-Max at 40/1min on Linux ended in an 82.5% victory for King Slayer (75+ 15= 10-). And that is almost all due to the better move ordering of King Slayer, as most of its evaluation terms were not even switched on. So it bungled some games because it did not know that KNK is a draw.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: Symbolic vs FairyMax

Post by sje »

After making a few changes to Symbolic, I ran another 100 game match against FairyMax using a 5 minute time control. The result this time was 67-16-17 (+196 elo).

The games: https://dl.dropboxusercontent.com/u/316 ... 930.pgn.gz
PK
Posts: 895
Joined: Mon Jan 15, 2007 11:23 am
Location: Warsza

Re: Symbolic vs FairyMax

Post by PK »

If I'm not mistaken, this puts Symbolic at about 2200 Elo (CCRL scale). Sungorus is 2300, so you may as well make it the next target. And in about two weeks, I am planning to release "Mini-Rodent". There is still much code refactoring and commenting to do, but the thing is beating Sungorus by 80%, so may well serve as the next hurdle to overcome.
User avatar
hgm
Posts: 27837
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Symbolic vs FairyMax

Post by hgm »

At 5min sudden-death the difference grows even larger. King Slayer is leading by 87.5% (22+ 5= 1-) there.
mvk
Posts: 589
Joined: Tue Jun 04, 2013 10:15 pm

Re: Symbolic vs tscp: more match results

Post by mvk »

hgm wrote:From http://hgm.nubati.net/cgi-bin/gitweb.cgi you can always download the latest 'snapshot' of all my open-source projects as a tar ball. The Fairy-Max sources include a Makefile, and you can build it with "make install". A slightly stronger engine is in the simple.git section there; this project is so fresh that I have not included a Makefile yet. But you can compile with

gcc -O2 simple.c -o simple
I downloaded from this URL:
http://hgm.nubati.net/cgi-bin/gitweb.cg ... 155;sf=tgz

This is what I get:

Code: Select all

make 
cc -O2 -s   simple.c -o kingslayer
simple.c:325:10: warning: equality comparison result unused
      [-Wunused-comparison]
  if(stm == side, 1) return 0;                    // on our move we migh...
     ~~~~^~~~~~~
simple.c:325:10: note: use '=' to turn this equality comparison into an
      assignment
  if(stm == side, 1) return 0;                    // on our move we migh...
         ^~
         =
simple.c:335:27: warning: if statement has empty body [-Wempty-body]
    if(pawn == (promo^16));
                          ^
simple.c:335:27: note: put the semicolon on a separate line to silence this
      warning
simple.c:365:72: warning: if statement has empty body [-Wempty-body]
  ...& 7&#41; == 0 && dist&#91;hisKing - &#40;king^2&#41;&#93; < 2 - myTurn&#41;;  // own King is tra...
                                                        ^
simple.c&#58;365&#58;72&#58; note&#58; put the semicolon on a separate line to silence this
      warning
simple.c&#58;379&#58;63&#58; warning&#58; '&&' within '||' &#91;-Wlogical-op-parentheses&#93;
  ...== king + 2*forward&#41; return (!lastRank || next && myTurn&#41;; // oppose K n...
                                            ~~ ~~~~~^~~~~~~~~
simple.c&#58;379&#58;63&#58; note&#58; place parentheses around the '&&' expression to silence
      this warning
  ...== king + 2*forward&#41; return (!lastRank || next && myTurn&#41;; // oppose K n...
                                                    ^
                                               (             )
simple.c&#58;383&#58;23&#58; warning&#58; & has lower precedence than ==; == will be evaluated
      first &#91;-Wparentheses&#93;
    return (!lastRank & dist&#91;king + 2*forward - hisKing&#93; + myTurn == 1&#41;...
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
simple.c&#58;383&#58;23&#58; note&#58; place parentheses around the '==' expression to silence
      this warning
    return (!lastRank & dist&#91;king + 2*forward - hisKing&#93; + myTurn == 1&#41;...
                      ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
simple.c&#58;383&#58;23&#58; note&#58; place parentheses around the & expression to evaluate it
      first
    return (!lastRank & dist&#91;king + 2*forward - hisKing&#93; + myTurn == 1&#41;...
                      ^
            (                                                    )
simple.c&#58;442&#58;1&#58; warning&#58; control may reach end of non-void function
      &#91;-Wreturn-type&#93;
&#125;
^
simple.c&#58;572&#58;17&#58; warning&#58; '&&' within '||' &#91;-Wlogical-op-parentheses&#93;
      if&#40;f != 0 && board&#91;sq-17&#93; == WHITE+PAWN ||                            /...
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~
simple.c&#58;572&#58;17&#58; note&#58; place parentheses around the '&&' expression to silence
      this warning
      if&#40;f != 0 && board&#91;sq-17&#93; == WHITE+PAWN |...
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
simple.c&#58;573&#58;17&#58; warning&#58; '&&' within '||' &#91;-Wlogical-op-parentheses&#93;
         f != 7 && board&#91;sq-15&#93; == WHITE+PAWN   ) ...
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
simple.c&#58;573&#58;17&#58; note&#58; place parentheses around the '&&' expression to silence
      this warning
         f != 7 && board&#91;sq-15&#93; == WHITE+PAWN   ) ...
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
simple.c&#58;596&#58;17&#58; warning&#58; '&&' within '||' &#91;-Wlogical-op-parentheses&#93;
      if&#40;f != 0 && board&#91;sq+15&#93; == BLACK+PAWN ||                            /...
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~
simple.c&#58;596&#58;17&#58; note&#58; place parentheses around the '&&' expression to silence
      this warning
      if&#40;f != 0 && board&#91;sq+15&#93; == BLACK+PAWN |...
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
simple.c&#58;597&#58;17&#58; warning&#58; '&&' within '||' &#91;-Wlogical-op-parentheses&#93;
         f != 7 && board&#91;sq+17&#93; == BLACK+PAWN   ) ...
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
simple.c&#58;597&#58;17&#58; note&#58; place parentheses around the '&&' expression to silence
      this warning
         f != 7 && board&#91;sq+17&#93; == BLACK+PAWN   ) ...
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
simple.c&#58;621&#58;1&#58; warning&#58; control reaches end of non-void function
      &#91;-Wreturn-type&#93;
&#125;
^
simple.c&#58;808&#58;29&#58; warning&#58; '&&' within '||' &#91;-Wlogical-op-parentheses&#93;
         iterDepth >= depth && bestScore >= beta&#41;  //     or for reduce...
         ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
simple.c&#58;808&#58;29&#58; note&#58; place parentheses around the '&&' expression to silence
      this warning
         iterDepth >= depth && bestScore >= beta&#41;  //     or for reduce...
                            ^
         (                                      )
simple.c&#58;812&#58;63&#58; warning&#58; implicit declaration of function 'TimeIsUp' is invalid
      in C99 &#91;-Wimplicit-function-declaration&#93;
    if&#40;&#40;nodeCount++ & 0x3FF&#41; == 0 && !forceMove&#41; abortFlag |= TimeIsUp&#40;3...
                                                              ^
simple.c&#58;851&#58;62&#58; warning&#58; operator '<<' has lower precedence than '+'; '+' will
      be evaluated first &#91;-Wshift-op-parentheses&#93;
  ...moves&#91;--captures&#93; = to | from<<8 | QUEEN-PAWN+0x8000<<16;// add promotio...
                                        ~~~~~~~~~~^~~~~~~~~
simple.c&#58;851&#58;62&#58; note&#58; place parentheses around the '+' expression to silence
      this warning
  ...moves&#91;--captures&#93; = to | from<<8 | QUEEN-PAWN+0x8000<<16;// add promotio...
                                        ~~~~~~~~~~^~~~~~~
simple.c&#58;852&#58;58&#58; warning&#58; operator '<<' has lower precedence than '-'; '-' will
      be evaluated first &#91;-Wshift-op-parentheses&#93;
  ...moves&#91;lastMove++&#93; = to | from<<8 | KNIGHT-PAWN<<16;      // and under-pr...
                                        ~~~~~~^~~~~~~
simple.c&#58;852&#58;58&#58; note&#58; place parentheses around the '-' expression to silence
      this warning
  ...moves&#91;lastMove++&#93; = to | from<<8 | KNIGHT-PAWN<<16;      // and under-pr...
                                        ~~~~~~^~~~~
simple.c&#58;855&#58;59&#58; warning&#58; operator '<<' has lower precedence than '-'; '-' will
      be evaluated first &#91;-Wshift-op-parentheses&#93;
  ...moves&#91;--captures&#93; = to | from<<8 | key&#91;victim&#93;-type << 24;   // add capt...
                                        ~~~~~~~~~~~^~~~~ ~~
simple.c&#58;855&#58;59&#58; note&#58; place parentheses around the '-' expression to silence
      this warning
  ...moves&#91;--captures&#93; = to | from<<8 | key&#91;victim&#93;-type << 24;   // add capt...
                                                   ^
                                        (               )
simple.c&#58;880&#58;62&#58; warning&#58; operator '<<' has lower precedence than '+'; '+' will
      be evaluated first &#91;-Wshift-op-parentheses&#93;
  ...moves&#91;--captures&#93; = to | from<<8 | QUEEN-PAWN+0x6000<<16;// add promotio...
                                        ~~~~~~~~~~^~~~~~~~~
simple.c&#58;880&#58;62&#58; note&#58; place parentheses around the '+' expression to silence
      this warning
  ...moves&#91;--captures&#93; = to | from<<8 | QUEEN-PAWN+0x6000<<16;// add promotio...
                                        ~~~~~~~~~~^~~~~~~
simple.c&#58;881&#58;58&#58; warning&#58; operator '<<' has lower precedence than '-'; '-' will
      be evaluated first &#91;-Wshift-op-parentheses&#93;
  ...moves&#91;lastMove++&#93; = to | from<<8 | KNIGHT-PAWN<<16;      //     under-pr...
                                        ~~~~~~^~~~~~~
simple.c&#58;881&#58;58&#58; note&#58; place parentheses around the '-' expression to silence
      this warning
  ...moves&#91;lastMove++&#93; = to | from<<8 | KNIGHT-PAWN<<16;      //     under-pr...
                                        ~~~~~~^~~~~
simple.c&#58;884&#58;61&#58; warning&#58; operator '<<' has lower precedence than '+'; '+' will
      be evaluated first &#91;-Wshift-op-parentheses&#93;
  ...moves&#91;lastMove++&#93; = to+step | from<<8 | 0x80+to<<16;     // add double p...
                                             ~~~~^~~~~
simple.c&#58;884&#58;61&#58; note&#58; place parentheses around the '+' expression to silence
      this warning
  ...moves&#91;lastMove++&#93; = to+step | from<<8 | 0x80+to<<16;     // add double p...
                                                 ^
                                             (      )
simple.c&#58;907&#58;58&#58; warning&#58; operator '<<' has lower precedence than '+'; '+' will
      be evaluated first &#91;-Wshift-op-parentheses&#93;
      moves&#91;lastMove++&#93; = king+2*dir | king<<8 | king+dir+0x80<<16;      // ad...
                                                 ~~~~~~~~^~~~~~~
simple.c&#58;907&#58;58&#58; note&#58; place parentheses around the '+' expression to silence
      this warning
      moves&#91;lastMove++&#93; = king+2*dir | king<<8 | king+dir+0x80<<16;      // ad...
                                                         ^
                                                 (            )
simple.c&#58;1012&#58;25&#58; warning&#58; expression result unused &#91;-Wunused-value&#93;
  ...iterDepth <= 1 && eval + value&#91;victim&#93; + value&#91;epVictim&#93; < alpha - 200,0...
     ~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
simple.c&#58;1076&#58;34&#58; warning&#58; while loop has empty body &#91;-Wempty-body&#93;
          while&#40;(*p++ = *pvSP++)); pvSP = p;                // append da...
                                 ^
simple.c&#58;1076&#58;34&#58; note&#58; put the semicolon on a separate line to silence this
      warning
simple.c&#58;1113&#58;54&#58; warning&#58; '&&' within '||' &#91;-Wlogical-op-parentheses&#93;
          !ply && !forceMove && iterDepth < maxDepth && !TimeIsUp&#40;1&#41;); /...
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
simple.c&#58;1113&#58;54&#58; note&#58; place parentheses around the '&&' expression to silence
      this warning
          !ply && !forceMove && iterDepth < maxDepth && !TimeIsUp&#40;1&#41;); /...
                                                     ^
          (                                                         )
simple.c&#58;1118&#58;36&#58; warning&#58; '&' within '|' &#91;-Wbitwise-op-parentheses&#93;
    bucket->move&#91;slot&#93;  = hashMove & 0xFFFFFF | checker << 24; // pack c...
                          ~~~~~~~~~^~~~~~~~~~ ~
simple.c&#58;1118&#58;36&#58; note&#58; place parentheses around the '&' expression to silence
      this warning
    bucket->move&#91;slot&#93;  = hashMove & 0xFFFFFF | checker << 24; // pack c...
                                   ^
                          (                  )
simple.c&#58;1175&#58;1&#58; warning&#58; control may reach end of non-void function
      &#91;-Wreturn-type&#93;
&#125;
^
simple.c&#58;1195&#58;21&#58; warning&#58; operator '>>' has lower precedence than '-'; '-' will
      be evaluated first &#91;-Wshift-op-parentheses&#93;
      pstEval += &#40;4 - &#40;i&8&#41; >> 2&#41;*pst&#91;i&#93;&#91;sqr&#93;;        // update PST eva...
                  ~~^~~~~~~ ~~
simple.c&#58;1195&#58;21&#58; note&#58; place parentheses around the '-' expression to silence
      this warning
      pstEval += &#40;4 - &#40;i&8&#41; >> 2&#41;*pst&#91;i&#93;&#91;sqr&#93;;        // update PST eva...
                    ^
                  (        )
simple.c&#58;1214&#58;1&#58; warning&#58; type specifier missing, defaults to 'int'
      &#91;-Wimplicit-int&#93;
MakeMove &#40;int move&#41;
^
simple.c&#58;1239&#58;12&#58; warning&#58; if statement has empty body &#91;-Wempty-body&#93;
  if&#40;s&#91;4&#93;) ; // TODO&#58; promotion
           ^
simple.c&#58;1239&#58;12&#58; note&#58; put the semicolon on a separate line to silence this
      warning
simple.c&#58;1296&#58;16&#58; warning&#58; '&&' within '||' &#91;-Wlogical-op-parentheses&#93;
  if&#40;score > 0 && stm == WHITE || score < 0 && stm == BLACK&#41; printf&#40;"1-0\n");
     ~~~~~~~~~~^~~~~~~~~~~~~~~ ~~
simple.c&#58;1296&#58;16&#58; note&#58; place parentheses around the '&&' expression to silence
      this warning
  if&#40;score > 0 && stm == WHITE || score < 0 && stm == BLACK&#41; printf&#40;"1-0\n");
     ~~~~~~~~~~^~~~~~~~~~~~~~~
simple.c&#58;1296&#58;45&#58; warning&#58; '&&' within '||' &#91;-Wlogical-op-parentheses&#93;
  if&#40;score > 0 && stm == WHITE || score < 0 && stm == BLACK&#41; printf&#40;"1-0\n");
                               ~~ ~~~~~~~~~~^~~~~~~~~~~~~~~
simple.c&#58;1296&#58;45&#58; note&#58; place parentheses around the '&&' expression to silence
      this warning
  if&#40;score > 0 && stm == WHITE || score < 0 && stm == BLACK&#41; printf&#40;"1-0\n");
                                  ~~~~~~~~~~^~~~~~~~~~~~~~~
30 warnings generated.
Is it supposed to give this amount of warnings? The code really looks like that and is incomprehensible to me as well. Maybe this is the wrong version?

When I run it, an easy win:

Code: Select all

./kingslayer 
go
0-1
[Account deleted]
User avatar
hgm
Posts: 27837
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Symbolic vs tscp: more match results

Post by hgm »

This is the version that crushes Fairy-Max. I never claimed that it was finished. Almost all eval terms are currently disabled by default, and the code calculating them is not tested or debugged.

The compiler is right to consider the if(... ,1) suspicious, but the ",1" is actually just a temporary addition to force an immediate null-return for a routine that is not yet finished (KQKPdraw). The empty-body statement is in that disabled routine (and one of the reasons for disabling it). The empty body on line 365 (KPKdraw) could be a genuine error, though, thanks for spotting it. On line 1239 the empty body is accompanied by a 'TODO' comment; the body will be supplied when I decide how to handle under-promotions at game level, so that I would know what has to be done here.

The missing return value in the Fortress1 function is a bad error; I am surprised that my compiler does not complain about that. (I get no warnings at all when I compile with gcc.) The function is not yet active (recognizers = 0, forcing an immediate null return, so the error in KPKdraw mentioned above is also in inactive code). The same error in PawnEval is just because the latter should have been declared as 'void' anyway; it is called only in one place, where the value is not used.

Your compiler seems to take offense to an implicit declaration; mine apparently doesn't (and they always seem to work correctly).

The 'unused value' is a temporary disabling of not-yet-woking code for futility pruning by suffixing it with ",0".

The missing return in TimeIsUp would be non-reachable; I can put one there just to silence the warning.

The rest of the warnings is just nonsense about unnecessary parantheses. Perhaps compiling with -Wnosillywarnings would adequately deal with those. :wink:

As to your easy win:

It seems you did forget to give the 'new' command to start a game. Not much of an achievement to beat an opponent that has no pieces! :lol:
(Actually a bit strange that it does not claim this as a stalemate, though. But the code was not designed to handle the absence of Kings, so the check detection could very well go haywire here.)
mvk
Posts: 589
Joined: Tue Jun 04, 2013 10:15 pm

Re: Symbolic vs tscp: more match results

Post by mvk »

hgm wrote:The rest of the warnings is just nonsense about unnecessary parantheses. Perhaps compiling with -Wnosillywarnings would adequately deal with those. :wink:


Unfortunately that increases the number of warnings by 1:

Code: Select all

cc -O2 -s -Wnosillywarnings   simple.c -o kingslayer
warning&#58; unknown warning option '-Wnosillywarnings'; did you mean '-W#warnings'?
      &#91;-Wunknown-warning-option&#93;
&#91;...&#93;
31 warnings generated.
As to your easy win:

It seems you did forget to give the 'new' command to start a game. Not much of an achievement to beat an opponent that has no pieces! :lol:
(Actually a bit strange that it does not claim this as a stalemate, though. But the code was not designed to handle the absence of Kings, so the check detection could very well go haywire here.)

Code: Select all

./kingslayer 
new
go
0-1
Under Xboard the program plays fine. Thanks a lot, I will certainly use it to test my side project, which happens to play some sort of chess now.

I quickly browsed through simple.c. You use all globals, which is not bad by itself for this purpose. But I can recommend to declare everything as 'static', to avoid accidental name clashes and all you want to have externally visible is 'main' anyway. (I was once bitten by naming a global variable 'exp', and that crashed nicely on some platforms.)
[Account deleted]
User avatar
hgm
Posts: 27837
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Symbolic vs tscp: more match results

Post by hgm »

Oh, it seems that the 0-1 happens because you give it zero time. This immediately aborts the search after the first move in the root returns, so that no valid move was found, and this leads to resign.

So

./kingslayer
new
time 10000
go

works fine. Like you say, XBoard would do this, and King Slayer plays fine there. Swintching on any of its options is at your own risk, although drawishness in combination with recognizers wold probably work in the version I just pushed,and be an improvement. Other options could be so purely tuned that they weaken play even if they are bug-free. (Current match result 37+ 7= 2- in favor of King Slayer at 5+0.)