将小船放置在战舰中(删除代码复制)

时间:2010-12-20 04:29:27

标签: common-lisp code-duplication

我(慢慢)正在制作一个2D版本的战舰,因为我的1D版本已经完成。考虑到船的长度,船的位置以及船面向的方向,我写下了以下功能,将船放在船上。但是,这个功能很难看。十分难看。我的意思是,代码重复的方式很多。任何人都可以指出一些方法可以减少这段代码中的重复吗?

(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))))

编辑:为了澄清,pos是1到100之间的数字,表示10x10 2D数组中的单元格。

2 个答案:

答案 0 :(得分:1)

嗯,首先,我认为你不需要i和偏移。他们都是从0到len同步。

然后你可以做这样的事情来折叠&lt;的+/-个案。或&gt; = 50成一个陈述:

(+ (/ pos 10) (* (if (< pos 50) 1 -1) offset))

给你(未经测试):

(defun place-boat (len pos dir)
  (dotimes (offset len)
    (if (= dir 0)
      (setf (aref *ans-board*
                  (+ (/ pos 10) (* (if (< pos 50) 1 -1) offset))
                  (mod pos 10))
            '#)
      (setf (aref *ans-board*
                  (/ pos 10)
                  (+ (mod pos 10) (* (if (< pos 50) 1 -1) offset)))
            '#))))

仍然有一些冗余。但到目前为止,这就是我所拥有的。

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

答案 1 :(得分:0)

假设我理解你的需要: 如果你要处理方向-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) '\#)))