;;; xiangqi.el --- Xiangqi mode ;; cursor movement is "borrowed" from gomoku.el ;-). ;; more documentation later. ;; send suggestions, bugs reports to deng@ifcss.org ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; (global-set-key "\C-x\C-x" 'xiangqi-minor-mode) (autoload 'xiangqi-minor-mode "xiangqi" "xq" t) ;;; (defvar xiangqi-minor-mode-keymap nil "Local key map for xiangqi-minor-mode.") (defvar xiangqi-minor-mode nil "Xiangqi-minor-mode toggle.") (defvar xiangqi-minor-mode-string nil "Xiangqi-minor-mode-string.") (if xiangqi-minor-mode-keymap () (setq xiangqi-minor-mode-keymap (make-keymap)) (define-key xiangqi-minor-mode-keymap "u" 'xiangqi-move-nw) ; Y (define-key xiangqi-minor-mode-keymap "o" 'xiangqi-move-ne) ; U (define-key xiangqi-minor-mode-keymap "n" 'xiangqi-move-sw) ; B (define-key xiangqi-minor-mode-keymap "m" 'xiangqi-move-se) ; N (define-key xiangqi-minor-mode-keymap "j" 'xiangqi-move-left) ; H (define-key xiangqi-minor-mode-keymap "l" 'xiangqi-move-right) ; L (define-key xiangqi-minor-mode-keymap "k" 'xiangqi-move-down) ; J (define-key xiangqi-minor-mode-keymap "i" 'xiangqi-move-up) ; K (define-key xiangqi-minor-mode-keymap "\C-c\C-n" 'xiangqi-move-down) ; C-N (define-key xiangqi-minor-mode-keymap "\C-c\C-p" 'xiangqi-move-up) ; C-P (define-key xiangqi-minor-mode-keymap "\C-c\C-f" 'xiangqi-move-right) ; C-F (define-key xiangqi-minor-mode-keymap "\C-c\C-b" 'xiangqi-move-left) ; C-B (define-key xiangqi-minor-mode-keymap "\C-c\C-l" 'xiangqi-blank-board) (define-key xiangqi-minor-mode-keymap "\C-c\C-u" 'xiangqi-full-board) (define-key xiangqi-minor-mode-keymap "\C-c+" 'xiangqi-plus); (define-key xiangqi-minor-mode-keymap "\C-cI" 'xiangqi-SHUAI); (define-key xiangqi-minor-mode-keymap "\C-cS" 'xiangqi-SHI); (define-key xiangqi-minor-mode-keymap "\C-cX" 'xiangqi-XIANG); (define-key xiangqi-minor-mode-keymap "\C-cM" 'xiangqi-MA); (define-key xiangqi-minor-mode-keymap "\C-cJ" 'xiangqi-JU); (define-key xiangqi-minor-mode-keymap "\C-cP" 'xiangqi-PAO); (define-key xiangqi-minor-mode-keymap "\C-cB" 'xiangqi-BING); (define-key xiangqi-minor-mode-keymap "\C-ci" 'xiangqi-jiang); (define-key xiangqi-minor-mode-keymap "\C-cs" 'xiangqi-shi); (define-key xiangqi-minor-mode-keymap "\C-cx" 'xiangqi-xiang); (define-key xiangqi-minor-mode-keymap "\C-cm" 'xiangqi-ma); (define-key xiangqi-minor-mode-keymap "\C-cj" 'xiangqi-ju); (define-key xiangqi-minor-mode-keymap "\C-cp" 'xiangqi-pao); (define-key xiangqi-minor-mode-keymap "\C-cz" 'xiangqi-zu); );;end (defun xiangqi-minor-mode () "A minor mode to edit end games or whatever in the buffer. Commands: Most cursor movement commands. Use \\[xiangqi-minor-mode-help] to get help. " (interactive) (cond (xiangqi-minor-mode (use-local-map xiangqi-minor-previous-local-map) (if buffer-read-only (toggle-read-only)) (setq xiangqi-minor-mode nil) (set-buffer-modified-p (buffer-modified-p))) (t (if (not (assq 'xiangqi-minor-mode minor-mode-alist)) (setq minor-mode-alist (cons '(xiangqi-minor-mode xiangqi-minor-mode-string) minor-mode-alist))) (mapcar 'make-variable-buffer-local '(xiangqi-minor-previous-local-map xiangqi-minor-mode xiangqi-minor-keymap xiangqi-minor-mode-string)) (setq xiangqi-minor-previous-local-map (current-local-map)) (setq xiangqi-minor-mode-string " XiangQi") (setq xiangqi-minor-mode t) (message (substitute-command-keys "\\[xiangqi-minor-mode-help] for help.")) (use-local-map xiangqi-minor-mode-keymap) (toggle-read-only) (set-buffer-modified-p (buffer-modified-p))))) (defun xiangqi-minor-mode-help () "To get help for xiangqi-minor-mode. \\[xiangqi-minor-mode-help]." (interactive) (describe-function 'xiangqi-minor-mode) ) (defvar xiangqi-board-width 10 "Number of columns on the Xiangqi board.") (defvar xiangqi-board-height 11 "Number of lines on the Xiangqi board.") (defconst xiangqi-square-width 4 "*Horizontal spacing between squares on the Xiangqi board.") (defconst xiangqi-square-height 2 "*Vertical spacing between squares on the Xiangqi board.") (defconst xiangqi-x-offset 3 "*Number of columns between the Xiangqi board and the side of the window.") (defconst xiangqi-y-offset 1 "*Number of lines between the Xiangqi board and the top of the window.") (defun xiangqi-max-width () "Largest possible board width for the current window." (1+ (/ (- (window-width (selected-window)) xiangqi-x-offset xiangqi-x-offset 1) xiangqi-square-width))) (defun xiangqi-point-x () "Return the board column where point is, or nil if it is not a board column." (let ((col (- (current-column) xiangqi-x-offset))) (if (and (>= col 0) (zerop (% col xiangqi-square-width)) (<= (setq col (1+ (/ col xiangqi-square-width))) xiangqi-board-width)) col))) (defun xiangqi-point-y () "Return the board row where point is, or nil if it is not a board row." (let ((row (- (count-lines 1 (point)) xiangqi-y-offset 1))) (if (and (>= row 0) (zerop (% row xiangqi-square-height)) (<= (setq row (1+ (/ row xiangqi-square-height))) xiangqi-board-height)) row))) ;;; ;;; xiangqi board ;;; (defun xiangqi-blank-board () "Draw a blank Xiangqi board" (interactive) (if buffer-read-only (toggle-read-only)) (let ((row (% (count-lines 1 (point)) 2))) (if (= row 0)(next-line 1)) (beginning-of-line) (insert " 1 2 3 4 5 6 7 8 9 \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | \\ | / | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | / | \\ | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | | | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | | | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | | | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | | | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | \\ | / | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | / | \\ | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " 9 8 7 6 5 4 3 2 1 \n") (previous-line 20) (beginning-of-line) (forward-char 3) (toggle-read-only) )) (defun xiangqi-full-board () "Draw a blank Xiangqi board plus initial pieces" (interactive) (if buffer-read-only (toggle-read-only)) (let ((row (% (count-lines 1 (point)) 2))) (if (= row 0) (next-line 1)) (beginning-of-line) (insert " 1 2 3 4 5 6 7 8 9 \n") (insert " (j)-(m)-(x)-(s)-(i)-(s)-(x)-(m)-(j) \n") (insert " | | | | \\ | / | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | / | \\ | | | | \n") (insert " +--(p)--+---+---+---+---+--(p)--+ \n") (insert " | | | | | | | | | \n") (insert " (z)--+--(z)--+--(z)--+--(z)--+--(z) \n") (insert " | | | | | | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | | | | | | \n") (insert " (B)--+--(B)--+--(B)--+--(B)--+--(B) \n") (insert " | | | | | | | | | \n") (insert " +--(P)--+---+---+---+---+--(P)--+ \n") (insert " | | | | \\ | / | | | | \n") (insert " +---+---+---+---+---+---+---+---+ \n") (insert " | | | | / | \\ | | | | \n") (insert " (J)-(M)-(X)-(S)-(I)-(S)-(X)-(M)-(J) \n") (insert " 9 8 7 6 5 4 3 2 1 \n") (previous-line 20) (beginning-of-line) (forward-char 3) (toggle-read-only) )) ;;; ;;; insert ;;; (defun xiangqi-plus () "Draw + on the Xiangqi board." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (backward-char 2) (cond ((looking-at "-") (forward-char 1) (delete-char 3) (insert "-+-")) ((looking-at " ") (forward-char 1) (delete-char 3) (insert " +-")) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-jiang () "Draw jiang (i) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(i)") (delete-char 2)) (forward-char 2) (t (message "Bad QiZi position!")))) (toggle-read-only) ) (defun xiangqi-shi () "Draw shi (s) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(s)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-xiang () "Draw xiang (x) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(x)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-ma () "Draw ma (m) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(m)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-ju () "Draw ju (j) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(j)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-pao () "Draw pao (p) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(p)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-zu () "Draw zu (z) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(z)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-SHUAI () "Draw SHUAI (I) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(I)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-SHI () "Draw SHI (S) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(S)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-XIANG () "Draw XIANG (X) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(X)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-MA () "Draw MA (M) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(M)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-JU () "Draw JU (J) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(J)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-PAO () "Draw PAO (P) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(P)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) (defun xiangqi-BING () "Draw BING (B) on the Xiangqi screen." (interactive) (if buffer-read-only (toggle-read-only)) (save-excursion (cond ((looking-at "+") (backward-char 1) (delete-char 1) (insert "(B)") (delete-char 2)) (t (message "Bad QiZi position!")))) (forward-char 1) (toggle-read-only) ) ;;; ;;; CURSOR MOTION. ;;; (defun xiangqi-move-left () "Move point backward one column on the Xiangqi board." (interactive) (let ((x (xiangqi-point-x))) (backward-char (cond ((null x) 1) ((> x 1) xiangqi-square-width) (t 0))))) (defun xiangqi-move-right () "Move point forward one column on the Xiangqi board." (interactive) (let ((x (xiangqi-point-x))) (forward-char (cond ((null x) 1) ((< x xiangqi-board-width) xiangqi-square-width) (t 0))))) (defun xiangqi-move-down () "Move point down one row on the Xiangqi board." (interactive) (next-line 2) ) (defun xiangqi-move-up () "Move point up one row on the Xiangqi board." (interactive) (previous-line 2) ) (defun xiangqi-move-ne () "Move point North East on the Xiangqi board." (interactive) (xiangqi-move-up) (xiangqi-move-right)) (defun xiangqi-move-se () "Move point South East on the Xiangqi board." (interactive) (xiangqi-move-down) (xiangqi-move-right)) (defun xiangqi-move-nw () "Move point North West on the Xiangqi board." (interactive) (xiangqi-move-up) (xiangqi-move-left)) (defun xiangqi-move-sw () "Move point South West on the Xiangqi board." (interactive) (xiangqi-move-down) (xiangqi-move-left)) (provide 'xiangqi) ;;; xiangqi.el ends here