常见的lisp,如何屏蔽键盘输入

ccc*_*807 2 keyboard common-lisp masking

这是一个用于Hangman类型游戏的Common Lisp中的控制台程序.第一个玩家输入一个字符串,由第二个玩家猜测.我的输入功能在下面---不幸的是,第一个玩家输入的字符仍然可见.

使用JavaScript很简单,只需使用密码文本输入框即可.使用VB,使用相同类型的工具很简单.有没有办法使用本机Common Lisp函数来做到这一点?

谢谢,CC.

(defun get-answer ()
  (format t "Enter the word or phrase to be guessed: ~%")
  (coerce (string-upcase (read-line)) 'list))

(defun start-hangman ()
  (setf tries 6)
  (greeting)
  (setf answer (get-answer))
  (setf obscure (get-obscure answer))
  (game-loop answer obscure))
Run Code Online (Sandbox Code Playgroud)

cor*_*ump 5

每个实现都以不同方式支持

如果您想要在不同实现之上的可移植性层,您可能希望使用辅助库,如iolib.termioscl-charms(libcurses接口).

SBCL

我为SBCL 找到了一个关于它的讨论主题,这里是Richard M. Kreuter的实现代码:

(require :sb-posix)

(defun echo-off ()
  (let ((tm (sb-posix:tcgetattr sb-sys:*tty*)))
    (setf (sb-posix:termios-lflag tm)
      (logandc2 (sb-posix:termios-lflag tm) sb-posix:echo))
    (sb-posix:tcsetattr sb-sys:*tty* sb-posix:tcsanow tm)))

(defun echo-on ()
  (let ((tm (sb-posix:tcgetattr sb-sys:*tty*)))
    (setf (sb-posix:termios-lflag tm)
      (logior (sb-posix:termios-lflag tm) sb-posix:echo))
    (sb-posix:tcsetattr sb-sys:*tty* sb-posix:tcsanow tm)))
Run Code Online (Sandbox Code Playgroud)

所以,最后有机会谈论PROG2:

(defun read-silently ()
  (prog2
    (echo-off)
    (read-line sb-sys:*tty*)
    (echo-on)))
Run Code Online (Sandbox Code Playgroud)

但是,您可能希望确保在展开堆栈时始终重置echo,并在输入内容之前清除输入:

(defun read-silently ()
  (echo-off)
  (unwind-protect 
      (progn
        (clear-input sb-sys:*tty*)
        (read-line sb-sys:*tty*))  
    (echo-on)))
Run Code Online (Sandbox Code Playgroud)

CL-CHARMS

这是使用libcurse的替代方法.以下内容足以进行简单的测试工作.

(defun read-silently ()
  (let (input)
    (charms:with-curses ()
      (charms:disable-echoing)
      (charms:enable-raw-input)
      (clear-input *terminal-io*)
      (setf input (read-line *terminal-io*))
      (charms:disable-raw-input)
      (charms:enable-echoing))
    input))
Run Code Online (Sandbox Code Playgroud)

此外,使用libcurse可能会帮助您实现一个漂亮的刽子手控制台游戏.