Размещение лодок в линкоре (удаление дублирования кода) - PullRequest
0 голосов
/ 20 декабря 2010

Я (медленно) разрабатываю 2D-версию Battleship сейчас, когда моя 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.

Ответы [ 2 ]

1 голос
/ 20 декабря 2010

Ну, для начала, я не думаю, что вам нужны и я, и смещение.Они оба переходят от 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, так что я уверен, что кто-то другой мог бы сделать намного лучше:)

0 голосов
/ 21 декабря 2010

Предположим, я правильно понимаю ваши потребности: если бы вы имели дело с указаниями -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) '\#)))
...