aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1996-03-22 20:43:05 +0000
committerRichard M. Stallman1996-03-22 20:43:05 +0000
commitf5ecf0c90362f451a86d6127366cf950c724b95b (patch)
treecc66a318489dd5b894020d383d6ba32c560415ec
parent8dc7496c3f472a54d652c0725e2c015353c35bac (diff)
downloademacs-f5ecf0c90362f451a86d6127366cf950c724b95b.tar.gz
emacs-f5ecf0c90362f451a86d6127366cf950c724b95b.zip
Ancient leading comment removed.
(gomoku-mode-map): Added numeric keypad for 8 directions, changed comments to lowercase (C-c rather than C-C), added SPC to play and undo's binding to go back. (gomoku-emacs-won, gomoku-font-lock-O-face, gomoku-font-lock-X-face) (gomoku-font-lock-keywords): New variables. (gomoku-mode): Use it and make buffer read-only for user. (gomoku-terminate-game): Remove (ding) -- maybe should be optonal. (gomoku-init-display): Rewritten, makes fields intangible so you can't go in between. Make free fields have mouse-face. (gomoku-cross-qtuple): Take account of intangible text, and that empty lines are now really empty. (gomoku-move-left, gomoku-move-right): Removed thanks to intangibility. (gomoku-move-ne, -se, -nw, -sw): Use normal left / right motion.
-rw-r--r--lisp/play/gomoku.el228
1 files changed, 128 insertions, 100 deletions
diff --git a/lisp/play/gomoku.el b/lisp/play/gomoku.el
index b7d6bea0ac3..48429a3110f 100644
--- a/lisp/play/gomoku.el
+++ b/lisp/play/gomoku.el
@@ -1,6 +1,6 @@
1;;; gomoku.el --- Gomoku game between you and Emacs 1;;; gomoku.el --- Gomoku game between you and Emacs
2 2
3;; Copyright (C) 1988, 1994 Free Software Foundation, Inc. 3;; Copyright (C) 1988, 1994, 1996 Free Software Foundation, Inc.
4 4
5;; Author: Philippe Schnoebelen <phs@lifia.imag.fr> 5;; Author: Philippe Schnoebelen <phs@lifia.imag.fr>
6;; Adapted-By: ESR 6;; Adapted-By: ESR
@@ -25,12 +25,6 @@
25 25
26;;; Commentary: 26;;; Commentary:
27 27
28;; Gomoku game between you and GNU Emacs. Last modified on 13 Sep 1988
29;;
30;; Written by Ph. Schnoebelen (phs@lifia.imag.fr), 1987, 1988
31;; with precious advices from J.-F. Rit.
32;; This has been tested with GNU Emacs 18.50.
33
34;; RULES: 28;; RULES:
35;; 29;;
36;; Gomoku is a game played between two players on a rectangular board. Each 30;; Gomoku is a game played between two players on a rectangular board. Each
@@ -84,38 +78,75 @@
84(if gomoku-mode-map nil 78(if gomoku-mode-map nil
85 (setq gomoku-mode-map (make-sparse-keymap)) 79 (setq gomoku-mode-map (make-sparse-keymap))
86 80
87 ;; Key bindings for cursor motion. Arrow keys are just "function" 81 ;; Key bindings for cursor motion.
88 ;; keys, see below. 82 (define-key gomoku-mode-map "y" 'gomoku-move-nw) ; y
89 (define-key gomoku-mode-map "y" 'gomoku-move-nw) ; Y 83 (define-key gomoku-mode-map "u" 'gomoku-move-ne) ; u
90 (define-key gomoku-mode-map "u" 'gomoku-move-ne) ; U 84 (define-key gomoku-mode-map "b" 'gomoku-move-sw) ; b
91 (define-key gomoku-mode-map "b" 'gomoku-move-sw) ; B 85 (define-key gomoku-mode-map "n" 'gomoku-move-se) ; n
92 (define-key gomoku-mode-map "n" 'gomoku-move-se) ; N 86 (define-key gomoku-mode-map "h" 'backward-char) ; h
93 (define-key gomoku-mode-map "h" 'gomoku-move-left) ; H 87 (define-key gomoku-mode-map "l" 'forward-char) ; l
94 (define-key gomoku-mode-map "l" 'gomoku-move-right) ; L 88 (define-key gomoku-mode-map "j" 'gomoku-move-down) ; j
95 (define-key gomoku-mode-map "j" 'gomoku-move-down) ; J 89 (define-key gomoku-mode-map "k" 'gomoku-move-up) ; k
96 (define-key gomoku-mode-map "k" 'gomoku-move-up) ; K 90
97 (define-key gomoku-mode-map "\C-n" 'gomoku-move-down) ; C-N 91 (define-key gomoku-mode-map [kp-7] 'gomoku-move-nw)
98 (define-key gomoku-mode-map "\C-p" 'gomoku-move-up) ; C-P 92 (define-key gomoku-mode-map [kp-9] 'gomoku-move-ne)
99 (define-key gomoku-mode-map "\C-f" 'gomoku-move-right) ; C-F 93 (define-key gomoku-mode-map [kp-1] 'gomoku-move-sw)
100 (define-key gomoku-mode-map "\C-b" 'gomoku-move-left) ; C-B 94 (define-key gomoku-mode-map [kp-3] 'gomoku-move-se)
95 (define-key gomoku-mode-map [kp-4] 'backward-char)
96 (define-key gomoku-mode-map [kp-6] 'forward-char)
97 (define-key gomoku-mode-map [kp-2] 'gomoku-move-down)
98 (define-key gomoku-mode-map [kp-8] 'gomoku-move-up)
99
100 (define-key gomoku-mode-map "\C-n" 'gomoku-move-down) ; C-n
101 (define-key gomoku-mode-map "\C-p" 'gomoku-move-up) ; C-p
101 102
102 ;; Key bindings for entering Human moves. 103 ;; Key bindings for entering Human moves.
103 ;; If you have a mouse, you may also bind some mouse click ... 104 ;; If you have a mouse, you may also bind some mouse click ...
104 (define-key gomoku-mode-map "X" 'gomoku-human-plays) ; X 105 (define-key gomoku-mode-map "X" 'gomoku-human-plays) ; X
105 (define-key gomoku-mode-map "x" 'gomoku-human-plays) ; x 106 (define-key gomoku-mode-map "x" 'gomoku-human-plays) ; x
107 (define-key gomoku-mode-map " " 'gomoku-human-plays) ; RET
106 (define-key gomoku-mode-map "\C-m" 'gomoku-human-plays) ; RET 108 (define-key gomoku-mode-map "\C-m" 'gomoku-human-plays) ; RET
107 (define-key gomoku-mode-map "\C-c\C-p" 'gomoku-human-plays) ; C-C C-P 109 (define-key gomoku-mode-map "\C-c\C-p" 'gomoku-human-plays) ; C-c C-p
108 (define-key gomoku-mode-map "\C-c\C-b" 'gomoku-human-takes-back) ; C-C C-B 110 (define-key gomoku-mode-map "\C-c\C-b" 'gomoku-human-takes-back) ; C-c C-b
109 (define-key gomoku-mode-map "\C-c\C-r" 'gomoku-human-resigns) ; C-C C-R 111 (define-key gomoku-mode-map "\C-c\C-r" 'gomoku-human-resigns) ; C-c C-r
110 (define-key gomoku-mode-map "\C-c\C-e" 'gomoku-emacs-plays) ; C-C C-E 112 (define-key gomoku-mode-map "\C-c\C-e" 'gomoku-emacs-plays) ; C-c C-e
111 113
112 (define-key gomoku-mode-map [up] 'gomoku-move-up)
113 (define-key gomoku-mode-map [down] 'gomoku-move-down)
114 (define-key gomoku-mode-map [left] 'gomoku-move-left)
115 (define-key gomoku-mode-map [right] 'gomoku-move-right)
116 (define-key gomoku-mode-map [kp-enter] 'gomoku-human-plays) 114 (define-key gomoku-mode-map [kp-enter] 'gomoku-human-plays)
117 (define-key gomoku-mode-map [mouse-2] 'gomoku-click) 115 (define-key gomoku-mode-map [mouse-2] 'gomoku-click)
118 (define-key gomoku-mode-map [insert] 'gomoku-human-plays)) 116 (define-key gomoku-mode-map [insert] 'gomoku-human-plays)
117
118 (substitute-key-definition 'previous-line 'gomoku-move-up
119 gomoku-mode-map (current-global-map))
120 (substitute-key-definition 'next-line 'gomoku-move-down
121 gomoku-mode-map (current-global-map))
122 (substitute-key-definition 'undo 'gomoku-human-takes-back
123 gomoku-mode-map (current-global-map))
124 (substitute-key-definition 'advertised-undo 'gomoku-human-takes-back
125 gomoku-mode-map (current-global-map)))
126
127(defvar gomoku-emacs-won ()
128 "*For making font-lock use the winner's face for the line.")
129
130(defvar gomoku-font-lock-O-face
131 (if window-system
132 (list (facemenu-get-face 'fg:red) 'bold))
133 "*Face to use for Emacs' O.")
134
135(defvar gomoku-font-lock-X-face
136 (if window-system
137 (list (facemenu-get-face 'fg:green) 'bold))
138 "*Face to use for your X.")
139
140(defvar gomoku-font-lock-keywords
141 '(("O" . gomoku-font-lock-O-face)
142 ("X" . gomoku-font-lock-X-face)
143 ("[-|/\\]" 0 (if gomoku-emacs-won
144 gomoku-font-lock-O-face
145 gomoku-font-lock-X-face)))
146 "*Font lock rules for Gomoku.")
147
148(put 'gomoku-mode 'front-sticky
149 (put 'gomoku-mode 'rear-nonsticky '(intangible)))
119 150
120(defun gomoku-mode () 151(defun gomoku-mode ()
121 "Major mode for playing Gomoku against Emacs. 152 "Major mode for playing Gomoku against Emacs.
@@ -128,12 +159,15 @@ You play by moving the cursor over the square you choose and hitting \\[gomoku-h
128Other useful commands: 159Other useful commands:
129\\{gomoku-mode-map} 160\\{gomoku-mode-map}
130Entry to this mode calls the value of `gomoku-mode-hook' if that value 161Entry to this mode calls the value of `gomoku-mode-hook' if that value
131is non-nil." 162is non-nil. One interesting value is `turn-on-font-lock'."
132 (interactive) 163 (interactive)
133 (setq major-mode 'gomoku-mode 164 (setq major-mode 'gomoku-mode
134 mode-name "Gomoku") 165 mode-name "Gomoku")
135 (gomoku-display-statistics) 166 (gomoku-display-statistics)
136 (use-local-map gomoku-mode-map) 167 (use-local-map gomoku-mode-map)
168 (make-local-variable 'font-lock-defaults)
169 (setq font-lock-defaults '(gomoku-font-lock-keywords t))
170 (toggle-read-only t)
137 (run-hooks 'gomoku-mode-hook)) 171 (run-hooks 'gomoku-mode-hook))
138 172
139;;; 173;;;
@@ -531,7 +565,8 @@ that DVAL has been added on SQUARE."
531 gomoku-board-height m 565 gomoku-board-height m
532 gomoku-vector-length (1+ (* (+ m 2) (1+ n))) 566 gomoku-vector-length (1+ (* (+ m 2) (1+ n)))
533 gomoku-draw-limit (/ (* 7 n m) 10)) 567 gomoku-draw-limit (/ (* 7 n m) 10))
534 (setq gomoku-game-history nil 568 (setq gomoku-emacs-won nil
569 gomoku-game-history nil
535 gomoku-number-of-moves 0 570 gomoku-number-of-moves 0
536 gomoku-number-of-human-moves 0 571 gomoku-number-of-human-moves 0
537 gomoku-emacs-played-first nil 572 gomoku-emacs-played-first nil
@@ -650,7 +685,7 @@ that DVAL has been added on SQUARE."
650 685
651 (gomoku-display-statistics) 686 (gomoku-display-statistics)
652 (if message (message message)) 687 (if message (message message))
653 (ding) 688 ;;(ding)
654 (setq gomoku-game-in-progress nil))) 689 (setq gomoku-game-in-progress nil)))
655 690
656(defun gomoku-crash-game () 691(defun gomoku-crash-game ()
@@ -728,6 +763,7 @@ Use \\[describe-mode] for more info."
728 (gomoku-play-move square 6) 763 (gomoku-play-move square 6)
729 (cond ((>= score gomoku-winning-threshold) 764 (cond ((>= score gomoku-winning-threshold)
730 (gomoku-find-filled-qtuple square 6) 765 (gomoku-find-filled-qtuple square 6)
766 (setq gomoku-emacs-won t) ; for font-lock
731 (gomoku-cross-winning-qtuple) 767 (gomoku-cross-winning-qtuple)
732 (gomoku-terminate-game 'emacs-won)) 768 (gomoku-terminate-game 'emacs-won))
733 ((zerop score) 769 ((zerop score)
@@ -918,41 +954,44 @@ If the game is finished, this command requests for another game."
918 954
919(defun gomoku-put-char (char) 955(defun gomoku-put-char (char)
920 "Draw CHAR on the Gomoku screen." 956 "Draw CHAR on the Gomoku screen."
921 (let ((inhibit-read-only t)) 957 (let ((inhibit-read-only t)
922 (insert char) 958 (inhibit-point-motion-hooks t))
959 (insert-and-inherit char)
960 (and window-system
961 (eq char ?.)
962 (put-text-property (1- (point)) (point) 'mouse-face 'highlight))
923 (delete-char 1) 963 (delete-char 1)
924 (backward-char 1))) 964 (backward-char 1)))
925 965
926(defun gomoku-init-display (n m) 966(defun gomoku-init-display (n m)
927 "Display an N by M Gomoku board." 967 "Display an N by M Gomoku board."
928 (buffer-disable-undo (current-buffer)) 968 (buffer-disable-undo (current-buffer))
929 (let ((inhibit-read-only t)) 969 (let ((inhibit-read-only t)
970 (string1 (make-string gomoku-x-offset ? ))
971 (string2 (make-string (1- gomoku-square-width) ? ))
972 (point 1)
973 (i m) j)
930 (erase-buffer) 974 (erase-buffer)
931 (let (string1 string2 string3 string4) 975 ;; We do not use gomoku-plot-square which would be too slow for
932 ;; We do not use gomoku-plot-square which would be too slow for 976 ;; initializing the display.
933 ;; initializing the display. Rather we build STRING1 for lines where 977 (newline gomoku-y-offset)
934 ;; board squares are to be found, and STRING2 for empty lines. STRING1 is 978 (while (progn
935 ;; like STRING2 except for dots every DX squares. Empty lines are filled 979 (indent-to gomoku-x-offset)
936 ;; with spaces so that cursor moving up and down remains on the same 980 (setq j n)
937 ;; column. 981 (while (progn
938 (setq string1 (concat (make-string (1- gomoku-square-width) ? ) ".") 982 (put-text-property point (point) 'category 'gomoku-mode)
939 string1 (apply 'concat 983 (put-text-property point (point) 'intangible (point))
940 (make-list (1- n) string1)) 984 (setq point (point))
941 string1 (concat (make-string gomoku-x-offset ? ) "." string1 "\n") 985 (insert ?.)
942 string2 (make-string (+ 1 gomoku-x-offset 986 (if window-system
943 (* (1- n) gomoku-square-width)) 987 (put-text-property point (point)
944 ? ) 988 'mouse-face 'highlight))
945 string2 (concat string2 "\n") 989 (> (setq j (1- j)) 0))
946 string3 (apply 'concat 990 (insert string2))
947 (make-list (1- gomoku-square-height) string2)) 991 (> (setq i (1- i)) 0))
948 string3 (concat string3 string1) 992 (insert-char ?\n gomoku-square-height))
949 string3 (apply 'concat 993 (gomoku-goto-xy (/ (1+ n) 2) (/ (1+ m) 2))) ; center of the board
950 (make-list (1- m) string3)) 994 (sit-for 0)) ; Display NOW
951 string4 (apply 'concat
952 (make-list gomoku-y-offset string2)))
953 (insert string4 string1 string3))
954 (gomoku-goto-xy (/ (1+ n) 2) (/ (1+ m) 2)) ; center of the board
955 (sit-for 0))) ; Display NOW
956 995
957(defun gomoku-display-statistics () 996(defun gomoku-display-statistics ()
958 "Obnoxiously display some statistics about previous games in mode line." 997 "Obnoxiously display some statistics about previous games in mode line."
@@ -1042,53 +1081,42 @@ If the game is finished, this command requests for another game."
1042(defun gomoku-cross-qtuple (square1 square2 dx dy) 1081(defun gomoku-cross-qtuple (square1 square2 dx dy)
1043 "Cross every square between SQUARE1 and SQUARE2 in the DX, DY direction." 1082 "Cross every square between SQUARE1 and SQUARE2 in the DX, DY direction."
1044 (save-excursion ; Not moving point from last square 1083 (save-excursion ; Not moving point from last square
1045 (let ((depl (gomoku-xy-to-index dx dy))) 1084 (let ((depl (gomoku-xy-to-index dx dy))
1085 (inhibit-read-only t)
1086 (inhibit-point-motion-hooks t))
1046 ;; WARNING: this function assumes DEPL > 0 and SQUARE2 > SQUARE1 1087 ;; WARNING: this function assumes DEPL > 0 and SQUARE2 > SQUARE1
1047 (while (not (= square1 square2)) 1088 (while (/= square1 square2)
1048 (gomoku-goto-square square1) 1089 (gomoku-goto-square square1)
1049 (setq square1 (+ square1 depl)) 1090 (setq square1 (+ square1 depl))
1050 (cond 1091 (cond
1051 ((and (= dx 1) (= dy 0)) ; Horizontal 1092 ((= dy 0) ; Horizontal
1052 (let ((n 1)) 1093 (forward-char 1)
1053 (while (< n gomoku-square-width) 1094 (insert-char ?- (1- gomoku-square-width) t)
1054 (setq n (1+ n)) 1095 (delete-char (1- gomoku-square-width)))
1055 (forward-char 1) 1096 ((= dx 0) ; Vertical
1056 (gomoku-put-char ?-)))) 1097 (let ((n 1)
1057 ((and (= dx 0) (= dy 1)) ; Vertical 1098 (column (current-column)))
1058 (let ((n 1))
1059 (while (< n gomoku-square-height) 1099 (while (< n gomoku-square-height)
1060 (setq n (1+ n)) 1100 (setq n (1+ n))
1061 (next-line 1) 1101 (forward-line 1)
1062 (gomoku-put-char ?|)))) 1102 (indent-to column)
1063 ((and (= dx -1) (= dy 1)) ; 1st Diagonal 1103 (insert-and-inherit ?|))))
1104 ((= dx -1) ; 1st Diagonal
1064 (backward-char (/ gomoku-square-width 2)) 1105 (backward-char (/ gomoku-square-width 2))
1065 (next-line (/ gomoku-square-height 2)) 1106 (indent-to (prog1 (current-column)
1066 (gomoku-put-char ?/)) 1107 (forward-line (/ gomoku-square-height 2))))
1067 ((and (= dx 1) (= dy 1)) ; 2nd Diagonal 1108 (insert-and-inherit ?/))
1109 (t ; 2nd Diagonal
1068 (forward-char (/ gomoku-square-width 2)) 1110 (forward-char (/ gomoku-square-width 2))
1069 (next-line (/ gomoku-square-height 2)) 1111 (indent-to (prog1 (current-column)
1070 (gomoku-put-char ?\\)))))) 1112 (forward-line (/ gomoku-square-height 2))))
1113 (insert-and-inherit ?\\))))))
1071 (sit-for 0)) ; Display NOW 1114 (sit-for 0)) ; Display NOW
1072 1115
1073;;; 1116;;;
1074;;; CURSOR MOTION. 1117;;; CURSOR MOTION.
1075;;; 1118;;;
1076(defun gomoku-move-left () 1119;; previous-line and next-line don't work right with intangible newlines
1077 "Move point backward one column on the Gomoku board."
1078 (interactive)
1079 (let ((x (gomoku-point-x)))
1080 (backward-char (cond ((null x) 1)
1081 ((> x 1) gomoku-square-width)
1082 (t 0)))))
1083
1084(defun gomoku-move-right ()
1085 "Move point forward one column on the Gomoku board."
1086 (interactive)
1087 (let ((x (gomoku-point-x)))
1088 (forward-char (cond ((null x) 1)
1089 ((< x gomoku-board-width) gomoku-square-width)
1090 (t 0)))))
1091
1092(defun gomoku-move-down () 1120(defun gomoku-move-down ()
1093 "Move point down one row on the Gomoku board." 1121 "Move point down one row on the Gomoku board."
1094 (interactive) 1122 (interactive)
@@ -1109,25 +1137,25 @@ If the game is finished, this command requests for another game."
1109 "Move point North East on the Gomoku board." 1137 "Move point North East on the Gomoku board."
1110 (interactive) 1138 (interactive)
1111 (gomoku-move-up) 1139 (gomoku-move-up)
1112 (gomoku-move-right)) 1140 (forward-char))
1113 1141
1114(defun gomoku-move-se () 1142(defun gomoku-move-se ()
1115 "Move point South East on the Gomoku board." 1143 "Move point South East on the Gomoku board."
1116 (interactive) 1144 (interactive)
1117 (gomoku-move-down) 1145 (gomoku-move-down)
1118 (gomoku-move-right)) 1146 (forward-char))
1119 1147
1120(defun gomoku-move-nw () 1148(defun gomoku-move-nw ()
1121 "Move point North West on the Gomoku board." 1149 "Move point North West on the Gomoku board."
1122 (interactive) 1150 (interactive)
1123 (gomoku-move-up) 1151 (gomoku-move-up)
1124 (gomoku-move-left)) 1152 (backward-char))
1125 1153
1126(defun gomoku-move-sw () 1154(defun gomoku-move-sw ()
1127 "Move point South West on the Gomoku board." 1155 "Move point South West on the Gomoku board."
1128 (interactive) 1156 (interactive)
1129 (gomoku-move-down) 1157 (gomoku-move-down)
1130 (gomoku-move-left)) 1158 (backward-char))
1131 1159
1132(provide 'gomoku) 1160(provide 'gomoku)
1133 1161