summaryrefslogtreecommitdiff
path: root/chess-crafty.el
blob: 260ebb5845660980935bc24825426706a488d6e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Play against crafty!
;;
;; $Revision$

(require 'chess-engine)
(require 'chess-fen)
(require 'chess-algebraic)

(defgroup chess-crafty nil
  "The publically available chess engine 'crafty'."
  :group 'chess-engine)

(defcustom chess-crafty-path (or (executable-find "crafty")
				 (executable-find "wcrafty"))
  "The path to the crafty executable."
  :type 'file
  :group 'chess-crafty)

(defvar chess-crafty-temp-files nil)
(make-variable-buffer-local 'chess-crafty-temp-files)

(defvar chess-crafty-regexp-alist
  (list (cons (concat "\\s-*\\(White\\|Black\\)\\s-*([0-9]+):\\s-+\\("
		      chess-algebraic-regexp "\\)\\s-*$")
	      (function
	       (lambda ()
		 (funcall chess-engine-response-handler 'move
			  (match-string 0)))))
	(cons "Illegal move:\\s-*\\(.*\\)"
	      (function
	       (lambda ()
		 (signal 'chess-illegal (match-string 1)))))))

(defun chess-crafty-handler (event &rest args)
  (cond
   ((eq event 'initialize)
    (let (proc)
      (message "Starting chess program 'crafty'...")
      (unless chess-crafty-path
	(error "Cannot find crafty executable; check `chess-crafty-path'"))
      (setq proc (start-process "chess-process" (current-buffer)
				chess-crafty-path))
      (message "Starting chess program 'crafty'...done")
      (process-send-string proc (concat "display nogeneral\n"
					"display nochanges\n"
					"display noextstats\n"
					"display nohashstats\n"
					"display nomoves\n"
					"display nonodes\n"
					"display noply1\n"
					"display nostats\n"
					"display notime\n"
					"display novariation\n"
					"alarm off\n"
					"ansi off\n"))
      proc))

   ((eq event 'shutdown)
    (chess-engine-send nil "quit\n")
    (dolist (file chess-crafty-temp-files)
      (if (file-exists-p file)
	  (delete-file file))))

   ((eq event 'ready)
    (let ((game (chess-engine-game nil)))
      (if game
	  (chess-game-set-data game 'active t))))

   ((eq event 'setup-pos)
    (chess-engine-send nil (format "setboard %s\n"
				   (chess-pos-to-fen (car args)))))

   ((eq event 'setup-game)
    (let ((file (make-temp-file "cra")))
      (with-temp-file file
	(insert (chess-game-to-string (car args)) ?\n))
      (chess-engine-send nil (format "read %s\n" file))
      (push file chess-crafty-temp-files)))

   ((eq event 'pass)
    (chess-engine-send nil "go\n"))

   ((eq event 'move)
    (chess-engine-send nil (concat (chess-ply-to-algebraic (car args))
				   "\n")))))

(provide 'chess-crafty)

;;; chess-crafty.el ends here