2014-03-06 61 views
-1

我正在寫一個功能,需要一個單一的戰鬥騎士名單。運行他們戰鬥的代碼正在工作(角逐遊戲),現在我正在編寫一個錦標賽系統,我無法讓我的錦標賽開始工作。正如我所說,它需要一個騎士名單,並讓他們遞歸戰鬥,直到每個人都參加戰鬥,並返回兩個名單,一個贏家,一個失敗者。我嘗試了我所知道的一切,無論我做什麼,我都會遇到錯誤,代碼拒絕工作,我不明白爲什麼。這是我到目前爲止已經寫的:我是新來的計劃,我不知道什麼是錯的

(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的一些重要內容,而且我真的可以使用一個解釋。

感謝所有幫助下,問題已經解決

+7

您的縮進全部錯誤! – leppie

+1

提示:'(贏家......';不看猶太教(缺少'let'?) – leppie

+0

忽略縮進問題@leppie,(獲獎者)部分看起來工作正常,實際上,似乎並不 – user2904660

回答

1

首先認爲你應該知道方案是詞法範圍的。變量聲明僅在聲明的代碼框架或子框架中有意義。

此外,你用雙括號打開,這通常不是你想要做的,除非內部集合返回一個函數並且你想應用它。

你漂亮的打印是離開的。 Cond語句應該在一行中,或排列在該子句的第二個括號中。 If只有三個子句,並且應該再次全部在同一行上,或者在隨後的行中與第一個參數對齊。 let聲明的函數體應該與let的「e」或「t」對齊。在他們自己的路線上的拖尾分句通常是不被接受的。反覆遞歸

呼叫長度是壞的形式,length是O(n)的操作,以列表的長度剛剛檢查,如果該列表爲空或CDR是空

並且你確實需要和內在的功能來做你想做的事情。(內定義,letrec或​​命名讓我會做)

如果你像(append <some-list> (list <some list element>))追加你做得很差。首先是append是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)))))))  
+1

這裏有一本小書叫做小謀士,在寫一個基本的思維模式對編寫計劃程序非常有用的時候,這非常棒。 – WorBlux

+0

謝謝,這真的很有幫助,但我應該提到我沒有被允許使用循環。我也已經修復了代碼,我仍然需要關閉這個請求。不過謝謝,這看起來很酷。 – user2904660

+1

一個名爲let的不是一個循環。我可以將它命名爲'內部'或'助手'來獲得相同的結果,它只是比letrec有一點點的synactic糖。 (let name((arg1 val1)(arg2 val2)...)body)與(letrec((name(lambda(arg1 arg2 ...)body)))(name val1 val2 ...)) – WorBlux

0

當我看到這裏,你有多個問題...

(define (playTourneyRound knightList) 
    (
    ... 
) 
) 

在這裏你有沒用括號,這意味着你要執行在(...)之間將要評估的返回的第一條語句。既然你跟着cond然後(list '() '())。它沒有多大意義......

你可以寫這個想法:

(define (playTourneyRound knightList) 
    (begin 
    ... 
) 
) 

但這是綽綽有餘沒有任何東西:

(define (playTourneyRound knightList) 
    ...) 

而且,我能說什麼,現在是因爲你所做的一切都沒有副作用,它永遠不會追加任何東西或改變任何物體你可能想寫的是:

(set! winners (append ...)) 
(set! loosers (...)) 

但是因爲你沒有調用其他任何東西,並且你函數中的最後一個語句返回了一個空列表的列表......該函數沒有做任何事情,也不遍歷元素列表。

你應該嘗試一些更簡單的事情。

+0

我很困惑,我想定義一個函數,你必須打開和關閉括號來定義正在執行的功能?我真的沒有計劃,我更習慣於C++風格的語法。 – user2904660

+0

@ user2904660在C/C++和Lisp風格的語言之間有一個根本的區別。查找S表達式,因爲這是一切和唯一的數據結構,都是基於代碼和數據的。 –

+0

啊,我現在明白好多了。謝謝,我不明白,一切都是對象列表,函數調用是接受特定數量輸入的對象。我看到我基本上是將更多的參數輸入到函數調用期望的函數中。這使現在更有意義。非常感謝。 – user2904660

相關問題