我使用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)