summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Lang <mlang@delysid.org>2014-04-18 16:32:44 +0200
committerMario Lang <mlang@delysid.org>2014-04-18 16:32:44 +0200
commit21c5106bf8c043db243a18e7c365d8dc3200ddfa (patch)
tree22b678460874b065af6a841ff177c7a3aa59c2cc
parent6cf13b7b6a9458da5b1c7f054d6e69484187017a (diff)
chess-perft: Refactor to avoid repeatedly visiting the same list of plies at depth 1.
-rw-r--r--chess-perft.el84
1 files changed, 33 insertions, 51 deletions
diff --git a/chess-perft.el b/chess-perft.el
index 495ede9..dd6cc55 100644
--- a/chess-perft.el
+++ b/chess-perft.el
@@ -54,58 +54,40 @@ The result is a list of the form
(if (zerop depth)
(cl-values 1 0 0 0 0)
(let ((plies (chess-legal-plies position
- :color (chess-pos-side-to-move position))))
+ :color (chess-pos-side-to-move position)))
+ (nodes 0) (captures 0) (en-passants 0) (castles 0) (promotions 0)
+ (checks 0) (checkmates 0))
(if (= depth 1)
- (cl-values (length plies)
- ;; Captures
- (cl-count-if
- (lambda (ply)
- (or (chess-pos-piece-p
- (chess-ply-pos ply) (chess-ply-target ply)
- (not (chess-pos-side-to-move (chess-ply-pos ply))))
- (chess-ply-keyword ply :en-passant)))
- plies)
- ;; En passants
- (cl-count-if
- (lambda (ply)
- (chess-ply-keyword ply :en-passant))
- plies)
- ;; Castles
- (cl-count-if
- (lambda (ply)
- (chess-ply-any-keyword ply :castle :long-castle))
- plies)
- ;; Promotions
- (cl-count-if
- (lambda (ply)
- (chess-ply-keyword ply :promote))
- plies)
- ;; Checks
- (cl-count-if
- (lambda (ply)
- (chess-ply-any-keyword ply :check :checkmate))
- plies)
- ;; Checkmates
- (cl-count-if
- (lambda (ply)
- (chess-ply-any-keyword ply :checkmate))
- plies))
- (let ((nodes 0) (captures 0) (en-passants 0)
- (castles 0) (promotions 0)
- (checks 0) (checkmates 0))
- (dolist (ply plies (cl-values nodes
- captures en-passants
- castles promotions
- checks checkmates))
- (cl-multiple-value-bind (n c e ca p ch cm)
- (chess-perft (chess-ply-next-pos ply) (1- depth))
- (cl-incf nodes n)
- (cl-incf captures c)
- (cl-incf en-passants e)
- (cl-incf castles ca)
- (cl-incf promotions p)
- (cl-incf checks ch)
- (cl-incf checkmates cm))))))))
+ (dolist (ply plies)
+ (cl-incf nodes)
+ (when (let ((position (chess-ply-pos ply)))
+ (chess-pos-piece-p position (chess-ply-target ply)
+ (not (chess-pos-side-to-move position))))
+ (cl-incf captures))
+ (when (chess-ply-keyword ply :en-passant)
+ (cl-incf captures)
+ (cl-incf en-passants))
+ (if (chess-ply-any-keyword ply :castle :long-castle)
+ (cl-incf castles)
+ (when (chess-ply-keyword ply :promote)
+ (cl-incf promotions)))
+ (when (chess-ply-any-keyword ply :check :checkmate)
+ (cl-incf checks))
+ (when (chess-ply-any-keyword ply :checkmate)
+ (cl-incf checkmates)) )
+ (dolist (ply plies)
+ (cl-multiple-value-bind (n c e ca p ch cm)
+ (chess-perft (chess-ply-next-pos ply) (1- depth))
+ (cl-incf nodes n)
+ (cl-incf captures c)
+ (cl-incf en-passants e)
+ (cl-incf castles ca)
+ (cl-incf promotions p)
+ (cl-incf checks ch)
+ (cl-incf checkmates cm))))
+
+ (cl-values nodes
+ captures en-passants castles promotions checks checkmates))))
(ert-deftest chess-perft-startpos-depth1 ()
(should (equal (chess-perft (chess-pos-create) 1) '(20 0 0 0 0 0 0))))