首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用常用的lisp重新滚动选定的骰子,并使用用户输入保持未选择的状态。

使用常用的lisp重新滚动选定的骰子,并使用用户输入保持未选择的状态。
EN

Stack Overflow用户
提问于 2016-06-19 23:50:24
回答 3查看 138关注 0票数 0

我有以下两项基本职能:

代码语言:javascript
代码运行次数:0
运行
复制
(defun dice ()
  (+ 1 (random 6)))

(defun five-dice ()
   (list (dice) (dice) (dice) (dice) (dice)))

他们所做的就是创建一个五个滚动骰子的列表。我想做的是选择一定数量的骰子再滚一次。意思是,我想选择任何一个2,3,或所有五个再次滚动,并取代骰子重新滚动,同时保留我决定不滚动的骰子。我想使用用户输入来完成这个任务。

我的假设是,最好的方法是使用一个符号,但我已经尝试了大约一天,但不知道如何准确地做到这一点。这就是我决定寻求帮助的原因。

编辑:,谢谢你们的帮助,我真的很感激。我很难理解lisp如何接受用户输入,以及如何将其存储到变量中。

所以,我创建了一个全局变量,并使用它作为用户的初始滚动,但是一旦我尝试使用来自用户的输入重新滚动特定的骰子,这就是我难以理解的部分。我看了几个例子,我试着重新创建它,但它并不适合我:

(defun testfunction() (terpri) (princ "would you like to roll? ") (read-line) (if (member (read-line) '("y" "yes" "") :test #'string=) (let ((roll (five-dice))) )))

这就是我想要做的,所以,在用户输入“是”或“y”之后,它会给他们5个骰子,并给他们3次机会重新掷出他们想要的骰子。所以,这就是我现在想要的工作。

Edit2:

(defun roll-again(lst) (if (null lst)nil (setf (nth (car lst) list-dices)(dice)) (yup (cdr lst)) ))

为什么这个功能不起作用?我现在要做的是使用这个函数重新滚动用户选择的骰子。所以,一旦我从用户那里得到输入,我就把输入放到一个列表中,然后使用这个函数重新滚动那些骰子。但是,由于某种原因,我无法让这个函数工作。

EN

回答 3

Stack Overflow用户

发布于 2016-06-20 10:08:44

最简单的方法是使用MAPCAR浏览列表,询问用户是否想重新滚动骰子。

代码语言:javascript
代码运行次数:0
运行
复制
(defun dice ()
  (1+ (random 6)))

(defun roll-dice (&optional (n 5))
  (let ((dice (loop repeat n collecting (dice))))
    (format *query-io* "Rolled: ~{~a~^, ~}." dice)
    (finish-output *query-io*)
    (mapcar (lambda (d)
              (if (y-or-n-p "Roll ~a again?" d)
                  (dice)
                  d))
            dice)))

编辑

在您的编辑中,您说用户应该能够重新滚动任意数量的骰子最多三次。这里有一个允许他们这样做的版本:

代码语言:javascript
代码运行次数:0
运行
复制
(defun roll-dice (&optional (n 5))
  (loop with dice = (loop repeat n collecting (dice))
        for rolls-left from 3 downto 1
        while (y-or-n-p "Rolled: ~{~a~^, ~}.~@
                         Re-roll (~a re-roll~:*~p left)?"
                        dice rolls-left)
        do (map-into dice
                     (lambda (d)
                       (if (y-or-n-p "Roll ~a again?" d)
                           (dice)
                           d))
                     dice)
        finally (return dice)))
票数 2
EN

Stack Overflow用户

发布于 2016-06-20 08:36:48

我认为对于小列表,您的最佳任务是访问列表中的元素并对其进行修改。例如,使用函数nth,如果您想修改第二个元素,可以这样做:

代码语言:javascript
代码运行次数:0
运行
复制
CL-USER> (defparameter list-dices (five-dice))
LIST-DICES
CL-USER> list-dices
(1 5 2 3 2)
CL-USER> (setf (nth 1 list-dices) (dice))
2
CL-USER> list-dices
(1 2 2 3 2)
票数 0
EN

Stack Overflow用户

发布于 2016-06-20 10:20:44

像这样的东西可能适用于重滚:

代码语言:javascript
代码运行次数:0
运行
复制
(defun reroll-specific-dice (dice-list reroll-list)
  "Takes a list of dice results, and a list of dice indexes to reroll,
   returns a list of those dice, re-rolled. This function is non-destructive."
  (let ((dice-list (copy-list dice-list)))
    (loop for reroll-index in reroll-list
       do (setf (nth reroll-index dice-list) (dice)))
    dice-list))

跳过let/copy-list可以使其具有破坏性,但一般情况下,非破坏性更好。这也不做错误检查。它也不处理从用户那里获取输入的问题,因为以一种非常方便用户的方式这样做是我没有时间编写的。

对于“最小”用户输入,您可以执行以下操作:

代码语言:javascript
代码运行次数:0
运行
复制
(defun get-dice-to-reroll ()
  (format t "Provide a list of dice to reroll, between parentheses: ")
  (finish-output)
  (read))

同样,这具有最小的错误检查,但返回一个适合作为reroll-list传递给reroll-specific-dice的列表。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37913002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档