Common lisp 在战舰上放置船只(消除代码重复)

Common lisp 在战舰上放置船只(消除代码重复),common-lisp,code-duplication,Common Lisp,Code Duplication,现在我的1D版本已经完成,我正在(慢慢地)制作战舰的2D版本。我编写了下面的函数,根据船的长度、位置和方向,将船放置在板上。然而,它的功能是丑陋的。非常难看。我的意思是,代码复制的方式有很多。有谁能指出一些我可以减少代码重复的方法吗 (defun place-boat (len pos dir) (let ((offset 0)) (dotimes (i len) (if (= dir 0) (if (< pos 50) (set

现在我的1D版本已经完成,我正在(慢慢地)制作战舰的2D版本。我编写了下面的函数,根据船的长度、位置和方向,将船放置在板上。然而,它的功能是丑陋的。非常难看。我的意思是,代码复制的方式有很多。有谁能指出一些我可以减少代码重复的方法吗

(defun place-boat (len pos dir)
  (let ((offset 0))
    (dotimes (i len)
      (if (= dir 0)
        (if (< pos 50)
          (setf (aref *ans-board*
              (+ (/ pos 10) offset)
              (mod pos 10))
            '#)
          (setf (aref *ans-board*
              (- (/ pos 10) offset)
              (mod pos 10))
            '#))
        (if (< pos 50)
          (setf (aref *ans-board*
              (/ pos 10)
              (+ (mod pos 10) offset))
            '#)
          (setf (aref *ans-board*
              (/ pos 10)
              (- (mod pos 10) offset))
            '#)))
      (incf offset))))
(德芬广场船(len pos dir)
(let((偏移量0))
(多时)
(如果(=目录0)
(如果(<位置50)
(setf(aref*ans董事会)*
(+(/位置10)偏移量)
(国防部位置10))
'#)
(setf(aref*ans董事会)*
((/pos 10)偏移量)
(国防部位置10))
'#))
(如果(<位置50)
(setf(aref*ans董事会)*
(/位置10)
(+(模块位置10)偏移量)
'#)
(setf(aref*ans董事会)*
(/位置10)
((模块位置10)偏移量)
'#)))
(增量偏移量)

编辑:为了澄清起见,
pos
是一个介于1和100之间的数字,表示10x10 2D数组中的一个单元格。

首先,我认为您不需要同时使用I和offset。它们都是从0到len的步调

然后您可以这样做,将<或>=50的+/-情况折叠为一个语句:

(+(/pos 10)(*(如果(

给你(未经测试):

(德芬广场船(len pos dir)
(点时间(偏移长度)
(如果(=目录0)
(setf(aref*ans董事会)*
(+(/pos 10)(*(如果(
它仍然有一些冗余。但到目前为止,这就是我得到的


注意,我对Common Lisp知之甚少,因此我相信其他人可以做得更好:)

如果我正确理解您的需求: 如果你要处理方向-1,-1,10,-10,你可以很容易地做这样的事情:

(defun place (pos len dir) 
    (loop for i from pos to (+ pos (* len dir)) by dir do 
       (setf (aref board i) '\#)))

在#lisp中优秀人士的帮助下,我对您的解决方案进行了一些调整,最后得出以下结论:谢谢!这会起作用,但所处理的数组是二维的/
(defun place (pos len dir) 
    (loop for i from pos to (+ pos (* len dir)) by dir do 
       (setf (aref board i) '\#)))