Common Lisp在宏中生成变量名

时间:2019-06-22 13:06:45

标签: common-lisp

我目前正在学习Common Lisp,作为该过程的一部分,我正在尝试实现一个通用的井字游戏,其中棋盘可以是任何奇数大小(因此有一个中心正方形)。我到了要检查赢家的地方,并且正在使用此功能来检查行或列是否有赢家。

(defun straight-winner-p (board start size)
  (let ((row-player (aref board start 0))
        (row-count 0)
        (col-player (aref board 0 start))
        (col-count 0))

    (loop for step from 0 to (- size 1) do

         (if (equal
              (aref board start step)
              row-player)
             (incf row-count))
         (if (equal
              (aref board step start)
              col-player)
             (incf col-count))
         )
    (format t "row ~a, col ~a~%" row-count col-count)))

最终,如果检查播放器是否为nil并且计数等于大小,则将用检查代替它。无论如何,我想用一个宏替换两个ifs。所以,就像

(check row start step)

然后宏将生成if语句

         (if (equal
              (aref board start step)
              row-player)
             (incf row-count))

然后使用调用相同的宏(检查col步骤开始)。我似乎无法使宏从行生成行数和行播放器。你会怎么做?

1 个答案:

答案 0 :(得分:3)

在已经使用循环宏的情况下如何使用循环宏中的功能?

redux-saga

您想要做什么:

(defun straight-winner-p (board start size)
  (loop :with row-player := (aref board start 0)
        :and col-player := (aref board 0 start)
        :for step :below size
        :count (equal (aref board start step) row-player) :into row-count
        :count (equal (aref board step start) col-player) :into col-count
        :finally (format t "row ~a, col ~a~%" row-count col-count)
                 (return (or (= row-count size) (= col-count size)))))

尽管要特别注意万一宏和您的代码以不同的程序包结尾并使用提供的符号的程序包,但是如果使用不同的读取器设置读取文件,则将无法正常工作。如果编译一个而不编译另一个,则可能不起作用。