-;; Gomoku game between you and Emacs
+;;; gomoku.el --- Gomoku game between you and Emacs
+
;; Copyright (C) 1988 Free Software Foundation, Inc.
+;; Author: Phillippe Schnoebelen <phs@lifia.imag.fr>
+;; Adapted-By: ESR
+;; Keywords: games
+
;; This file is part of GNU Emacs.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 1, or (at your option)
+;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; along with GNU Emacs; see the file COPYING. If not, write to
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;;; Commentary:
+
;;; Gomoku game between you and GNU Emacs. Last modified on 13 Sep 1988
;;;
;;; Written by Ph. Schnoebelen (phs@lifia.imag.fr), 1987, 1988
;;; with precious advices from J.-F. Rit.
;;; This has been tested with GNU Emacs 18.50.
-(provide 'gomoku)
-
-
;; RULES:
;;
;; Gomoku is a game played between two players on a rectangular board. Each
;; it yourself :-).
-;; HOW TO INSTALL:
-;;
-;; There is nothing specific w.r.t. installation: just put this file in the
-;; lisp directory and add an autoload for command gomoku in site-init.el. If
-;; you don't want to rebuild Emacs, then every single user interested in
-;; Gomoku will have to put the autoload command in its .emacs file. Another
-;; possibility is to define in your .emacs some command using (require
-;; 'gomoku).
-;;
-;; The most important thing is to BYTE-COMPILE gomoku.el because it is
-;; important that the code be as fast as possible.
-;;
;; There are two main places where you may want to customize the program: key
;; bindings and board display. These features are commented in the code. Go
;; and see.
;; HOW TO USE:
;;
-;; Once this file has been installed, the command "M-x gomoku" will display a
+;; The command "M-x gomoku" displays a
;; board, the size of which depends on the size of the current window. The
;; size of the board is easily modified by giving numeric arguments to the
;; gomoku command and/or by customizing the displaying parameters.
;; The algorithm is briefly described in section "THE SCORE TABLE". Some
;; parameters may be modified if you want to change the style exhibited by the
;; program.
+
+;;; Code:
\f
;;;
;;; GOMOKU MODE AND KEYMAP.
(define-key gomoku-mode-map "\C-cr" 'gomoku-human-resigns) ; C-C R
(define-key gomoku-mode-map "\C-ce" 'gomoku-emacs-plays) ; C-C E
- ;; Key bindings for "function" keys. If your terminal has such
- ;; keys, make sure they are declared through the function-keymap
- ;; keymap (see file keypad.el).
- ;; One problem with keypad.el is that the function-key-sequence
- ;; function is really slow, so slow that you may want to comment out
- ;; the following lines ...
- (if (featurep 'keypad)
- (let (keys)
- (if (setq keys (function-key-sequence ?u)) ; Up Arrow
- (define-key gomoku-mode-map keys 'gomoku-move-up))
- (if (setq keys (function-key-sequence ?d)) ; Down Arrow
- (define-key gomoku-mode-map keys 'gomoku-move-down))
- (if (setq keys (function-key-sequence ?l)) ; Left Arrow
- (define-key gomoku-mode-map keys 'gomoku-move-left))
- (if (setq keys (function-key-sequence ?r)) ; Right Arrow
- (define-key gomoku-mode-map keys 'gomoku-move-right))
-;; (if (setq keys (function-key-sequence ?e)) ; Enter
-;; (define-key gomoku-mode-map keys 'gomoku-human-plays))
-;; (if (setq keys (function-key-sequence ?I)) ; Insert
-;; (define-key gomoku-mode-map keys 'gomoku-human-plays))
- )))
-
-
+ (define-key gomoku-mode-map [up] 'gomoku-move-up)
+ (define-key gomoku-mode-map [down] 'gomoku-move-down)
+ (define-key gomoku-mode-map [left] 'gomoku-move-left)
+ (define-key gomoku-mode-map [right] 'gomoku-move-right)
+ (define-key gomoku-mode-map [kp-enter] 'gomoku-human-plays)
+ (define-key gomoku-mode-map [insert] 'gomoku-human-plays))
(defun gomoku-mode ()
"Major mode for playing Gomoku against Emacs.
;; If score is equally good, choose randomly. But first check freeness:
((not (zerop (aref gomoku-board square)))
(aset gomoku-score-table square -1))
- ((= count (random-number (setq count (1+ count))))
+ ((zerop (random (setq count (1+ count))))
(setq best-square square
score-max score)))
(setq square (1+ square))) ; try next square
best-square))
-
-(defun random-number (n)
- "Return a random integer between 0 and N-1 inclusive."
- (setq n (% (random) n))
- (if (< n 0) (- n) n))
\f
;;;
;;; INITIALIZING THE SCORE TABLE.
;;; INTERACTIVE COMMANDS.
;;;
+;;;###autoload
(defun gomoku (&optional n m)
"Start a Gomoku game between you and Emacs.
If a game is in progress, this command allow you to resume it.
(defun gomoku-put-char (char)
"Draw CHAR on the Gomoku screen."
- (if buffer-read-only (toggle-read-only))
- (insert char)
- (delete-char 1)
- (backward-char 1)
- (toggle-read-only))
+ (let ((inhibit-read-only t))
+ (insert char)
+ (delete-char 1)
+ (backward-char 1)))
(defun gomoku-init-display (n m)
"Display an N by M Gomoku board."
(buffer-disable-undo (current-buffer))
- (if buffer-read-only (toggle-read-only))
- (erase-buffer)
- (let (string1 string2 string3 string4)
- ;; We do not use gomoku-plot-square which would be too slow for
- ;; initializing the display. Rather we build STRING1 for lines where
- ;; board squares are to be found, and STRING2 for empty lines. STRING1 is
- ;; like STRING2 except for dots every DX squares. Empty lines are filled
- ;; with spaces so that cursor moving up and down remains on the same
- ;; column.
- (setq string1 (concat (make-string (1- gomoku-square-width) ? ) ".")
- string1 (apply 'concat
- (make-list (1- n) string1))
- string1 (concat (make-string gomoku-x-offset ? ) "." string1 "\n")
- string2 (make-string (+ 1 gomoku-x-offset
- (* (1- n) gomoku-square-width))
- ? )
- string2 (concat string2 "\n")
- string3 (apply 'concat
- (make-list (1- gomoku-square-height) string2))
- string3 (concat string3 string1)
- string3 (apply 'concat
- (make-list (1- m) string3))
- string4 (apply 'concat
- (make-list gomoku-y-offset string2)))
- (insert string4 string1 string3))
- (toggle-read-only)
- (gomoku-goto-xy (/ (1+ n) 2) (/ (1+ m) 2)) ; center of the board
- (sit-for 0)) ; Display NOW
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (let (string1 string2 string3 string4)
+ ;; We do not use gomoku-plot-square which would be too slow for
+ ;; initializing the display. Rather we build STRING1 for lines where
+ ;; board squares are to be found, and STRING2 for empty lines. STRING1 is
+ ;; like STRING2 except for dots every DX squares. Empty lines are filled
+ ;; with spaces so that cursor moving up and down remains on the same
+ ;; column.
+ (setq string1 (concat (make-string (1- gomoku-square-width) ? ) ".")
+ string1 (apply 'concat
+ (make-list (1- n) string1))
+ string1 (concat (make-string gomoku-x-offset ? ) "." string1 "\n")
+ string2 (make-string (+ 1 gomoku-x-offset
+ (* (1- n) gomoku-square-width))
+ ? )
+ string2 (concat string2 "\n")
+ string3 (apply 'concat
+ (make-list (1- gomoku-square-height) string2))
+ string3 (concat string3 string1)
+ string3 (apply 'concat
+ (make-list (1- m) string3))
+ string4 (apply 'concat
+ (make-list gomoku-y-offset string2)))
+ (insert string4 string1 string3))
+ (gomoku-goto-xy (/ (1+ n) 2) (/ (1+ m) 2)) ; center of the board
+ (sit-for 0))) ; Display NOW
(defun gomoku-display-statistics ()
"Obnoxiously display some statistics about previous games in mode line."
(gomoku-move-down)
(gomoku-move-left))
+(provide 'gomoku)
+;;; gomoku.el ends here