I';我对scheme还不熟悉,我不熟悉';我不知道是什么';这是不对的
我正在写一个函数,它只包含一个战斗的骑士列表。运行他们战斗的代码正在运行(格斗游戏),现在我正在编写一个锦标赛系统,我无法让我的锦标赛回合运行。正如我所说,它需要一个骑士列表,让他们反复战斗,直到每个人都战斗过,然后返回两个列表,一个是赢家,一个是输家。我已经尝试了我所知道的一切,无论我做什么,我都会得到一个错误,代码拒绝工作,我不明白为什么。以下是我到目前为止所写的内容:I';我对scheme还不熟悉,我不熟悉';我不知道是什么';这是不对的,scheme,chicken-scheme,Scheme,Chicken Scheme,我正在写一个函数,它只包含一个战斗的骑士列表。运行他们战斗的代码正在运行(格斗游戏),现在我正在编写一个锦标赛系统,我无法让我的锦标赛回合运行。正如我所说,它需要一个骑士列表,让他们反复战斗,直到每个人都战斗过,然后返回两个列表,一个是赢家,一个是输家。我已经尝试了我所知道的一切,无论我做什么,我都会得到一个错误,代码拒绝工作,我不明白为什么。以下是我到目前为止所写的内容: (define (playTourneyRound knightList) ( (cond
(define (playTourneyRound knightList)
(
(cond
((> (length knightList) 1)
(let (
(winner (jousting-game (car knightList) (cadr knightList)))
(winners (list))
(losers (list))
(results (playTourneyRound (cddr knightList)))
)
(if (= winner 1) (winners (append winners (list (car knightList)))) (winners (append winners (list (cadr knightList)))))
(winners (append (car results)))
(losers (list (cadr knightList) (cadr results)))
(list winners losers)
)
)
((= (length knightList) 1)
(list knightList)
)
)
(list '() '())
)
)
有人能给我解释一下为什么会出现错误“非过程调用:#”,以及我以后如何避免这个错误?我肯定我只是不理解scheme/lisp中一些重要的东西,我真的需要一个解释
谢谢你的帮助,问题已经解决了,正如我在这里看到的,你有多个问题
(define (playTourneyRound knightList)
(
...
)
)
这里有无用的括号,这意味着您将执行将在(…)
之间求值的内容返回的第一条语句。因为您使用的是条件
,所以(列表“()”())
。这没有多大意义
你可以写下这样的想法:
(define (playTourneyRound knightList)
(begin
...
)
)
但没有任何东西,这就足够了:
(define (playTourneyRound knightList)
...)
此外,我现在可以说的是,由于您所做的一切都没有副作用,因此它永远不会附加任何内容或更改任何对象。您可能希望编写的内容是:
(set! winners (append ...))
(set! loosers (...))
但由于您不调用任何其他函数,并且函数中的最后一个语句返回一个空列表列表。。。该函数不执行任何操作,也不迭代元素列表
你应该试试更简单的 首先,您应该知道scheme是词汇范围的。变量声明仅在其声明的代码帧或子帧中有意义 此外,您还使用双括号打开,这通常不是您想要做的,除非内部集合返回一个函数,并且您想要应用它 你漂亮的印刷品太差了
Cond
语句应在一行中,或在子句的第二个括号中对齐If
只有三个子句,并且应该再次全部在同一行上,或者在与第一个参数对齐的后续行上。let
语句的函数体应该与let的“e”或“t”对齐。在他们自己的路线上拖尾的parnethesis通常是不受欢迎的
在递归中重复调用length是一种糟糕的形式,因为length
是对列表长度的O(n)操作,只需检查列表是否为null或cdr是否为null
你真的需要和内在的功能去做你想做的事情。(内部定义、letrec或命名let即可)
如果你像(append(list))
那样追加,那你做得很糟糕。First offappend
是第一个参数长度的O(n)。继续按相反的顺序累积结果,并在最后反转
(define (playTourneyRound knightList)
(let loop ((knights-L knightList) ;;named let
(winners (list))
(losers (list)))
(cond ((null? knight-L) (map reverse (list winners losers))) ;;length = 0
((null? (cdr knight-L) ;;lenght = 1
(loop (cdr knight-L)
(cons (car knight-L) winners)
losers))
(else ;; length > 1
(let* ((winner (jousting-game (car knight-L) (cadr knight-L)))
;;assuming that jousting-game return the winning knight
(loser (if (equal? winner (car knight-L))
(cadr knight-L)
(car knight-L))))
(loop (cddr knight-L)
(cons winner winners)
(cons loser losers)))))))
你的缩进全错了!提示:
(winners…
;看起来不洁(缺少一个让?)忽略缩进问题。@leppie,(winners)部分似乎工作正常,实际上,这似乎不是问题。(winners…
事情可能是错的,因为这就像调用一个名为winners
的函数。但在你的例子中,它是一个列表
@LoïcFaure Lacroix我想返回一个赢家列表和一个输家列表,它没有任何问题,它甚至没有走那么远,因为它即将进入锦标赛a的末尾ND试图返回一个空列表,但无法返回空列表。我不明白为什么,但我通常不使用LISP风格的语言。我很困惑,我想定义一个函数,你必须有开和关括号来定义正在执行的函数吗?我真的没有得到方案,我更习惯于C++风格的语法。@使用r2904660 C/C++和Lisp风格的语言之间有一个根本的区别。查找S表达式,因为它是所有东西都建立在其上的唯一数据结构,包括代码和数据。啊,我现在明白得多了。谢谢,我不明白所有东西都是对象列表,函数调用是接受特定nu的对象输入的数量。我知道我基本上是在函数中输入了比函数调用所期望的更多的参数。这现在变得更有意义了。非常感谢。@user2904660没问题都德:)Lisp风格的语言与C风格的语言非常不同,函数范式加上同音象似性和强大的宏系统使Scheme成为一种非常强大的语言。有一本叫做little schemer的小书,它非常擅长探索一种对编写Scheme程序有用的基本思维方式。谢谢,这是真的这很有帮助,但我应该提到我不允许使用循环。我也已经修复了代码,我仍然需要关闭此请求。尽管如此,这看起来非常酷。命名let不是循环。我可以将其命名为“内部”或“帮助器”,以获得相同的结果,它只是比letrec多一点合成糖。(let name((arg1 val1)(arg2 val2)…)body)与(letrec((名称(lambda(arg1 arg2…)body))相同(名称val1 val2…)