CIL Toolkit: code snippets: move generation

Discussion of chess software programming and technical issues.

Moderator: Ras

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

CIL Toolkit: Client/Server Search Protocol

Post by sje »

CIL Toolkit: Client/Server Search Protocol

To start a search, the client sends the verb "start". If the server is already searching, a fatal error is signaled. Otherwise, the server enters search mode and starts searching for a move.

While the server is searching, the only verbs it will accept without signalling a fatal error are: "deponder", "report", "syncreq", and "finish".

Upon receiving a "deponder" verb, the server will begin to observe the time limit, if any.

Upon receiving a "syncreq" verb, the server will send a "syncack" reply with a matching synchronization ordinal.

Upon receiving a "report" verb, the server will send an "analysis" reply with a PV, score, node count, and search status. Other data may be sent as well.

Note: multiple "analysis" replies may be sent without being requested as the search progresses. If the search is resolved without being finished by the client, then a "resolved" reply is sent.

Upon receiving a "finish" verb, the server will respond in one of two ways:

----

1: If the search has not already been resolved, then

1.1: Further searching is cancelled.

1.2: The search termination is set to "interrupted".

1.3: The single "resolved" reply is sent; it contains the final analysis data.

1.4: The server exits search mode.

----

2: If the search has already been resolved, then

2.1: The "resolved" reply was already sent. However, it's possible that the client may not have received it when the "finish" verb was sent.

2.2: The server exits search mode.

----

From the client side:

The client first ensures that the server has the correct position, move history and other data needed to start a search.

The client sends a "start" verb to the server.

The client receives zero or more "analysis" replies.

If the server resolves the search, then the client receives the single "resolved" reply; the client then sends a "finish" verb to end the search.

If the client wants to terminate the search, it sends the "finish" verb and waits for the "resolved" reply.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: CIL Toolkit: code snippets: move generation

Post by sje »

1) I note that as this thread is averaging around 600 views per day, it's reasonable to conclude that there is some interest. If the daily average drops to about a hundred or so, then maybe I'll stop posting.

2) There are twenty topic slots available in flat view, so using up only one of them isn't too much to ask. The alternative of having many sub threads would consume too many topic slots.

3) No one is required to read the thread, except maybe the moderators. If any of them feel that the posts aren't acceptable for any reason, then they are welcome to remove them and I will not post any more.

4) Relevant criticism of the code is always welcome.
Harald
Posts: 318
Joined: Thu Mar 09, 2006 1:07 am

Re: CIL Toolkit: code snippets: move generation

Post by Harald »

sje wrote:1) I note that as this thread is averaging around 600 views per day, it's reasonable to conclude that there is some interest. If the daily average drops to about a hundred or so, then maybe I'll stop posting.

2) There are twenty topic slots available in flat view, so using up only one of them isn't too much to ask. The alternative of having many sub threads would consume too many topic slots.

3) No one is required to read the thread, except maybe the moderators. If any of them feel that the posts aren't acceptable for any reason, then they are welcome to remove them and I will not post any more.

4) Relevant criticism of the code is always welcome.
Ah, ok. Sorry!
Now I see my problem. I always use the threaded view, where the thread
is very long, and I don't see the number of readers.

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

CIL Toolkit: code snippets: client/server synchronization

Post by sje »

Some client side routines for controlling move selection:

Code: Select all

;;; Selection starter/finisher single point gateways

(defun select-start (my-cpc)
  "This is the single point routine for starting a move selection."
  (when (cpc-cs-active my-cpc)
    (error "select-start: selection already active"))
  (setf (cpc-cs-active my-cpc) t)
  (setf (cpc-cs-resolution my-cpc) nil)
  (send-selector my-cpc (build-verb-start my-cpc)))

