[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/gnugo 40f7299 225/357: [gnugo] Fix bug: Ensure gametree

From: Stefan Monnier
Subject: [elpa] externals/gnugo 40f7299 225/357: [gnugo] Fix bug: Ensure gametree sync for -l/--infile.
Date: Sun, 29 Nov 2020 14:51:27 -0500 (EST)

branch: externals/gnugo
commit 40f7299123fede5e805fbbc0a44dbcd07b4907a8
Author: Thien-Thi Nguyen <ttn@gnu.org>
Commit: Thien-Thi Nguyen <ttn@gnu.org>

    [gnugo] Fix bug: Ensure gametree sync for -l/--infile.
    Previously, specifying ‘--infile FILENAME’ (or ‘-l FILENAME’)
    would result in a degenerate (root-node only) :sgf-gametree.
    Incidentally, the "don't snoop" part of this change removes
    the last remaining barrier to clean ‘lexical-binding: t’.
    * packages/gnugo/gnugo.el (gnugo): Rewrite docstring;
    parse user-specified command-line arguments;
    don't snoop "--boardsize", "--handicap", "--komi";
    instead, defer until subprocess available and then query;
    rewrite kick args to segregate/prioritize "--infile", "-l";
    save filename; when filename specified, expand it and
    pass to ‘gnugo-read-sgf-file’ instead of constructing
    the degenerate gametree; combine ‘gnugo--SZ!’ call with
    aforementioned ‘board-size’, ‘handicap’, ‘komi’ mining
    and do only for degenerate gametree construction.
 HACKING  |  1 -
 NEWS     |  1 +
 gnugo.el | 96 +++++++++++++++++++++++++++++++++++++---------------------------
 3 files changed, 57 insertions(+), 41 deletions(-)

diff --git a/HACKING b/HACKING
index c68d82c..5e54748 100644
@@ -5,7 +5,6 @@ This file is both a guide for newcomers and a todo list for 
 * next
 * fix bugs
 *** {next,previous}-line weirdness in the presence of images
-*** ‘-l FILENAME’ silently clobbers other options (PEBKAC, strictly speaking)
 *** no error-handling in SGF parsing
 *** performance -- ‘compare-strings’ approach too clever/slow :-/
 * ideas / wishlist
diff --git a/NEWS b/NEWS
index b803fd9..f552702 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ NB: "RCS: X..Y " means that the particular release includes
     - avoid clobbering SGF property ‘EV’ on resignation
     - follow main line in subtrees on read
     - for ‘F’ forced PASS moves, keep subproc informed as well
+    - proper support for ‘-l FILENAME’ / ‘--infile FILENAME’
   - dropped support for ‘gnugo-program’ of form "PROGRAM OPTIONS..."
   - dropped command: ‘t’ (gnugo-toggle-dead-group)
   - PASS for SZ <= 19 normalized to "" on read, written as ""
diff --git a/gnugo.el b/gnugo.el
index 06cabac..498da71 100644
--- a/gnugo.el
+++ b/gnugo.el
@@ -2409,21 +2409,20 @@ In this mode, keys do not self insert.
 (defun gnugo (&optional new-game)
   "Run gnugo in a buffer, or resume a game in progress.
-Prefix arg means skip the game-in-progress check and start a new
-game straight away.
-To play, use \\[gnugo-move] to place a stone or \\[gnugo-pass] to pass.
+If there is already a game in progress you may resume it instead
+of starting a new one.  Prefix arg means skip the game-in-progress
+check and start a new game straight away.
-You are queried for additional command-line options (Emacs supplies
-\"--mode gtp --quiet\" automatically).  Here is a list of options
-that gnugo.el understands and handles specially:
+Before starting, Emacs queries you for additional command-line
+options (Emacs supplies \"--mode gtp --quiet\" automatically).
-    --boardsize num   Set the board size to use (5--19)
-    --color <color>   Choose your color ('black' or 'white')
-    --handicap <num>  Set the number of handicap stones (0--9)
+Note that specifying \"--infile FILENAME\" (or, \"-l FILENAME\")
+silently clobbers certain other options, such as \"--color\".
+For details, see info node `(gnugo) Invoking GNU Go'.
-If there is already a game in progress you may resume it instead of
-starting a new one.  See `gnugo-board-mode' documentation for more info."
+To play, use \\[gnugo-move] to place a stone or \\[gnugo-pass] to pass.
+See `gnugo-board-mode' for a full list of commands."
   (interactive "P")
   (let* ((all (let (acc)
                 (dolist (buf (buffer-list))
@@ -2449,46 +2448,56 @@ starting a new one.  See `gnugo-board-mode' 
documentation for more info."
       ;; set up a new board
       (switch-to-buffer (generate-new-buffer "(Uninitialized GNUGO Board)"))
-      (let* ((args (read-string "GNU Go options: "
+      (let* ((filename nil)
+             (user-color "black")
+             (args (loop
+                    with ls = (split-string
+                               ;; todo: grok ‘gnugo --help’; completion
+                               (read-string
+                                "GNU Go options: "
                                 (car gnugo-option-history)
+                    with ok
+                    while ls do
+                    (let ((arg (pop ls)))
+                      (cl-flet
+                          ((ex (opt fn)
+                               (if filename
+                                   (warn "%s %s ignored" opt fn)
+                                 (setq filename fn))))
+                        (cond
+                         ((string= "--color" arg)
+                          (push arg ok)
+                          (push
+                           ;; Unfortunately, GTP does not provide
+                           ;; a way to query the user color, so
+                           ;; we must resort to this weirdness.
+                           (setq user-color
+                                 (pop ls))
+                           ok))
+                         ((string= "--infile" arg)
+                          (ex "--infile" (pop ls)))
+                         ((string-match "^-l" arg)
+                          (ex "-l" (if (< 2 (length arg))
+                                       (substring arg 2)
+                                     (pop ls))))
+                         (t (push arg ok)))))
+                    finally return (nreverse ok)))
              (proc (apply 'start-process "gnugo"
                           "--mode" "gtp" "--quiet"
-                          (split-string args)))
-             board-size user-color handicap komi minus-l infile)
-        (loop for (var default opt rx)
-              in '((board-size      19 "--boardsize")
-                   (user-color "black" "--color" "\\(black\\|white\\)")
-                   (handicap         0 "--handicap")
-                   (komi           0.0 "--komi")
-                   (minus-l        nil "\\([^-]\\|^\\)-l[ ]*" "[^ ]+")
-                   (infile         nil "--infile" "[ ]*[^ ]+"))
-              do (set var
-                      (or (when (string-match opt args)
-                            (let ((start (match-end 0)) s)
-                              (string-match (or rx "[0-9.]+") args start)
-                              (setq s (match-string 0 args))
-                              (if rx s (string-to-number s))))
-                          default)))
+                          args))
+             root board-size handicap komi)
         (gnugo-put :user-color user-color)
         (gnugo-put :proc proc)
         (set-process-sentinel proc 'gnugo-sentinel)
         ;; Emacs is too protective sometimes, blech.
         (set-process-query-on-exit-flag proc nil)
-        (when (or minus-l infile)
-          (loop for (prop q)
-                in '((board-size "query_boardsize")
-                     (komi       "get_komi")
-                     (handicap   "get_handicap"))
-                do (set prop (gnugo--nquery q))))
         (gnugo-put :diamond (substring (process-name proc) 5))
         (gnugo-put :gnugo-color (gnugo-other user-color))
-        (gnugo--SZ! board-size)
-        (let ((root (gnugo--root-node
-                     (gnugo--plant-and-climb
-                      (gnugo/sgf-create "(;FF[4]GM[1])" t)))))
+        (if filename
+            (gnugo-read-sgf-file (expand-file-name filename))
               ((r! (&rest plist)
@@ -2497,9 +2506,16 @@ starting a new one.  See `gnugo-board-mode' 
documentation for more info."
                           collect (let* ((k (pop plist))
                                          (v (pop plist)))
                                     (cons k v))))))
+            (gnugo--SZ!
+             (setq root (gnugo--root-node
+                         (gnugo--plant-and-climb
+                          (gnugo/sgf-create "(;FF[4]GM[1])" t)))
+                   komi       (gnugo--nquery "get_komi")
+                   handicap   (gnugo--nquery "get_handicap")
+                   board-size (gnugo--nquery "query_boardsize")))
             (r! :SZ board-size
                 :DT (format-time-string "%Y-%m-%d")
-                :RU (if (string-match "--chinese-rules" args)
+                :RU (if (member "--chinese-rules" args)
                 :AP (cons "gnugo.el" gnugo-version)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]