2016-04-21 93 views
0

我使用Realm of Racket書中給出的存根作爲基礎,構建了一個tick-tack-toe遊戲的AI。到目前爲止,一切都進展順利。但是,當我嘗試在樹的根上運行我的minimax函數時,它將返回可以通過運行它獲得的最低可能值列表(以任一播放器作爲謂詞)。
下面是函數的代碼轉儲:Minimax算法不起作用

(define (minimax tree player depth) 
    (define (generate-score tree player depth) 
    (define won (winner (ttt-tree-board tree))) 
    (if (<= depth 0) 0 
     (+ (cond 
      [(equal? won player) 1] 
      [(false? won) 0] 
      [else -1]) 
      (apply + 
        (for/list ([t (ttt-tree-moves tree)]) 
        (generate-score (second t) player (sub1 depth))))))) 
    (for/list ([t (ttt-tree-moves tree)]) 
    (generate-score (second t) player depth))) 

這只是我的minimax功能,因爲沒有其他人(除了winner)的需要顯示。這是winner

(define (winner board) 
    (or 
    (ormap (lambda (row) (if (all-equal? row) (first row) #f)) board) ; Horizontal 
    (ormap (lambda (i) (if ; Vertical 
         (all-equal? (map (lambda (j) (list-ref (list-ref board j) i)) (stream->list (in-range (length board))))) 
         (list-ref (first board) i) #f)) 
      (stream->list (in-range (length board)))) 
    (if ; Diagonal 
    (all-equal? (map (lambda (i) (list-ref (list-ref board i) i)) (stream->list (in-range (length board))))) 
    (first (first board)) #f) 

    (if ; Diagonal cont. 
    (all-equal? (map (lambda (i) (list-ref (reverse (list-ref board i)) i)) (stream->list (in-range (length board))))) 
    (last (first board)) #f))) 

(這是一個有點草率,因此,如果任何人有一個想法,把它縮短,告訴我你的建議)
ttt-tree結構遵循此模式:

(ttt-tree board moves) 

在其中board是與tick-tack-toe板(形式爲'((X - O) (O X -) (- X O)))相對應的2D陣列,並且moves是可以從該節點製作的可能移動的列表,其中每個移動都是具有兩個元素的列表:位置那改變了,並且ttt-tree形成下一個節點。所以(second t)指到下一個節點,如果t(list-ref (ttt-tree-moves #<ttt-tree>) x)

我最初的想法是,有可能是在cond一些錯誤,但我使用equal?eq?,所以我看不出這將是一個問題。另一種可能性是我錯誤地定義了winner,但我已經測試了很多次,所以我不知道會出現什麼問題。請幫忙!
(我全碼:http://paste.ofcode.org/AYez79zTQksys3CU7KJBZV

回答

1

事實證明,問題是,在我的winner功能,我從來沒有檢查,如果冠軍是"-",空瓦。因此,在大多數情況下會觸發else子句並導致-1分。