summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Lang <mlang@delysid.org>2014-03-28 11:57:29 +0100
committerMario Lang <mlang@delysid.org>2014-03-28 12:14:19 +0100
commit6ece68a4a2f5a413f48bb6816b25a41a9376ee3e (patch)
tree2ac7ebe01ee50b451ee2e308e1454d5a539a2b86
parent866b08a1f0c41c54fe398730ed7d3a0e77f400db (diff)
Make the strength of book replies configurable.
-rw-r--r--chess-polyglot.el36
-rw-r--r--chess-uci.el17
2 files changed, 34 insertions, 19 deletions
diff --git a/chess-polyglot.el b/chess-polyglot.el
index a58ae8d..a9a0551 100644
--- a/chess-polyglot.el
+++ b/chess-polyglot.el
@@ -462,23 +462,27 @@ Use `chess-ply-keyword' on elements of the returned list to retrieve them."
(when ply
(setq plies (nconc plies (list ply))))))))
-(defun chess-polyglot-book-ply (book position)
- "If non-nil, a (randomly picked) ply from plies in BOOK for POSITION.
-Random distribution is defined by the relative weights of the found plies."
- (let* ((plies (chess-polyglot-book-plies book position))
- (random-value (random (cl-reduce
- #'+ (mapcar (lambda (ply)
- (chess-ply-keyword
- ply :polyglot-book-weight))
- plies))))
- (max 0) ply)
- (while plies
- (let ((min max))
- (setq max (+ max (chess-ply-keyword (car plies) :polyglot-book-weight)))
- (if (and (>= random-value min) (< random-value max))
+(defun chess-polyglot-book-ply (book position &optional strength)
+ "If non-nil a (randomly picked) ply from plies in BOOK for POSITION.
+Random distribution is defined by the relative weights of the found plies.
+If non-nil, STRENGTH defines the bias towards better moves.
+A value below 1.0 will penalize known good moves while a value
+above 1.0 will prefer known good moves. The default is 1.0.
+A strength value of 0.0 will completely ignore move weights and evenly
+distribute the probability that a move gets picked."
+ (unless strength (setq strength 1.0))
+ (cl-assert (and (>= strength 0) (< strength 4)))
+ (cl-flet ((ply-weight (ply)
+ (round (expt (chess-ply-keyword ply :polyglot-book-weight)
+ strength))))
+ (let* ((plies (chess-polyglot-book-plies book position))
+ (random-value (random (cl-reduce #'+ (mapcar #'ply-weight plies))))
+ (max 0) ply)
+ (while plies
+ (if (< random-value (setq max (+ max (ply-weight (car plies)))))
(setq ply (car plies) plies nil)
- (setq plies (cdr plies)))))
- ply))
+ (setq plies (cdr plies))))
+ ply)))
(defalias 'chess-polyglot-book-close 'kill-buffer
"Close a polyglot book.")
diff --git a/chess-uci.el b/chess-uci.el
index ad6852c..e164f72 100644
--- a/chess-uci.el
+++ b/chess-uci.el
@@ -36,7 +36,16 @@
(defcustom chess-uci-polyglot-book-file nil
"The path to a polyglot binary opening book file."
:group 'chess-uci
- :type '(choice (const :tag "Not specified" nil) file))
+ :type '(choice (const :tag "Not specified" nil) (file :must-match t)))
+
+(defcustom chess-uci-polyglot-book-strength 1.0
+ "Influence random distribution when picking a ply from the book.
+A value above 1.0 means to prefer known good moves while a value below
+1.0 means to penalize known good moves. 0.0 will stop to consider
+move weights and simply pick a move at random. For simple
+reasons of numerical overflow, this should be strictly less than 4.0."
+ :group 'chess-uci
+ :type '(float :match (lambda (widget value) (and (>= value 0) (< value 4)))))
(defvar chess-uci-book nil
"A (polyglot) opening book object.
@@ -121,8 +130,10 @@ If conversion fails, this function fired an 'illegal event."
(let ((book-ply (and chess-uci-book (bufferp chess-uci-book)
(buffer-live-p chess-uci-book)
- (chess-polyglot-book-ply chess-uci-book
- (chess-game-pos game)))))
+ (chess-polyglot-book-ply
+ chess-uci-book
+ (chess-game-pos game)
+ chess-uci-polyglot-book-strength))))
(if book-ply
(let ((chess-display-handling-event nil))
(funcall chess-engine-response-handler 'move book-ply))