第一个问题:您打开一个文件,但从不关闭它。使用时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))))
第四个问题:make-array 形式需要数字来设置它的维度,但是你给它两个符号。您需要评估这些符号以获得所需的值:
(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))))
第五个问题:您似乎希望矩阵包含位,但您只将字符放入其中。最重要的是,您的矩阵甚至不会包含您期望的(the number ) 和期望a 的#\1
(the character ) ,而是包含以下 (假设 Unix 样式的换行符):1
#\0
0
#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
并返回此类的对象。