Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Lisp] ООП на ЛИСПе


Автор: ScoobyDoo 31.5.2007, 17:05
Уважаемые специалисты в языке LISP. Вынужден обратиться к Вам с просьбой. Завтра мне кровь из носу нужно сдать программу на классы.

В Лиспе я не силён, но две попытки я уже предпринимал:

1) Игра "Жизнь"

Код


Код
исходная матрица задается в таком виде:
10 10
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0 0
0 0 0 1 1 1 0 0 0 0
0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
правила просты - в след поколение проходят только единички, окруженные
ровно 2 или 3 единичками. Если нолик окружен ровно 3 единичками - там
рождается новая единичка

;игра "Жизнь"
(defclass Life ()
        (
                (x :initarg :xi :initform 10)
                (y :initarg :yi :initform 10)
                (field)
                (temp-field)
        )
)

;считать из файла исходную матрицу
(defmethod read_field (life-class filename)
        (setq fin (open filename :direction :input))

        (setf (slot-value life-class 'x) (read fin))
        (setf (slot-value life-class 'y) (read fin))
        
        (setf (slot-value life-class 'field)
                (make-array (list
                        (+ (slot-value life-class 'x) 2)
                        (+ (slot-value life-class 'y) 2))
                        :initial-element 0
                )
        )       
        (setf (slot-value life-class 'temp-field)
                (make-array (list
                        (+ (slot-value life-class 'x) 2)
                        (+ (slot-value life-class 'y) 2))
                        :initial-element 0
                )
        )


        (do ((i 1)) ((= i (+ (slot-value life-class 'x) 1)) T)
                (do ((j 1)) ((= j (+ (slot-value life-class 'y) 1)) T)
                        (setf (aref (slot-value life-class 'field) i j)                                                 
                                (read fin)
                        )
                        (setq j (+ j 1))
                )
                (setq i (+ i 1))
        )

        (close fin)
)

;ф-я возвращает количество соседей данной клетки
(defmethod neighbours (life-class i j)
        (+      (aref (slot-value life-class 'field) (+ i -1) (+ j -1))
                (aref (slot-value life-class 'field) (+ i -1) (+ j 0))
                (aref (slot-value life-class 'field) (+ i -1) (+ j 1))
                (aref (slot-value life-class 'field) (+ i 0) (+ j -1))
                (aref (slot-value life-class 'field) (+ i 0) (+ j 1))
                (aref (slot-value life-class 'field) (+ i 1) (+ j -1))
                (aref (slot-value life-class 'field) (+ i 1) (+ j 0))
                (aref (slot-value life-class 'field) (+ i 1) (+ j 1))
        )
)

;ф-я находит след. поколение. Для этого создается временная матрица в которой
; получается ответ, и которая потом заменяет старую
(defmethod next_generation (life-class)
        (do ((i 1)) ((= i (+ (slot-value life-class 'x) 1)) T)
                (do ((j 1)) ((= j (+ (slot-value life-class 'y) 1)) T)
                        (setf (aref (slot-value life-class 'temp-field) i j)
                                (cond
                                        ((= (neighbours life-class i j) 3) 1)
                                        ((= (neighbours life-class i j) 2)
                                                (aref (slot-value life-class 'field) i j))
                                        (T 0)
                                )
                        )
                        (setq j (+ j 1))
                )
                (setq i (+ i 1))
        )

        (do ((i 1)) ((= i (+ (slot-value life-class 'x) 1)) T)
                (do ((j 1)) ((= j (+ (slot-value life-class 'y) 1)) T)
                        (setf (aref (slot-value life-class 'field) i j)                                                 
                                (aref (slot-value life-class 'temp-field) i j)
                        )
                        (setq j (+ j 1))
                )
                (setq i (+ i 1))
        )
)

;вывести текущую матрицу на экран
(defmethod print_field (life-class)
        (do ((i 1)) ((= i (+ (slot-value life-class 'x) 1)) T)
                (do ((j 1)) ((= j (+ (slot-value life-class 'y) 1)) T)
                        (prin1 (aref (slot-value life-class 'field) i j))
                        (princ " ")
                        (setq j (+ j 1))
                )
                (terpri)
                (setq i (+ i 1))
        )
)

(defmethod next_and_print (life-class)
        (next_generation life-class)
        (print_field life-class)
)

;это типа инициализация
(setf l (make-instance 'Life))
(read_field l "c:\life.txt")
;(read_field l 'life.txt)

;чтобы поюзать прогу, надо, когда ее запустишь, вызывать ф-ю
(next_and_print l)
;должно выводиться след. поколение


2) Класс "Множество" и операции с ними (пересечение, объединение итд)


Код

Код
Создать класс “Множества” с методами, реализующими операции с ними.
Сначала создадим сам класс: 
(defclass Sets ()((list1 :accessor set-list1 :initform nil :initarg :sl1)
                       (list2 :accessor set-list2 :initform nil :initarg :sl2)
  ))

Создадим экземпляры этих классов с помощью функции make-sets:
(defun make-sets (&optional S1 S2) 
(make-instance 'Sets :sl1 S1 :sl2 S2))
  MAKE-SETS

(setf S11 (make-sets))

(setf S22 (make-sets))


Методы заполнения множеств значениями:
(defmethod S1-load ((prList  Sets)  S1 &optional nz) 
        (setf (set-list1 prlist) S1))


(defmethod S2-load ((prList  Sets)  S2 &optional ns) 
        (setf (set-list2 prlist) S2))  

     
При вызове данных метод множествам с начальными значениями Nil присваивается некое значение, например:
(setf q (S1-load  S11 '(A S C D E F)))
(A S C D E F)

(setf qq (S2-load  S22 '(B C D)))
(B C D)

Метод для распечатки множеств: (выводит на экран множества)
defmethod print-sets ((prList1  Sets)(prList2 Sets) ) 
        (print (set-list1 prlist1))
         (print (set-list2 prlist2)))

(print-sets S11 S22)
(A S C D E F)
(B C D)

Метод проверяет, пересекаются ли множества, если пересекаются, то выводит результат пересечения:
(defmethod Inter ( )
(defun Intersec (S SS)
  (cond ((null  S) nil)
        ((member (car S)   SS)
         (cons (car  S) (Intersec (cdr  S)  SS) ))
        (T (Intersec (cdr S)  SS)))))

Вызов:
(progn
(Inter)
(Intersec q qq) )
(C D)

Метод  применяет операцию объединения к двум множествам и выдает результат объединения:
(defmethod Unio ()
(defun Uni (S SS)
  (cond ((null S)  SS)
        ((member (car S)  SS)
         (Uni (cdr S) SS))
        (T (cons (car S) (Uni (cdr S) SS))))))

Вызов:
(progn
(Unio)
(Uni q qq) )
(A S E F B C D)

Метод применяет операцию дополнения к двум множествам и выдает результат дополнения:
(defmethod Raznoct ()
(defun Deff (S1 S2 )
  (cond ((null  S1) nil)
        ((member (car  S1)  S2)
         (Deff (cdr  S1)  S2))
        (T (cons (car  S1) (Deff (cdr S1)  S2))
))))

Вызов:
(progn
(Raznoct)
(Deff q qq) )
(A S E F)


Однако мой преподаватель ни одну из них мне не зачёл. Сказал, что ООП в программах применено плохо, нет наследования, преобразования методов. Необходимо сделать более гармоничную программу, чтобы методы можно было применять к каким-то другим классам.

Очень прошу знатоков ЛИСПа откликнуться и придти мне на помощь. Горю, если завтра не сдам - к сессии не допустят  . Может ли кто-нибудь написать программы на классы, с использованием наследования, преобразования методов и, может, каких-то ещё основных принципов ООП?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)