在循环中读取用户的数据

时间:2017-01-18 14:20:31

标签: common-lisp

对于我正在进行的小游戏,我想阅读玩家的名字。到目前为止我有两个解决方案,我发现它们都有点麻烦。版本1强制用户另外声明他/她想要添加更多玩家:

(defun read-player ()
  (loop :while (y-or-n-p "Add another player?")
        :do (format t "~& Name of player #~D: " (1+ (length players)))
        :collect (read-line) :into players
        :finally (print players)))

版本2需要format表达式的副本:

(defun read-player2 ()
  (let ((players '()))
    (format t "~& Name of player #~D: " (1+ (length players)))
    (loop :for player = (read-line)
          :until (string= player "")
          :collect player :into players
          :do (format t "~& Name of player #~D: " (1+ (length players)))
          :finally (print players))))

我的两种方法是否合成?不打扰用户有其他问题而不重复代码?

1 个答案:

答案 0 :(得分:4)

阅读播放器时如何使用progn

(defun read-players ()
  (loop :for player-count :upfrom 1
    :for player =
    (progn
      (format t "~& Name of player #~D (RET to stop): " player-count)
      (finish-output)
      (read-line))
    :while (plusp (length player))
    :collect player))
> (read-players)
 Name of player #1 (RET to stop): r
 Name of player #2 (RET to stop): g
 Name of player #3 (RET to stop): 
==> ("r" "g")

PS。添加像

这样的函数是相对常见的
(defun ask-user (format-string &rest format-arguments)
  (fresh-line)
  (apply #'format t format-string format-arguments)
  (finish-output)
  (read-line))

或者,如果你喜欢format魔法,

(defun ask-user (format-string &rest format-arguments)
  (format t "~&~?: " format-string format-arguments)
  (finish-output)
  (read-line))

这会让您的read-players更具可读性:

(defun read-players ()
  (loop :for player-count :upfrom 1
    :for player = (ask-user "Name of player #~D (RET to stop)" player-count)
    :while (plusp (length player))
    :collect player))