在已经有数字的位置插入一个数字,创建一个List
Insert a number into a position that already has a number to create a List
我有这段 lisp 代码,用于 4 行游戏
(defun board ()
'((
(NIL NIL NIL NIL)
(NIL NIL NIL NIL)
(NIL NIL NIL NIL)
(NIL NIL NIL NIL)
)
(NIL NIL)))
每个 NIL 代表一列(忘记最后两个 NIL)。在每一列中,我最多可以放置游戏棋子,可以是 1(代表白色)或 10(代表黑色)。下面的代码是用来把棋子放在玩家想要的地方。
(defun get-level (level board)
(cond ((= level 1) (first board))
((= level 2) (second board))
((= level 3) (third board))
((= level 4) (fourth board))
))
(defun get-column (column board)
(cond ((= column 1) (first board))
((= column 2) (second board))
((= column 3) (third board))
((= column 4) (fourth board))
))
(defun get-line (line board)
(cond ((= line 1) (first board))
((= line 2) (second board))
((= line 3) (third board))
((= line 4) (fourth board))
))
(defun get-elem (x y z board)
(get-column y (get-line x (get-level z board))))
(defun value1 (x y z board)
(insertValue x y z board '1))
(defun value10 (x y z board)
(insertValue x y z board '10))
(defun insertValue (x y z board value)
(cond ((= z 1)(list (act-levelValue x y (first board) value) (second board) (third board) (fourth board)))
((= z 2)(list (first board) (act-levelValue x y (second board) value) (third board) (fourth board)))
((= z 3)(list (first board) (second board) (act-nivelValor x y (third board) value) (fourth board)))
((= z 4)(list (first board) (second board) (third board) (act-levelValue x y (fourth board) value)))))
(defun act-levelValue (x y level value)
(cond ((= x 1)(list (act-lineValue y (first level) valor) (second level) (third level) (fourth level)))
((= x 2)(list (first level) (act-lineValue y (second level) value) (third level) (fourth level)))
((= x 3)(list (first level) (second level) (act-lineValue y (third level) value) (fourth level)))
((= x 4)(list (first level) (second level) (third level) (act-linhaValor y (fourth level) value)))))
(defun act-lineValue (y line value)
(cond ((= y 1) (list value (second line) (third line) (fourth line)))
((= y 2) (list (first line) value (third line) (fourth line)))
((= y 3) (list (first line) (second line) value (fourth line)))
((= y 4) (list (first line) (second line) (third line) value))))
当我尝试在空位置插入一个值时,它起作用了。
CL-USER 1 > (inserirValor 1 1 1 '(((NIL NIL NIL NIL)(NIL NIL NIL NIL)(NIL NIL NIL NIL)(NIL NIL NIL NIL))(NIL NIL)) '10)
(((10 NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL NIL)) (NIL NIL) NIL NIL)
但是当我尝试在同一位置插入另一个值时,它不起作用。它只是用新值替换了以前的值,而我真正想要的是这样的:
CL-USER 1 > (inserirValor 1 1 1 '(((10 NIL NIL NIL)(NIL NIL NIL NIL)(NIL NIL NIL NIL)(NIL NIL NIL NIL))(NIL NIL)) '1)
((((1 10) NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL NIL)) (NIL NIL) NIL NIL)
有人可以帮助我吗?我应该怎么办?在 insertValue
函数中创建一个新条件?
代码重复
你不应该打这么多字。想想 RSI ;-)
而不是到处都是 first
、second
等,您可以使用 NTH
进行简单访问。
这适用于不同尺寸,而不仅仅是 4。
至于更新板,您似乎选择了使用嵌套列表和纯函数方法(即无突变)。您需要制作电路板的修改副本。让我们定义一个辅助函数,它以纯函数的方式替换列表中的一个元素:
(defun replace-element (list n value)
(nconc
(subseq list 0 n)
(list value)
(subseq list (1+ n))))
(APPEND 也可以代替 NCONC,但为什么分配更多内存?)
您还可以复制和变异:
(defun replace-element (list n value)
(let ((copy
(copy-list list)))
(setf (nth N copy) value)
copy))
这是一个测试:
(let ((list '(a b c d e)))
(loop
for i below (length list)
collect (replace-element list i '_)))
((_ B C D E)
(A _ C D E)
(A B _ D E)
(A B C _ E)
(A B C D _))
添加一个值
您有效地在 act-lineValue
函数中添加了值。与其替换旧值,不如想想你的数据是如何初始化的。当棋盘为空时你有 NIL,这代表空列表。
这意味着您可以将您的值放在现有列表的前面,而不是替换已经存在的列表。
使用前面的函数,这变成:
(replace-element line N (cons value (nth N line)))
其他备注
Lisp 中的名称不使用 CamelCase,而是使用破折号分隔单词。这意味着 level-value
而不是 levelValue
。
另外,你的名字有点神秘,我不太明白act
前缀代表什么。而 get-elem
应该是 get-element
。代码应该是可读的。
为什么用数字编码白色和黑色?您正在使用 Lisp,这是一种具有符号值的语言。只需使用 'white
和 'black
,这不会导致效率损失并且更具可读性。
我有这段 lisp 代码,用于 4 行游戏
(defun board ()
'((
(NIL NIL NIL NIL)
(NIL NIL NIL NIL)
(NIL NIL NIL NIL)
(NIL NIL NIL NIL)
)
(NIL NIL)))
每个 NIL 代表一列(忘记最后两个 NIL)。在每一列中,我最多可以放置游戏棋子,可以是 1(代表白色)或 10(代表黑色)。下面的代码是用来把棋子放在玩家想要的地方。
(defun get-level (level board)
(cond ((= level 1) (first board))
((= level 2) (second board))
((= level 3) (third board))
((= level 4) (fourth board))
))
(defun get-column (column board)
(cond ((= column 1) (first board))
((= column 2) (second board))
((= column 3) (third board))
((= column 4) (fourth board))
))
(defun get-line (line board)
(cond ((= line 1) (first board))
((= line 2) (second board))
((= line 3) (third board))
((= line 4) (fourth board))
))
(defun get-elem (x y z board)
(get-column y (get-line x (get-level z board))))
(defun value1 (x y z board)
(insertValue x y z board '1))
(defun value10 (x y z board)
(insertValue x y z board '10))
(defun insertValue (x y z board value)
(cond ((= z 1)(list (act-levelValue x y (first board) value) (second board) (third board) (fourth board)))
((= z 2)(list (first board) (act-levelValue x y (second board) value) (third board) (fourth board)))
((= z 3)(list (first board) (second board) (act-nivelValor x y (third board) value) (fourth board)))
((= z 4)(list (first board) (second board) (third board) (act-levelValue x y (fourth board) value)))))
(defun act-levelValue (x y level value)
(cond ((= x 1)(list (act-lineValue y (first level) valor) (second level) (third level) (fourth level)))
((= x 2)(list (first level) (act-lineValue y (second level) value) (third level) (fourth level)))
((= x 3)(list (first level) (second level) (act-lineValue y (third level) value) (fourth level)))
((= x 4)(list (first level) (second level) (third level) (act-linhaValor y (fourth level) value)))))
(defun act-lineValue (y line value)
(cond ((= y 1) (list value (second line) (third line) (fourth line)))
((= y 2) (list (first line) value (third line) (fourth line)))
((= y 3) (list (first line) (second line) value (fourth line)))
((= y 4) (list (first line) (second line) (third line) value))))
当我尝试在空位置插入一个值时,它起作用了。
CL-USER 1 > (inserirValor 1 1 1 '(((NIL NIL NIL NIL)(NIL NIL NIL NIL)(NIL NIL NIL NIL)(NIL NIL NIL NIL))(NIL NIL)) '10)
(((10 NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL NIL)) (NIL NIL) NIL NIL)
但是当我尝试在同一位置插入另一个值时,它不起作用。它只是用新值替换了以前的值,而我真正想要的是这样的:
CL-USER 1 > (inserirValor 1 1 1 '(((10 NIL NIL NIL)(NIL NIL NIL NIL)(NIL NIL NIL NIL)(NIL NIL NIL NIL))(NIL NIL)) '1)
((((1 10) NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL NIL)) (NIL NIL) NIL NIL)
有人可以帮助我吗?我应该怎么办?在 insertValue
函数中创建一个新条件?
代码重复
你不应该打这么多字。想想 RSI ;-)
而不是到处都是 first
、second
等,您可以使用 NTH
进行简单访问。
这适用于不同尺寸,而不仅仅是 4。
至于更新板,您似乎选择了使用嵌套列表和纯函数方法(即无突变)。您需要制作电路板的修改副本。让我们定义一个辅助函数,它以纯函数的方式替换列表中的一个元素:
(defun replace-element (list n value)
(nconc
(subseq list 0 n)
(list value)
(subseq list (1+ n))))
(APPEND 也可以代替 NCONC,但为什么分配更多内存?)
您还可以复制和变异:
(defun replace-element (list n value)
(let ((copy
(copy-list list)))
(setf (nth N copy) value)
copy))
这是一个测试:
(let ((list '(a b c d e)))
(loop
for i below (length list)
collect (replace-element list i '_)))
((_ B C D E)
(A _ C D E)
(A B _ D E)
(A B C _ E)
(A B C D _))
添加一个值
您有效地在 act-lineValue
函数中添加了值。与其替换旧值,不如想想你的数据是如何初始化的。当棋盘为空时你有 NIL,这代表空列表。
这意味着您可以将您的值放在现有列表的前面,而不是替换已经存在的列表。 使用前面的函数,这变成:
(replace-element line N (cons value (nth N line)))
其他备注
Lisp 中的名称不使用 CamelCase,而是使用破折号分隔单词。这意味着
level-value
而不是levelValue
。另外,你的名字有点神秘,我不太明白
act
前缀代表什么。而get-elem
应该是get-element
。代码应该是可读的。为什么用数字编码白色和黑色?您正在使用 Lisp,这是一种具有符号值的语言。只需使用
'white
和'black
,这不会导致效率损失并且更具可读性。