访问和更改使用“define”创建的值
我正在制作一个游戏,我有这样的:
(define b "black piece") (define w "white piece")
(define (board)
(lambda (matrix)
(list ((b w b w b w b w)
(w b w b w b w b)
(b w b w b w b w)
(w b w b w b w b)
(b w b w b w b w)
(w b w b w b w b)
(b w b w b w b w)
(w b w b w b w b)))))
board
制作一个包含 8 行和 8 列黑白棋子的列表。
如何访问和更改看板的元素?如何使用递归来制作过程矩阵?
I'm making a game, and I have this:
(define b "black piece") (define w "white piece")
(define (board)
(lambda (matrix)
(list ((b w b w b w b w)
(w b w b w b w b)
(b w b w b w b w)
(w b w b w b w b)
(b w b w b w b w)
(w b w b w b w b)
(b w b w b w b w)
(w b w b w b w b)))))
board
makes a list with 8 lines and 8 columns of black and white pieces.
How do I access and change elements of the board? How do I do the procedure matrix with recursion?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先是一些注意事项:
(定义 f (lambda (x) l ))
与
相同
(定义(fx)l))
然而,您将它们与
结合起来
(定义(板)(lambda(矩阵)l))
这与
相同
(define board (lambda () (lambda (matrix) l )))
区别很重要。前两个我列出了将 f 绑定到一个带有一个参数并返回 l 的函数。我猜这就是你想做的。在后两个中,您将 board 绑定到一个不带参数的函数,并返回一个带 1 个参数矩阵的函数(它似乎没有做任何事情),并返回一个 l。
第二个问题,
(list ((b w....) ...))
不起作用,因为它将尝试评估(bw ...)
。您需要在板的每一行的函数应用程序位置中都有列表,如下所示(list (list bw ...) (list wb ...) ...)
以便编写代码甚至编译。关于你的问题。 link-ref 包含在racket/base中,当您知道列表中的索引时,用于引用列表中的元素。
(list-ref 2 (列表 'a 'b 'c 'd))
将返回'c。索引从 0 开始。由于您有一个列表列表,因此您需要应用 list-ref 两次来检索 'b 或 'w。
至于改变它,嗯,你不能。从 r6rs 开始,对(组成列表)是不可变的。如果可能的话,推荐的做法是返回包含更改的新列表。您可以使用这个有点低效的
list-set
版本,它返回列表的副本,并在索引处包含您的新值。然而,在这种情况下,我建议切换到更适合手头任务的不同数据结构,因为您可能需要 O(1) 访问板中的元素。查看向量,它们的行为与列表非常相似,但用于不断的查找和更新。有一个内置的
vector-ref
和vector-set!
操作,您应该使用它们来代替我上面的函数。如果这是一个更大问题的一部分,并且您已经在各处使用列表,则可以使用
vector->list
和list->vector
函数返回等等。另外,您可以使用可变列表,但不要这样做。更好的是 srfi/25 中提供的多维数组库,但是可能比您想要的更复杂。
你问题的第二部分是如何递归地构建棋盘。嗯,这是一个使用地图的版本。
这是一个递归版本
first a few notes:
(define f (lambda (x) l ))
is the same as
(define (f x) l ))
You however are combining them with
(define (board) (lambda (matrix) l ))
which is the same as
(define board (lambda () (lambda (matrix) l )))
The distinction is important. The first two I have listed bind f to a function that take one parameter and return l. I'm guessing this is what you want to do. In the second two, you're binding board to a function that takes no parameters and returns a function that takes 1 parameter, matrix, (which it doesn't seem to do anything with), and returns a l.
second issue,
(list ((b w....) ...))
isn't going to work because it will try to evaluate(b w ...)
. you need to have list in the function application position for each row of your board like so(list (list b w ...) (list w b ...) ...)
in order for you code to even compile.On to your question. link-ref is included in racket/base and is used for referencing elements in a list when you know the index into the list.
(list-ref 2 (list 'a 'b 'c 'd))
will return 'c. The index starts at 0. Since you have a list of lists, you will need to apply list-ref twice to retrieve a 'b or 'w.
As for changing it, well, you can't. As of r6rs, pairs (which make up lists) are immutable. The recommended way of doing things when possible is to return a new list with your change. you can use this somewhat inefficient version of
list-set
which returns a copy of the list with your new value at an index.In this case however, I would recommend switching to a different data structure more appropriate to the task at hand since you probably want O(1) access to the elements in the board. Look into vectors which behave much like lists but are used for constant lookups and updates. there is a built in
vector-ref
andvector-set!
operations, which you should use instead of my above function.Incase this is part of a larger problem and you're already using lists everywhere, you can use the
vector->list
andlist->vector
functions to go back and forth. Also, you can use mutable lists but don't.Better still is the multidimensional array library offered in srfi/25, but that might be more complicated that you want to get.
The second part of your question was how to construct the board recursively. Well, here's a version using map.
and here's a recursive version