0

I'm (slowly) working out a 2D version of Battleship now that my 1D version is done. I wrote the following function to place a boat on the board given the length of the boat, the position of the boat, and the direction the boat is facing. However, the function is ugly. Very ugly. By which I mean, there is much in the way of code duplication. Could anyone point out some ways in which I could reduce the duplication in this code?

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

EDIT: For clarification, pos is a number between 1 and 100, signifying a cell in a 10x10 2D array.

4

2 回答 2

1

好吧,对于初学者来说,我认为你不需要 i 和 offset。它们都从 0 到 len 步调一致。

然后你可以做这样的事情来将 < 或 >= 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 知之甚少,所以我相信其他人可以做得更好:)

于 2010-12-20T06:59:38.503 回答
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) '\#)))
于 2010-12-21T14:26:27.423 回答