(defun select-finish (my-cpc)
  "This is the single point routine for finishing a move selection."
  (unless (cpc-cs-active my-cpc)
    (error "select-finish: selection already inactive"))
  (send-selector my-cpc (build-verb-finish my-cpc))
  (unless (cpc-cs-resolution my-cpc)
    (dountil (cpc-cs-resolution my-cpc)
      (let ((sal (wait-next-selector-response my-cpc)))
        (when (= (cdr (assoc 'reply sal)) ssr-resolved)
          (setf (cpc-cs-resolution my-cpc) sal)))))
  (setf (cpc-cs-active my-cpc) nil))


;;; Selection deponder single point gateway

(defun select-deponder (my-cpc)
  "This is the single point routine for depondering a move selection."
  (unless (cpc-cs-active my-cpc)
    (error "select-deponder: selection is inactive"))
  (send-selector my-cpc (build-verb-deponder my-cpc)))


;;; Selection play/unplay single point gateways

(defun select-play (my-cpc my-move)
  "This is the single point routine for instructing the server to play a move."
  (when (cpc-cs-active my-cpc)
    (error "select-play: selection is active"))
  (advance-pos (cpc-cs-pos my-cpc) my-move)
  (send-selector my-cpc (build-verb-play my-cpc my-move)))

(defun select-unplay (my-cpc)
  "This is the single point routine for instructing the server to unplay a move."
  (when (cpc-cs-active my-cpc)
    (error "select-unplay: selection is active"))
  (retreat-pos (cpc-cs-pos my-cpc))
  (send-selector my-cpc (build-verb-unplay my-cpc)))


;;; Selection position reloading single point gateway

(defun select-reload (my-cpc my-pos my-base-fenpos)
  "This is the single point routine for instructing the server to set up a position."
  (when (cpc-cs-active my-cpc)
    (error "select-setpos: selection is active"))
  (setf (cpc-cs-base-fenpos my-cpc) (clone-fenpos my-base-fenpos))
  (setf (cpc-cs-pos         my-cpc) (clone-pos    my-pos))
  (send-selector my-cpc (build-verb-reload my-cpc my-pos my-base-fenpos)))


;;; Selection soft cancellation and soft synchronization

(defun select-soft-cancel (my-cpc)
  "Ensure that the selection is inactive."
  (when (cpc-cs-active my-cpc)
    (select-finish my-cpc)))

(defun select-soft-synchronize (my-cpc)
  "Ensure that the selection is inactive and the positions are synchronized."
  (select-soft-cancel my-cpc)
  (when
    (or
      (not (same-fenpos? (cpc-base-fenpos my-cpc) (cpc-cs-base-fenpos my-cpc)))
      (not (same-pos?    (cpc-pos         my-cpc) (cpc-cs-pos         my-cpc))))
    (select-reload my-cpc (cpc-pos my-cpc) (cpc-base-fenpos my-cpc))))
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

CIL Toolkit: code snippets: another speed test

Post by sje »

Movepath enumeration to depth eight:

Code: Select all

* (time-emp-cwt pos0 8)
Na3 3193522577
Nc3 3926684340
Nf3 3937354096
Nh3 3221278282
a3 2863411653
a4 3676309619
b3 3579299617
b4 3569067629
c3 3806229124
c4 4199667616
d3 6093248619
d4 7184581950
e3 8039390919
e4 8102108221
f3 2728615868
f4 3199039406
g3 3641432923
g4 3466204702
h3 2860408680
h4 3711123115
Ply:0  HT:[C:1048576 P:1 M:0 R:0.0 S:1 U:1 F:9.536743e-7]
Ply:1  HT:[C:1048576 P:20 M:0 R:0.0 S:20 U:20 F:1.9073486e-5]
Ply:2  HT:[C:1048576 P:400 M:0 R:0.0 S:400 U:400 F:3.8146973e-4]
Ply:3  HT:[C:1048576 P:8902 M:3540 R:0.39766344 S:5362 U:5358 F:0.005109787]
Ply:4  HT:[C:1048576 P:118522 M:46348 R:0.39104977 S:72174 U:69774 F:0.06654167]
Ply:5  HT:[C:1048576 P:1799932 M:841454 R:0.4674921 S:958478 U:571915 F:0.54542065]
Ply:6  HT:[C:1048576 P:23588501 M:10169469 R:0.43111977 S:13419032 U:1048473 F:0.9999018]
Ply:7  HT:[C:1048576 P:366186818 M:135122619 R:0.36899912 S:231064199 U:1048576 F:1.0]
Total path count for depth eight: 84998978956
Descriptive: eighty-four billion nine hundred ninety-eight million nine hundred seventy-eight thousand nine hundred fifty-six
F/P: 2.4389517 MHz / 410.01224 nsec
84998978956
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

CIL Toolkit: code snippets: xboard interface test

Post by sje »

The toolkit's xboard command processor interface has been nearly completed. Missing: full ponder logic, level setting, kibitzing, and result posting. Also, the search at this point in time merely returns a randomly selected move.

Hey, it's a start!

Incredible as it may seem, once I got the toolkit's I/O connected to xboard, the thing worked the very first time. Of course, there had been plenty of manual testing.

For your amusement, here are the very first games played by the new toolkit:

Code: Select all

[Event "Xboard game"]
[Site "gail"]
[Date "2008.10.11"]
[Round "1"]
[White "Symbolic v2008.05.25"]
[Black "Chess In Lisp Toolkit 2008.10.11"]
[Result "1-0"]
[Termination "Black is checkmated"]
[TimeControl "G/60"]
[LTS "Sat Oct 11 07:21:19 2008"]
[UTC "2008.10.11 11:21:19"]
[ECO "A40"]
[Opening "Queen's pawn: Charlick (Englund) gambit"]
[SOC "4650"]

1 d4 e5 2 dxe5 d6 3 g3 dxe5 4 Qxd8+ Kxd8 5 Bg2 Ke8 6 Nc3 h5 7 Nf3 h4 8 Nxh4 a6
9 Nd5 f6 10 Nxc7+ Kd7 11 Nxa8 Ne7 12 Be3 a5 13 Nb6+ Kc7 14 Nc4 Rh6 15 Bxh6 Nbc6
16 Be3 Bg4 17 Bb6+ Kb8 18 Nxa5 Ng6 19 Nxc6+ Ka8 20 Nxg6 Bd6 21 Rd1 e4 22 Nce7
Bb8 23 Rd4 Be6 24 Ra4+ Ba7 25 Rxa7+ Kb8 26 Bxe4 Bc8 27 Nf8 Bh3 28 Bxb7 Bc8 29
Nc6# 1-0

[Event "Xboard game"]
[Site "gail"]
[Date "2008.10.11"]
[Round "2"]
[White "Chess In Lisp Toolkit 2008.10.11"]
[Black "Symbolic v2008.05.25"]
[Result "0-1"]
[Termination "White is checkmated"]
[TimeControl "G/60"]
[LTS "Sat Oct 11 07:22:07 2008"]
[UTC "2008.10.11 11:22:07"]
[ECO "A04"]
[Opening "Reti opening"]
[SOC "0431"]

1 Nf3 c5 2 g4 d5 3 b3 Bxg4 4 a4 Bxf3 5 Ra3 Bxh1 6 a5 Qd6 7 d4 cxd4 8 Bh6 Qxh6 9
e4 dxe3 10 f4 Qh4+ 11 Ke2 Qg4+ 12 Ke1 Bf3 13 Ba6 Qg1+ 14 Bf1 Qf2# 0-1
smcracraft
Posts: 737
Joined: Wed Mar 08, 2006 8:08 pm
Location: Orange County California
Full name: Stuart Cracraft

Re: CIL Toolkit: code snippets: move generation

Post by smcracraft »

A question for you about CIL...
using your toolkit, have you or
others produced playable programs?

If so, I am curious what kinds of
strength on what kind of hardware
you/they achieved.

My interest in this is mostly curiousity
about Lisp, having done some light
programming (3 non-trivial programs)
so far.

Also, if any of those full programs are
available anywhere for inspection, that
would be great.

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

Re: CIL Toolkit: code snippets: move generation

Post by sje »

The new CIL Toolkit is not yet completed; perhaps by the end of this month, perhaps by the end of this year. So it will take some time to see what kind of players can be built.

Also, while I will obviously be releasing the toolkit source, I very likely will not be freely distributing the sources of any advanced programs I might build with the source. However, others are welcome to release what they want to release; I would respect their decisions either way.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

CIL Toolkit: code snippets: Citrine move notation encoding

Post by sje »

Here, "NAN" means "Novag (Citrine) Algebraic Notation":

Code: Select all

;;; Novag Citrine algebraic notation move encoding

(defun encode-nan (my-stream my-move)
  "Encode a move in Novag Citrine algebraic notation; hopefully they will switch to SAN someday."
  (cond
;;
    ((is-move-regular? my-move)
      (put-string my-stream (svref as-sq-vec (move-fr-sq my-move)))
      (if (is-move-simple-capture? my-move)
        (put-char my-stream #\x)
        (put-char my-stream ascii-hyphen))
      (put-string my-stream (svref as-sq-vec (move-to-sq my-move))))
;;
    ((is-move-en-passant? my-move)
      (put-string my-stream (svref as-sq-vec (move-fr-sq my-move)))
      (put-char my-stream #\x)
      (put-string my-stream (svref as-sq-vec (move-to-sq my-move))))
;;
    ((is-move-castling? my-move)
     (put-string my-stream (svref mc-msc-to-castling-san-vec (move-msc my-move))))
;;
    ((is-move-promotion? my-move)
      (put-string my-stream (svref as-sq-vec (move-fr-sq my-move)))
      (if (is-move-simple-capture? my-move)
        (put-char my-stream #\x)
        (put-char my-stream ascii-hyphen))
      (put-string my-stream (svref as-sq-vec (move-to-sq my-move)))
      (put-char my-stream ascii-slash)
      (put-char my-stream (svref acuc-piece-vec (svref mc-msc-to-piece-vec (move-msc my-move)))))
;;
    (t (error "encode-nan: cond fault")))
  (values))

(declaim (type (function (move) simple-base-string) nan-string))
(defun nan-string (my-move)
  "Encode a Novag Citrine algebraic notation move on a string."
  (let ((result nil) (str-stream (make-string-output-stream)))
    (encode-nan str-stream my-move)
    (setf result (get-output-stream-string str-stream))
    (close str-stream)
  result))
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

CIL Toolkit: code snippets: Citrine position encoding

Post by sje »

From the Novag Citrine documentation:

Code: Select all

Position : P 
To display the current board position or set up the board position. 
 
N 
New Game 
pcpa2ka1bkh8- 
pcpa2ka1bkh8- 
P 
Position Board 
. aa bb cc dd ee ff gg hh 
.8  ::    ::    ::    :: bk 8 
.7     ::    ::    ::    :: 7 
.6  ::    ::    ::    ::    6 
.5     ::    ::    ::    :: 5 
.4  ::    ::    ::    ::    4 
.3     ::    ::    ::    :: 3 
.2  WP    ::    ::    ::    2 
.1  WK ::    ::    ::    :: 1- 
. aa bb cc dd ee ff gg hh 
Toolkit routines:

Code: Select all

;;; Novag Citrine set position command encoding

(defun encode-novag-set-pos-aux (my-stream my-pos my-color)
  "Encode men by color for a set position command according to the Novag Citrine format."
  (let ((bb (clone-bb (svref (pos-loc-color-bb-vec my-pos) my-color))))
    (loop-bb (bb sq)
      (let ((man (get-man (pos-board my-pos) sq)))
        (format my-stream "~C" (svref ac-piece-vec (svref mc-man-to-piece-vec man)))
        (format my-stream "~A" (svref as-sq-vec sq)))))
  (values))

(defun encode-novag-set-pos (my-stream my-pos)
  "Encode a set position command according to the Novag Citrine format."
  (format my-stream "Pc")
  (encode-novag-set-pos-aux my-stream my-pos color-white)
  (format my-stream "b")
  (encode-novag-set-pos-aux my-stream my-pos color-black)
  (format my-stream "~C" (if (= (pos-act-color my-pos) color-white) #\+ #\-))
  (values))

(declaim (type (function (pos) simple-base-string) novag-set-pos-string))
(defun novag-set-pos-string (my-pos)
  "Encode a Novag set position command on a string."
  (let ((result nil) (str-stream (make-string-output-stream)))
    (encode-novag-set-pos str-stream my-pos)
    (setf result (get-output-stream-string str-stream))
    (close str-stream)
  result))
Samples:
[d]7k/8/8/8/8/8/8/K7 w - - 0 1

Code: Select all

Pcka1bkh8+
[d]2qrr1n1/3b1kp1/2pBpn1p/1p2PP2/p2P4/1BP5/P3Q1PP/4RRK1 w - - 0 1

Code: Select all

Pcre1rf1kg1pa2qe2pg2ph2bb3pc3pd4pe5pf5bd6bpa4pb5pc6pe6nf6ph6bd7kf7pg7qc8rd8re8ng8+