第一個問題:您打開一個文件,但從不關閉它。當你使用open
時,你需要記住close
。由於這很常見,所以有with-open-file
,它會自動關閉(請參閱CLHS的文檔)。
(defvar *N*)
(defvar *M*)
(defvar *Goal*)
(defvar *Start*)
(defvar *Matrix*)
(defun read-matrix (file)
(with-open-file (in file
:direction :input)
(read-line in nil)
(setq *N* (parse-integer (read-char in)))
(read-line in nil)
(read-line in nil)
(setq *M* (parse-integer (read-line in)))
(read-line in nil)
(read-line in nil)
(setq *Matrix* (make-array '(*N* *M*) :initial-element 1))
(loop for i from 0 to *N*
do (loop for j from 0 to *M*
do (setf (aref *Matrix* i j)
(read-char in))))
(read-line in nil)
(setq *Start* (read-line in))
(read-line in nil)
(setq *Goal* (read-line in))))
問題二:read-char
返回字符,parse-integer
不是爲角色定義。看起來你可以簡單地閱讀整行。
(defvar *N*)
(defvar *M*)
(defvar *Goal*)
(defvar *Start*)
(defvar *Matrix*)
(defun read-matrix (file)
(with-open-file (in file
:direction :input)
(read-line in nil)
(setq *N* (parse-integer (read-line in)))
(read-line in nil)
(read-line in nil)
(setq *M* (parse-integer (read-line in)))
(read-line in nil)
(read-line in nil)
(setq *Matrix* (make-array '(*N* *M*) :initial-element 1))
(loop for i from 0 to *N*
do (loop for j from 0 to *M*
do (setf (aref *Matrix* i j)
(read-char in))))
(read-line in nil)
(setq *Start* (read-line in))
(read-line in nil)
(setq *Goal* (read-line in))))
第三個問題:看起來你放棄了那些你需要的行數太多。
(defvar *N*)
(defvar *M*)
(defvar *Goal*)
(defvar *Start*)
(defvar *Matrix*)
(defun read-matrix (file)
(with-open-file (in file
:direction :input)
(read-line in nil) ; "ROWS"
(setq *N* (parse-integer (read-line in)))
(read-line in nil) ; "COLUMNS"
(setq *M* (parse-integer (read-line in)))
(read-line in nil) ; "MATRIX"
(setq *Matrix* (make-array '(*N* *M*) :initial-element 1))
(loop for i from 0 to *N*
do (loop for j from 0 to *M*
do (setf (aref *Matrix* i j)
(read-char in))))
(read-line in nil) ; "START"
(setq *Start* (read-line in))
(read-line in nil) ; "GOAL"
(setq *Goal* (read-line in))))
第四個問題:使陣列形式的需求數量來設置它的尺寸,但你給它兩個符號來代替。你需要評估這些符號,以獲得您想要的值:
(defvar *N*)
(defvar *M*)
(defvar *Goal*)
(defvar *Start*)
(defvar *Matrix*)
(defun read-matrix (file)
(with-open-file (in file
:direction :input)
(read-line in nil) ; "ROWS"
(setq *N* (parse-integer (read-line in)))
(read-line in nil) ; "COLUMNS"
(setq *M* (parse-integer (read-line in)))
(read-line in nil) ; "MATRIX"
(setq *Matrix* (make-array (list *N* *M*) :initial-element 1))
(loop for i from 0 to *N*
do (loop for j from 0 to *M*
do (setf (aref *Matrix* i j)
(read-char in))))
(read-line in nil) ; "START"
(setq *Start* (read-line in))
(read-line in nil) ; "GOAL"
(setq *Goal* (read-line in))))
第五個問題:看來您希望您的基質含有位,但你只把字符轉換成它。最重要的是,你的矩陣甚至不會包含#\1
(在字符),您期望1
(在號)和#\0
,你期待一個0
,而是以下(假定Unix風格的換行符) :
#2A((#\1 #\Space #\1 #\Space #\1)
(#\Space #\1 #\Space #\1 #\Newline)
(#\1 #\Space #\1 #\Space #\0)
(#\Space #\1 #\Space #\1 #\Newline)
(#\1 #\Space #\1 #\Space #\0))
來完成你想要什麼,我建議閱讀的矩陣線,然後將它們分開的空間和分析等領域。一個方便的庫是split-sequence
。
(defvar *N*)
(defvar *M*)
(defvar *Goal*)
(defvar *Start*)
(defvar *Matrix*)
(defun read-matrix (file)
(with-open-file (in file
:direction :input)
(read-line in nil) ; "ROWS"
(setq *N* (parse-integer (read-line in)))
(read-line in nil) ; "COLUMNS"
(setq *M* (parse-integer (read-line in)))
(read-line in nil) ; "MATRIX"
(setq *Matrix* (make-array (list *N* *M*) :initial-element 1))
(loop :for i :from 0 :to *N*
:do (let* ((line (read-line in))
(fields (split-sequence:split-sequence #\Space line))))
(loop :for field :in fields
:for j :upfrom 0
:do (setf (aref *matrix* i j)
(parse-integer field))))
(read-line in nil) ; "START"
(setq *Start* (read-line in))
(read-line in nil) ; "GOAL"
(setq *Goal* (read-line in))))
在這一點上,本應「工作」,爲「工作」的某些價值(我沒有測試過,雖然)。
然而,大約30年前,使用全局變量傳遞信息已被證實爲不實用。把它變成一個更適合強大程序的風格的第一步就是從函數返回值。
(defun read-matrix (file)
(let (n m goal start matrix)
(with-open-file (in file
:direction :input)
(read-line in nil) ; "ROWS"
(setf n (parse-integer (read-line in)))
(read-line in nil) ; "COLUMNS"
(setf m (parse-integer (read-line in)))
(read-line in nil) ; "MATRIX"
(setf matrix (make-array (list n m) :initial-element 1))
(loop :for i :from 0 :to n
:do (let* ((line (read-line in))
(fields (split-sequence:split-sequence #\Space line))))
(loop :for field :in fields
:for j :upfrom 0
:do (setf (aref matrix i j)
(parse-integer field))))
(read-line in nil) ; "START"
(setf start (read-line in))
(read-line in nil) ; "GOAL"
(setf goal (read-line in)))
(values n m goal start matrix)))
我認爲你真正需要的是一個結構或類,你在這裏閱讀的內容。它可能被稱爲game-state
。然後
(defclass game-state()
((rows :accessor rows :initarg :rows)
(columns :accessor columns :initarg :columns)
(goal :accessor goal :initarg :goal)
(start :accessor start :initarg :start)
(board :accessor board :initarg board)))
你的功能應該命名爲read-game-state
,並返回這個類的一個對象。
對不起,我不知道爲什麼格式有這種方式。 – user1673162