;; Author: Thien-Thi Nguyen <ttn@gnu.org>
;; Maintainer: Thien-Thi Nguyen <ttn@gnu.org>
-;; Version: 2.3.1
-;; Package-Requires: ((ascii-art-to-unicode "1.5") (xpm "1.0.0"))
+;; Version: 3.0.0
+;; Package-Requires: ((ascii-art-to-unicode "1.5") (xpm "1.0.1") (cl-lib "0.5"))
+;; Keywords: games, processes
+;; URL: http://www.gnuvola.org/software/gnugo/
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; Meta-Meta-Playing (aka Hacking)
;; -------------------------------
;;
-;; <http://git.sv.gnu.org/cgit/emacs/elpa.git/tree/packages/gnugo/HACKING>
-;;
-;;
-;; Tip Jar
-;; -------
-;;
-;; <http://www.gnuvola.org/software/gnugo/>
+;; <http://git.sv.gnu.org/cgit/emacs/elpa.git/tree/packages/gnugo/>
;;; Code:
-(eval-when-compile (require 'cl)) ; use the source luke!
-(require 'ascii-art-to-unicode) ; for `aa2u'
+(require 'cl-lib) ; use the source luke!
(require 'time-date) ; for `time-subtract'
;;;---------------------------------------------------------------------------
;;; Political arts
-(defconst gnugo-version "2.3.1"
+(defconst gnugo-version "3.0.0"
"Version of gnugo.el currently loaded.
This follows a MAJOR.MINOR.PATCH scheme.")
For more information on GTP and GNU Go, please visit:
<http://www.gnu.org/software/gnugo>")
-(defvar gnugo-board-mode-map nil
+(defvar gnugo-board-mode-map
+ ;; Re <http://lists.gnu.org/archive/html/emacs-devel/2014-04/msg00123.html>,
+ ;; ideally we could ‘defvar’ here w/o value and also ‘defvar’ below
+ ;; in "load-time actions" w/ value and docstring, to avoid this ugly
+ ;; (from the forward references) block early in the file. Unfortunately,
+ ;; byte-compiling such a split formulation results in the initial ‘defvar’
+ ;; being replaced by:
+ ;; (defvar VAR (make-sparse-keymap))
+ ;; and the second ‘defvar’ is ignored on load. At least, this is the case
+ ;; for Emacs built from repo (trunk) 2014-05-27. --ttn
+ (let ((map (make-sparse-keymap)))
+ (suppress-keymap map)
+ (mapc (lambda (pair)
+ (define-key map (car pair) (cdr pair)))
+ '(("?" . describe-mode)
+ ("S" . gnugo-request-suggestion)
+ ("\C-m" . gnugo-move)
+ (" " . gnugo-move)
+ ("P" . gnugo-pass)
+ ("R" . gnugo-resign)
+ ("q" . gnugo-quit)
+ ("Q" . gnugo-leave-me-alone)
+ ("U" . gnugo-fancy-undo)
+ ("\M-u" . gnugo-undo-one-move)
+ ("u" . gnugo-undo-two-moves)
+ ("\C-?" . gnugo-undo-two-moves)
+ ("o" . gnugo-oops)
+ ("O" . gnugo-okay)
+ ("\C-l" . gnugo-refresh)
+ ("\M-_" . gnugo-boss-is-near)
+ ("_" . gnugo-boss-is-near)
+ ("h" . gnugo-move-history)
+ ("L" . gnugo-frolic-in-the-leaves)
+ ("\C-c\C-l" . gnugo-frolic-in-the-leaves)
+ ("i" . gnugo-image-display-mode)
+ ("w" . gnugo-worm-stones)
+ ("W" . gnugo-worm-data)
+ ("d" . gnugo-dragon-stones)
+ ("D" . gnugo-dragon-data)
+ ("g" . gnugo-grid-mode)
+ ("!" . gnugo-estimate-score)
+ (":" . gnugo-command)
+ (";" . gnugo-command)
+ ("=" . gnugo-describe-position)
+ ("s" . gnugo-write-sgf-file)
+ ("\C-x\C-s" . gnugo-write-sgf-file)
+ ("\C-x\C-w" . gnugo-write-sgf-file)
+ ("l" . gnugo-read-sgf-file)
+ ("F" . gnugo-display-final-score)
+ ("A" . gnugo-switch-to-another)
+ ("C" . gnugo-comment)
+ ("\C-c\C-a" . gnugo-assist-mode)
+ ("\C-c\C-z" . gnugo-zombie-mode)
+ ;; mouse
+ ([(down-mouse-1)] . gnugo-mouse-move)
+ ([(down-mouse-2)] . gnugo-mouse-move) ; mitigate accidents
+ ([(down-mouse-3)] . gnugo-mouse-pass)
+ ;; delving into the curiosities
+ ("\C-c\C-p" . gnugo-describe-internal-properties)))
+ map)
"Keymap for GNUGO Board mode.")
(defvar gnugo-board-mode-hook nil
(interactive)
(let ((buf (current-buffer))
(d (gnugo-get :diamond))
- (acc (loop for key being the hash-keys of gnugo-state
- using (hash-values val)
- collect (cons key
- (case key
- ((:xpms)
- (format "hash: %X (%d images)"
- (sxhash val)
- (length val)))
- (:sgf-collection
- (length val))
- (:sgf-gametree
- (list (hash-table-count
- (gnugo--tree-mnum val))
- (gnugo--root-node val)
- (gnugo--tree-ends val)))
- (:monkey
- (let ((mem (aref val 0)))
- (list (aref val 1)
- (car mem))))
- (t val))))))
+ (acc (cl-loop
+ for key being the hash-keys of gnugo-state
+ using (hash-values val)
+ collect (cons key
+ (cl-case key
+ ((:xpms)
+ (format "hash: %X (%d images)"
+ (sxhash val)
+ (length val)))
+ (:sgf-collection
+ (length val))
+ (:sgf-gametree
+ (list (hash-table-count
+ (gnugo--tree-mnum val))
+ (gnugo--root-node val)
+ (gnugo--tree-ends val)))
+ (:monkey
+ (let ((mem (aref val 0)))
+ (list (aref val 1)
+ (car mem))))
+ (t val))))))
(switch-to-buffer (get-buffer-create
(format "%s*GNUGO Board Properties*"
d)))
(if (string= "" d)
".+\n"
""))))
- (while (re-search-forward rx (point-max) t)
+ (while (re-search-forward rx nil t)
(let ((pos (get-text-property (string-to-number (match-string 1))
'gnugo-position buf)))
(delete-region (+ 2 (match-beginning 0)) (point))
(user-error "Wrong buffer -- try M-x gnugo"))
(unless (gnugo-get :proc)
(user-error "No \"gnugo\" process!"))
- (destructuring-bind (&optional color . suggestion)
+ (cl-destructuring-bind (&optional color . suggestion)
(gnugo-get :waiting)
(when color
(apply 'user-error
(setplist (gnugo-f 'ispc) (and new '(display (space :width 0))))
(gnugo-put :highlight-last-move-spec
(if new
- '((lambda (p)
- (get (gnugo-yy (get-text-property p 'gnugo-yin)
- (get-text-property p 'gnugo-yang)
- t)
- 'display))
+ `(,(lambda (p)
+ (get (gnugo-yy (get-text-property p 'gnugo-yin)
+ (get-text-property p 'gnugo-yang)
+ t)
+ 'display))
0 delete-overlay)
(gnugo-get :default-highlight-last-move-spec)))
;; a kludge to be reworked another time perhaps by another gnugo.el lover
(funcall (if bool
'remove-from-invisibility-spec
'add-to-invisibility-spec)
- :nogrid)
+ :nogrid)
(save-excursion (gnugo-refresh)))))
(defun gnugo-propertize-board-buffer ()
;; This has something to do w/ the bletcherous `before-string'.
(overlay-put ov 'invisible :nogrid)
(overlay-put ov 'category %lpad))
- (do ((p edge (+ 2 p)) (ival 'even (if (eq 'even ival) 'odd 'even)))
+ (cl-do ((p edge (+ 2 p)) (ival 'even (if (eq 'even ival) 'odd 'even)))
((< other-edge p))
(let* ((position (format "%c%s" (aref "ABCDEFGHJKLMNOPQRST"
(truncate (- p edge) 2))
(gnugo-put capprop new)
(delete-char old-len)
(insert (apply 'propertize new keep))
- (incf adj (- (length new) old-len)))
+ (cl-incf adj (- (length new) old-len)))
(setq new (aref aft aft-idx))
(insert-and-inherit (char-to-string new))
(let ((yin (get-text-property cut 'gnugo-yin))
(assq :W node)))
(defun gnugo--as-pos-func ()
- (lexical-let ((size (gnugo-get :SZ)))
+ (let ((size (gnugo-get :SZ)))
;; rv
(lambda (cc)
(if (string= "" cc)
(`car (car (nn)))
(`cadr (nn) (car (nn)))
(`two (nn) (nn) acc)
- (`bpos (loop with prop = (gnugo--prop<-color color)
- while mem
- when (and (remem)
- (eq prop (car mprop))
- (setq move (cdr mprop))
- ;; i.e., "normal CC" position
- (= 2 (length move)))
- return (funcall as-pos move)))
+ (`bpos (cl-loop
+ with prop = (gnugo--prop<-color color)
+ while mem
+ when (and (remem)
+ (eq prop (car mprop))
+ (setq move (cdr mprop))
+ ;; i.e., "normal CC" position
+ (= 2 (length move)))
+ return (funcall as-pos move)))
(_ nil)))))
(defun gnugo-boss-is-near ()
(aref monkey 0)))
(defun gnugo--as-cc-func ()
- (lexical-let ((size (gnugo-get :SZ)))
+ (let ((size (gnugo-get :SZ)))
(lambda (pos)
(let* ((col (aref pos 0))
(one (+ ?a (- col (if (< ?H col) 1 0) ?A)))
(format "%c%c" one two)))))
(defun gnugo--decorate (node &rest plist)
- (loop with tp = (last node)
- with fruit
- while plist
- do (setf
- fruit (list (cons ; DWR: LtR OoE assumed.
- (pop plist)
- (pop plist)))
- (cdr tp) fruit
- tp fruit)))
+ (cl-loop
+ with tp = (last node)
+ with fruit
+ while plist
+ do (setf
+ fruit (list (cons ; DWR: LtR OoE assumed.
+ (pop plist)
+ (pop plist)))
+ (cdr tp) fruit
+ tp fruit)))
(defun gnugo-close-game (end-time resign)
(gnugo-put :game-end-time end-time)
(let* ((root (gnugo--root-node))
(cur (assq :RE root)))
(when cur
- (assert (not (eq cur (car root))) nil
- ":RE at head of root node: %S"
- root)
+ (cl-assert (not (eq cur (car root))) nil
+ ":RE at head of root node: %S"
+ root)
(delq cur root))))
(defun gnugo-push-move (who move)
;;
;; This linear search loses for multiple ‘old’ w/ "A",
;; a very unusual (but not invalid, sigh) situation.
- (loop
+ (cl-loop
with (bx previous)
for i
;; Start with latest / highest likelihood for hit.
below count
if (setq bx (mod (+ bidx i) count)
previous
- (loop with node
- for m on (aref ends bx)
- while (< tip-move-num
- (gethash (setq node (car m))
- mnum))
- if (eq mem (cdr m))
- return
- (when (equal pair (assq property node))
- m)
- finally return
- nil))
+ (cl-loop
+ with node
+ for m on (aref ends bx)
+ while (< tip-move-num
+ (gethash (setq node (car m))
+ mnum))
+ if (eq mem (cdr m))
+ return (when (equal pair (assq property node))
+ m)
+ finally return nil))
;; yes => follow
return
(progn
(unless (= bidx bx)
- (rotatef (aref ends bidx)
- (aref ends bx)))
+ (cl-rotatef (aref ends bidx)
+ (aref ends bx)))
(setq mem previous))
;; no => construct
finally do
(when (and (not (= color-key (aref new sx)))
(cl-plusp (random 4)))
(aset new sx (aref bg-data sb)))
- (incf sx)
- (incf sb))
+ (cl-incf sx)
+ (cl-incf sb))
(apply 'create-image new 'xpm t
:ascent 'center (when c-symbs
(list :color-symbols
(gnugo-propertize-board-buffer))
;; last move
(when move
- (destructuring-bind (l-ov . r-ov) (gnugo-get :paren-ov)
+ (cl-destructuring-bind (l-ov . r-ov) (gnugo-get :paren-ov)
(if (member move '("PASS" "resign"))
(mapc 'delete-overlay (list l-ov r-ov))
(gnugo-goto-pos move)
(let (acc cut c)
(while (setq cut (string-match "~[bwpmtu]" cur))
(aset cur cut ?%)
- (setq c (aref cur (incf cut)))
+ (setq c (aref cur (cl-incf cut)))
(aset cur cut ?s)
(push
`(,(intern (format "squig-%c" c))
- ,(case c
+ ,(cl-case c
(?b '(or (gnugo-get :black-captures) 0))
(?w '(or (gnugo-get :white-captures) 0))
(?p '(gnugo-current-player))
(let ((old "to play")
(new "waiting for suggestion"))
(when back
- (rotatef old new))
+ (cl-rotatef old new))
(let ((name (buffer-name)))
(when (string-match old name)
(rename-buffer (replace-match new t t name))))))
(full (gnugo-put :get-move-string (concat so-far string))))
(when (string-match "^= \\(.+\\)\n\n" full)
(setq full (match-string 1 full)) ; POS or "PASS"
- (destructuring-bind (color . suggestion)
+ (cl-destructuring-bind (color . suggestion)
(gnugo-get :waiting)
(gnugo--forget :get-move-string
:waiting)
(message "%s %s in group." blurb (length stones))
(setplist (gnugo-f 'anim) nil)
(let* ((spec (if (gnugo-get :display-using-images)
- (loop with yin = (get-text-property (point) 'gnugo-yin)
- with yang = (gnugo-yang (following-char))
- with up = (get (gnugo-yy yin yang t) 'display)
- with dn = (get (gnugo-yy yin yang) 'display)
- for n below (length gnugo-animation-string)
- collect (if (zerop (logand 1 n))
- dn up))
+ (cl-loop
+ with yin = (get-text-property (point) 'gnugo-yin)
+ with yang = (gnugo-yang (following-char))
+ with up = (get (gnugo-yy yin yang t) 'display)
+ with dn = (get (gnugo-yy yin yang) 'display)
+ for n below (length gnugo-animation-string)
+ collect (if (zerop (logand 1 n))
+ dn up))
(split-string gnugo-animation-string "" t)))
(cell (list spec))
(ovs (save-excursion
(when (and (file-exists-p filename)
(not (y-or-n-p "File exists. Continue? ")))
(user-error "Not writing %s" filename))
+ (when (buffer-modified-p)
+ ;; take responsibility for our actions
+ (gnugo--set-root-prop :AP (cons "gnugo.el" gnugo-version)))
(gnugo/sgf-write-file (gnugo-get :sgf-collection) filename)
(gnugo--ok-file filename))
(defun gnugo--dance-dance (karma)
- (destructuring-bind (dance btw)
+ (cl-destructuring-bind (dance btw)
(aref [(moshpit " Zombie")
(classic nil)
(reverse " Zombie Assist") ; "Assist Zombie"? no thanks! :-D
(gnugo--who-is-who wait play samep)))
(defun gnugo--mem-with-played-stone (pos &optional noerror)
- (let ((color (case (following-char)
+ (let ((color (cl-case (following-char)
(?X :B)
(?O :W))))
(if (not color)
(unless noerror
(user-error "No stone at %s" pos))
- (loop with fruit = (cons color (funcall (gnugo--as-cc-func) pos))
- for mem on (aref (gnugo-get :monkey) 0)
- when (equal fruit (caar mem))
- return mem
- finally return nil))))
+ (cl-loop
+ with fruit = (cons color (funcall (gnugo--as-cc-func) pos))
+ for mem on (aref (gnugo-get :monkey) 0)
+ when (equal fruit (caar mem))
+ return mem
+ finally return nil))))
(defun gnugo--climb-towards-root (spec &optional reaction keep)
(gnugo-gate)
(when ulastp
(let ((g (gnugo-get :gnugo-color)))
(cl-flet ((turn () (gnugo--turn-the-wheel t)))
- (case (or reaction gnugo-undo-reaction)
+ (cl-case (or reaction gnugo-undo-reaction)
(play (turn))
(play! (let ((wheel (gnugo-get :wheel)))
- (letf (((cdr wheel) (cons g (cdr wheel))))
+ (cl-letf (((cdr wheel) (cons g (cdr wheel))))
(turn))))
(zombie (gnugo-zombie-mode 1))
(t (gnugo-put :one-shot g)))))))))
(gnugo-put :user-color play)
(gnugo-put :gnugo-color wait)
(gnugo--who-is-who wait play samep)))
- (gnugo--climb-towards-root 1 (case gnugo-undo-reaction
+ (gnugo--climb-towards-root 1 (cl-case gnugo-undo-reaction
(zombie gnugo-undo-reaction)
(t 'one-shot))))
(ucolor (gnugo-get :user-color))
(uprop (gnugo--prop<-color ucolor)))
(cl-flet ((mvno (node) (gethash node mnum)))
- (loop
+ (cl-loop
with ok = (if full
(mvno (car end))
(+ 2 (mvno (car mem))))
todo))))
until (eq mem (cdr ls))
finally do
- (loop
+ (cl-loop
for (userp pos) in todo
do (progn
(gnugo-push-move userp pos)
result (gnugo-query "final_score %d" seed))
(cond ((string= "Chinese" (gnugo--root-prop :RU))
(dolist (group live)
- (incf (if (gnugo--blackp (caar group))
- b-terr
- w-terr)
- (length (cdr group))))
+ (cl-incf (if (gnugo--blackp (caar group))
+ b-terr
+ w-terr)
+ (length (cdr group))))
(dolist (group dead)
- (incf (if (gnugo--blackp (caar group))
- w-terr
- b-terr)
- (length (cdr group))))
+ (cl-incf (if (gnugo--blackp (caar group))
+ w-terr
+ b-terr)
+ (length (cdr group))))
(push (format "%s%d %s = %3.1f\n" b= b-terr terr b-terr) blurb)
(push (format "%s%d %s + %3.1f %s = %3.1f\n" w=
w-terr terr komi 'komi (+ w-terr komi))
blurb))
(t
(dolist (group dead)
- (incf (if (gnugo--blackp (caar group))
- w-terr
- b-terr)
- (* 2 (length (cdr group)))))
+ (cl-incf (if (gnugo--blackp (caar group))
+ w-terr
+ b-terr)
+ (* 2 (length (cdr group)))))
(push (format "%s%d %s + %s %s = %3.1f\n" b=
b-terr terr
b-capt capt
(cl-flet
((yep (pretty moment)
(push (format-time-string
- (concat pretty ": %Y-%m-%d %H:%M:%S %z\n")
+ (concat pretty ": %F %T %z\n")
moment)
blurb)))
(yep "Game start" beg)
(defun gnugo-switch-to-another ()
"Switch to another GNU Go game buffer (if any)."
(interactive)
- (loop for buf in (cdr (buffer-list))
- if (gnugo-board-buffer-p buf)
- return (progn
- (bury-buffer)
- (switch-to-buffer buf))
- finally do (message "(only one)")))
+ (cl-loop
+ for buf in (cdr (buffer-list))
+ if (gnugo-board-buffer-p buf)
+ return (progn
+ (bury-buffer)
+ (switch-to-buffer buf))
+ finally do (message "(only one)")))
(defun gnugo-comment (node comment)
"Add to NODE a COMMENT (string) property.
(define-derived-mode gnugo-board-mode special-mode "GNUGO Board"
"Major mode for playing GNU Go.
Entering this mode runs the normal hook `gnugo-board-mode-hook'.
-In this mode, keys do not self insert.
-
-\\{gnugo-board-mode-map}"
+In this mode, keys do not self insert."
(buffer-disable-undo) ; todo: undo undo undoing
(setq font-lock-defaults '(gnugo-font-lock-keywords t)
truncate-lines t)
(gnugo-board-mode)
(let* ((filename nil)
(user-color "black")
- (args (loop
+ (args (cl-loop
with ls = (split-string
;; todo: grok ‘gnugo --help’; completion
(read-string
(when (and (zerop handicap) actually)
(setq handicap (string-to-number (cadr actually)))))
(r! :SZ board-size
- :DT (format-time-string "%Y-%m-%d")
+ :DT (format-time-string "%F")
:RU (if (member "--chinese-rules" args)
"Chinese"
"Japanese")
- :AP (cons "gnugo.el" gnugo-version)
:KM komi)
(let ((ub (gnugo--blackp user-color)))
(r! (if ub :PW :PB) (concat "GNU Go " (gnugo-query "version"))
;;;---------------------------------------------------------------------------
;;; Load-time actions
-(unless gnugo-board-mode-map
- (setq gnugo-board-mode-map (make-sparse-keymap))
- (suppress-keymap gnugo-board-mode-map)
- (mapc (lambda (pair)
- (define-key gnugo-board-mode-map (car pair) (cdr pair)))
- '(("?" . describe-mode)
- ("S" . gnugo-request-suggestion)
- ("\C-m" . gnugo-move)
- (" " . gnugo-move)
- ("P" . gnugo-pass)
- ("R" . gnugo-resign)
- ("q" . gnugo-quit)
- ("Q" . gnugo-leave-me-alone)
- ("U" . gnugo-fancy-undo)
- ("\M-u" . gnugo-undo-one-move)
- ("u" . gnugo-undo-two-moves)
- ("\C-?" . gnugo-undo-two-moves)
- ("o" . gnugo-oops)
- ("O" . gnugo-okay)
- ("\C-l" . gnugo-refresh)
- ("\M-_" . gnugo-boss-is-near)
- ("_" . gnugo-boss-is-near)
- ("h" . gnugo-move-history)
- ("L" . gnugo-frolic-in-the-leaves)
- ("\C-c\C-l" . gnugo-frolic-in-the-leaves)
- ("i" . gnugo-image-display-mode)
- ("w" . gnugo-worm-stones)
- ("W" . gnugo-worm-data)
- ("d" . gnugo-dragon-stones)
- ("D" . gnugo-dragon-data)
- ("g" . gnugo-grid-mode)
- ("!" . gnugo-estimate-score)
- (":" . gnugo-command)
- (";" . gnugo-command)
- ("=" . gnugo-describe-position)
- ("s" . gnugo-write-sgf-file)
- ("\C-x\C-s" . gnugo-write-sgf-file)
- ("\C-x\C-w" . gnugo-write-sgf-file)
- ("l" . gnugo-read-sgf-file)
- ("F" . gnugo-display-final-score)
- ("A" . gnugo-switch-to-another)
- ("C" . gnugo-comment)
- ("\C-c\C-a" . gnugo-assist-mode)
- ("\C-c\C-z" . gnugo-zombie-mode)
- ;; mouse
- ([(down-mouse-1)] . gnugo-mouse-move)
- ([(down-mouse-2)] . gnugo-mouse-move) ; mitigate accidents
- ([(down-mouse-3)] . gnugo-mouse-pass)
- ;; delving into the curiosities
- ("\C-c\C-p" . gnugo-describe-internal-properties))))
-
(unless (get 'help :gnugo-gtp-command-spec)
(cl-flet*
((sget (x) (get x :gnugo-gtp-command-spec))
(plist-put (sget cmd) prop val)))
(validpos (s &optional go)
(let ((pos (upcase s)))
- (loop with size = (gnugo-get :SZ)
- for c across (funcall (gnugo--as-cc-func)
- pos)
- do (let ((norm (- c ?a)))
- (unless (and (< -1 norm)
- (> size norm))
- (user-error "Invalid position: %s"
- pos))))
+ (cl-loop
+ with size = (gnugo-get :SZ)
+ for c across (funcall (gnugo--as-cc-func)
+ pos)
+ do (let ((norm (- c ?a)))
+ (unless (and (< -1 norm)
+ (> size norm))
+ (user-error "Invalid position: %s"
+ pos))))
(when go
(gnugo-goto-pos pos))
pos))
(goto-char (point-min))
(save-excursion
(while (re-search-forward "^ *[*] \\([a-zA-Z_]+\\)\\(:.*\\)*\n"
- (point-max) t)
+ nil t)
(unless pad
(setq pad (make-string (- (match-beginning 1)
(match-beginning 0))
(when (setq output (plist-get spec :output))
(if (functionp output)
(note "handles the output specially")
- (case output
+ (cl-case output
(:discard (note "discards the output"))
(:message (note "displays the output in the echo area")))))
(when (eq sel cur)
(specs (or (get 'gnugo/sgf-*r4-properties* :specs)
(put 'gnugo/sgf-*r4-properties* :specs
(mapcar (lambda (full)
- (cons (car full) (cdddr full)))
+ (cons (car full) (cl-cdddr full)))
gnugo/sgf-*r4-properties*))))
SZ)
(cl-labels
((sw () (skip-chars-forward " \t\n"))
(x (end preserve-whitespace)
(let ((beg (point))
- (endp (case end
+ (endp (cl-case end
(:end (lambda (char) (= ?\] char)))
(:mid (lambda (char) (= ?\: char)))
(t (lambda (char) (or (= ?\: char)
(one (type end) (let ((s (progn
(forward-char 1)
(x end (eq 'text type)))))
- (case type
+ (cl-case type
((stone point move)
;; blech, begone bu"tt"-ugly blatherings
;; (but bide brobdingnagian boards)...
;; probably this assumption is consistent
;; w/ the SGF authors' desire to make the
;; parsing easy, but you never know...
- (cons v (one (cdaddr spec) :end)))))
+ (cons v (one (cl-cdaddr spec) :end)))))
(t (cons (one (car spec) :mid)
(one (cdr spec) :end)))))
(short (who) (when (eobp)
(forward-char 1)
t))
(NODE () (when (seek-into ?\;)
- (loop with prop
- while (setq prop (PROP))
- collect (progn
- (when (eq :SZ (car prop))
- (setq SZ (cdr prop)))
- prop))))
+ (cl-loop
+ with prop
+ while (setq prop (PROP))
+ collect (progn
+ (when (eq :SZ (car prop))
+ (setq SZ (cdr prop)))
+ prop))))
(TREE (parent mnum)
(let ((ls parent)
prev node)
;; singular
(list ls)
;; multiple
- (loop while (seek ?\()
- append (TREE ls mnum)))
+ (cl-loop
+ while (seek ?\()
+ append (TREE ls mnum)))
(seek-into ?\))))))
(with-temp-buffer
(if (not data-p)
(insert-file-contents file-or-data)
(insert file-or-data)
(goto-char (point-min)))
- (loop while (morep)
- collect (let* ((mnum (gnugo--mkht :weakness 'key))
- (ends (TREE nil mnum))
- (root (car (last (car ends)))))
- (vector (apply 'vector ends)
- mnum
- root)))))))
+ (cl-loop
+ while (morep)
+ collect (let* ((mnum (gnugo--mkht :weakness 'key))
+ (ends (TREE nil mnum))
+ (root (car (last (car ends)))))
+ (vector (apply 'vector ends)
+ mnum
+ root)))))))
(defun gnugo/sgf-write-file (collection filename)
(let ((aft-newline-appreciated '(:AP :GN :PB :PW :HA :KM :RU :RE))
- (me (cons "gnugo.el" gnugo-version))
(specs (mapcar (lambda (full)
(cons (intern (format ":%s" (car full)))
- (cdddr full)))
+ (cl-cdddr full)))
gnugo/sgf-*r4-properties*))
p name v spec)
(cl-labels
((esc (composed fmt arg)
(mapconcat (lambda (c)
- (case c
+ (cl-case c
;; ‘?\[’ is not strictly required
;; but neither is it forbidden.
((?\[ ?\] ?\\) (format "\\%c" c))
(t
(>>one v) (>>nl))))
(>>node (node)
- (loop initially (insert ";")
- for prop in node
- do (>>prop prop)))
+ (cl-loop
+ initially (insert ";")
+ for prop in node
+ do (>>prop prop)))
(>>tree (tree)
(unless (zerop (current-column))
(newline))
(insert ")")))
(with-temp-buffer
(dolist (tree collection)
- ;; take responsibility for our actions
- (gnugo--set-root-prop :AP me tree)
;; write it out
(let ((ht (gnugo--mkht))
(leaves (append (gnugo--tree-ends tree) nil)))
(cl-flet
((hang (stack)
- (loop
+ (cl-loop
with rh ; rectified history
with bp ; branch point
for node in stack