1 ;;; chess-sjeng.el --- Play against sjeng!
3 ;; Copyright (C) 2004 Free Software Foundation, Inc.
5 ;; Author: Mario Lang <mlang@delysid.org>
8 ;; This file is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; This file is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU Emacs; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
25 (require 'chess-common)
27 (defgroup chess-sjeng nil
28 "The publically available chess engine 'sjeng'."
30 :link '(url-link "http://sjeng.sourceforge.net"))
32 (defcustom chess-sjeng-path (executable-find "sjeng")
33 "*The path to the sjeng executable."
37 (defvar chess-sjeng-evaluation nil)
39 (make-variable-buffer-local 'chess-sjeng-evaluation)
41 (defvar chess-sjeng-regexp-alist
43 (cons (concat "move\\s-+\\(" chess-algebraic-regexp "\\)\\s-*$")
46 (funcall chess-engine-response-handler 'move
47 (chess-engine-convert-algebraic (match-string 1) t)))))
48 (cons "tellics set 1\\s-+\\(.+\\)$"
51 (setq chess-engine-opponent-name (match-string 1)))))
52 (cons "{\\(Black\\|White\\) resigns}"
55 (funcall chess-engine-response-handler 'resign))))
56 (cons "\\(Illegal move\\|unrecognized/illegal command\\):\\s-*\\(.*\\)"
59 (error (match-string 1)))))
60 (cons "command not legal now"
63 (error (match-string 0)))))))
65 (defun chess-sjeng-handler (game event &rest args)
66 (unless chess-engine-handling-event
68 ((eq event 'initialize)
69 (let ((proc (chess-common-handler game 'initialize "sjeng")))
70 (when (and proc (processp proc)
71 (eq (process-status proc) 'run))
72 (process-send-string proc "xboard\nnew\n")
73 (setq chess-engine-process proc)
76 ((eq event 'setup-pos)
77 (chess-engine-send nil (format "setboard %s\n"
78 (chess-pos-to-string (car args)))))
81 (when (= 1 (chess-game-index game))
82 (chess-game-set-tag game "White" chess-full-name)
83 (chess-game-set-tag game "Black" chess-engine-opponent-name))
87 (concat (chess-index-to-coord (chess-ply-source (car args)))
88 (chess-index-to-coord (chess-ply-target (car args)))
89 (if (chess-ply-keyword (car args) :promote)
90 (string (downcase (chess-ply-keyword (car args) :promote)))
93 (if (chess-game-over-p game)
94 (chess-game-set-data game 'active nil)))
96 ((eq event 'setup-game)
97 (let ((file (chess-with-temp-file
98 (insert (chess-game-to-string (car args)) ?\n))))
99 (chess-engine-send nil (format "read %s\n" file))))
101 ((eq event 'set-option)
103 ((eq (car args) 'resign)
105 (chess-engine-send nil "resign 9\n")
106 (chess-engine-send nil "resign -1\n")))
107 ((eq (car args) 'ponder)
109 (chess-engine-send nil "hard\n")
110 (chess-engine-send nil "easy\n")))))
113 (if (and (eq event 'undo)
114 (= 1 (mod (car args) 2)))
115 (error "Cannot undo until after sjeng moves"))
117 (apply 'chess-common-handler game event args)))))
119 (provide 'chess-sjeng)
121 ;;; chess-sjeng.el ends here