fink/gtp.lisp

108 lines
3.5 KiB
Common Lisp

(in-package :gtp-handler)
;(require :sb-bsd-sockets)
(defparameter *quit?* nil)
(defun nslookup (hostname)
"Performs a DNS look up for HOSTNAME and returns the address as a
four element array, suitable for socket-connect. If HOSTNAME is
not found, a host-not-found-error condition is thrown."
(if hostname
(sb-bsd-sockets:host-ent-address (sb-bsd-sockets:get-host-by-name hostname))
nil))
(defun tcp-connect (server port &optional (timeout 10))
(handler-case
(let ((socket (make-instance 'sb-bsd-sockets:inet-socket :type :stream :protocol :tcp)))
(sb-bsd-sockets:socket-connect socket (nslookup server) port)
socket)
(sb-bsd-sockets:CONNECTION-REFUSED-ERROR ()
(progn
(format t "Error: Connection refused~%")
nil))))
(defun tcp-print-raw (socket line)
(when (and socket line)
(sb-bsd-sockets:socket-send socket line nil)))
(defun tcp-print (socket line)
(tcp-print-raw socket (concatenate 'string (format nil "~04d" (length line)) line)))
(defun tcp-read-raw (socket &key (maxsize 65536) (timeout 10))
(when socket
(values (sb-bsd-sockets:socket-receive socket nil maxsize))))
;(if-timeout (timeout (format t "socket-receive timed out after ~A seconds.~%" timeout) (force-output) nil)
(defun tcp-read (socket &key (timeout 10))
(when socket
(let ((len (parse-integer (tcp-read-raw socket :maxsize 4 :timeout timeout))))
(tcp-read-raw socket :maxsize len :timeout timeout))))
(defun gtp-net-client (server port)
(go-bot:init)
(setf *quit?* nil)
(let ((socket (tcp-connect server port)))
(if (eql socket nil)
()
(progn
(format t "Connection establish, playing...~%")
(do ()
((or (eql socket nil) (eql *quit?* t)))
(let ((cmd (tcp-read socket)))
; (print cmd)
(let ((resp (dispatch-gtp-command cmd)))
;(print resp)
(tcp-print socket (concatenate 'string "= " resp (string #\newline) (string #\newline))))))))))
(defun gtp-client ()
(go-bot:init)
(setf *quit?* nil)
(do ()
((eql *quit?* t))
(format t "= ~a~%~%" (dispatch-gtp-command (read-line t)))))
(defun split-string (string pivot-str)
(do ((pivot (char pivot-str 0))
(i 0 (+ i 1))
(beg 0)
(strings '()))
((> i (length string)) (reverse strings))
(if (or (eql (length string) i) (eql (aref string i) pivot))
(progn (push (subseq string beg i) strings) (setf beg (+ i 1))))))
(defun dispatch-gtp-command (command-string)
(let* ((commands (split-string (string-upcase command-string) " "))
;(cl-ppcre:split "\\s+" (string-upcase command-string)))
(command (intern (first commands) :gtp-handler)))
(case command
(name go-bot:*name*)
(version go-bot:*version*)
(protocol_version "gtp2ip-0.1")
(boardsize (go-bot:set-boardsize (parse-integer (second commands)))
(go-bot:init-board)
"")
; warning: read-from-string pulls full reader. not safe
(komi (go-bot:set-komi (read-from-string (second commands)))
"")
(clear_board (go-bot:init) "")
(play (go-bot:play (char (second commands) 0) (third commands)) "")
(genmove (go-bot:genmove (char (second commands) 0)))
(genmove_black (go-bot:genmove #\b))
(genmove_white (go-bot:genmove #\w))
;(get_random_seed "0")
;(known_command)
;(list_commands)
(game_score (format t "Score for ~c: ~s~%" go-bot:*player* (string-trim (string #\newline) (second commands))) "")
(quit (setf *quit?* t) "")
(otherwise (concatenate 'string "? unknown command: " (string-downcase (first commands)))))))