Лучший способ реализовать ходы ладьи и возможные ходы в Лиспе - PullRequest
1 голос
/ 09 мая 2020

У меня есть доска [8,8], и я пытаюсь реализовать горизонтальное и вертикальное движение на основе движений вверх, вниз, влево и вправо, движений ладьи на шахматной доске, и мне сложно понять, как чтобы переместить фигуру на поле с указанием количества клеток, на которое нужно сделать ход.

(defun board ()
 '((64 35 74 26 21 57 12 28) 
   (43 15 47 53 24 56 42 29) 
   (51 41 71 31 17 45 55 30) 
   (67 66 22 T 54 75 32 38) 
   (13 11 16 23 25 27 33 20) 
   (34 36 37 44 46 52 61 48) 
   (10 49 59 69 68 70 50 40) 
   (62 63 65 72 73 76 77 58)))

Ладья перемещается по горизонтали и вертикали на любое количество полей, вперед или назад. На диаграмме ладья может перейти на любой из выделенных квадратов.

введите описание изображения здесь

Функция для проверки правильности координат

(defun position-valid (x y)
  (and (>= x 0) (>= y 0) (< x 8) (< y 8)))

Функция, которая перемещает башню в соответствии с координатами (x, y)

(defun move-piece (x y dx dy board)
  (let ((new-board (copy-tree board))
        (new-x (+ x dx))
        (new-y (+ y dy))
        (piece (nth x (nth y board))))
    (setf (nth x (nth y new-board)) nil
          (nth new-x (nth new-y new-board)) piece)
    new-board))

Функция, которая перемещает фигуру вниз

 (defun DOWN (x y board) 
   (cond
    ((equal (position-valid (+ x 1) (+ y 0)) 'T)
     (move-piece x y 1 0 board))
    (T NIL)))

Функция, которая перемещает фигуру вверх

(defun UP (x y board) 
  (cond
    ((equal (position-valid (- x 1) (+ y 0)) 'T)
     (move-piece x y -1 0 board))
    (T NIL)))

Функция, которая перемещает фигуру влево

(defun LEFT (x y board) 
  (cond
    ((equal (position-valid (+ x 0) (- y 1)) 'T)
     (move-piece x y 0 -1 board))
    (T NIL)))

Функция, которая перемещает фигуру вправо

(defun RIGHT (x y board) 
  (cond
    ((equal (position-valid (+ x 0) (+ y 1)) 'T)
     (move-piece x y 0 1 board))
   (T NIL)))

теперь цель состоит в том, чтобы реализовать вертикальные и горизонтальные движения на основе движений, упомянутых выше, чтобы фигура перемещалась, и в этом случае я думаю, что нам все еще нужно реализовать возможные движения в зависимости от типа движения и количества квадратов, которые нужно переместить

Я реализовал этот список операторов для горизонтального и вертикального движения, но он не работает

Функция, которая перемещает Башню по горизонтали

(defun HORIZONTAL (x y n mov board) ;;n is number of square to move
  (cond
    ((and (equal (position-valid (+ x 0) (- y 1)) 'T) ;;left
          (equal (position-valid (+ x 0) (+ y 1)) 'T));;right     
          (cond
               ((equal mov 'LEFT)  (LEFT x y board))
               ((equal mov 'RIGHT) (RIGTH x y board))
               (T (HORIZONTAL x y (1- n) mov board))))
   (T NIL)))

Функция, которая заставляет Башню двигаться в вертикальном направлении,

(defun VERTICAL(x y n mov board) ;;n is number of square to move
  (cond
    ((and (equal (position-valid (- x 1) (+ y 0)) 'T) ;;up
          (equal (position-valid (+ x 1) (+ y 0)) 'T));;down
          (cond
               ((equal mov 'DOWN)  (DOWN x y board))     
               ((equal mov 'UP)    (UP x y board))
               (T (VERTICAL x y (1- n) mov board))))
   (T NIL)))

и как получить возможные ходы башни на доске ba sed по типу ходов

Любое предложение?

1 Ответ

3 голосов
/ 09 мая 2020

Мне кажется, что вы создаете слишком много ненужных функций. Что бы я сделал, так это иметь функцию MOVE, основанную на подвижной части, которая будет выполнять как горизонтальное, так и вертикальное смещение. Поскольку у вас есть параметр mov, который может быть ВВЕРХ, ВНИЗ, ВЛЕВО или ВПРАВО, горизонтальные и вертикальные движения уже неявны, поэтому нет необходимости иметь отдельную функцию для каждого направления.
Итак, это то, что я бы хотел do:

(setq board 
 '((64 35 74 26 21 57 12 28) 
   (43 15 47 53 24 56 42 29) 
   (51 41 71 31 17 45 55 30) 
   (67 66 22 T 54 75 32 38) 
   (13 11 16 23 25 27 33 20) 
   (34 36 37 44 46 52 61 48) 
   (10 49 59 69 68 70 50 40) 
   (62 63 65 72 73 76 77 58)))


(defun position-valid (x y)
  (and (>= x 0) (>= y 0) (< x 8) (< y 8)) )


(defun move-piece (x y dx dy board)
  (let ((new-board (copy-tree board))
        (new-x (+ x dx))
        (new-y (+ y dy))
        (piece (nth x (nth y board))) )
    (when (position-valid new-x new-y)
      (setf (nth x (nth y new-board)) nil
          (nth new-x (nth new-y new-board)) piece ))
    new-board))


(defun MOVE (x y n mov board) ;; n is number of squares to move
  (case mov
    (UP (move-piece x y 0 (- n) board))
    (DOWN (move-piece x y 0 n board))
    (LEFT (move-piece x y (- n) 0 board))
    (RIGHT (move-piece x y n 0 board))
    (otherwise NIL) ))

А затем, если вы хотите получить список всех возможных ходов:

(defun valid-moves (x y board)
  (let (result)
    (dolist (mov '(up down left right) result)
      (dotimes (n 7)
        (when (move x y n mov board)
          (push (list n mov) result) )))))
...