2012-10-29 10 views
5

Aby dowiedzieć się Clojure, pracuję nad małą grą w Tic Tac Toe. Po dość szybkim ukończeniu pierwszej części gry, starałem się zbudować inteligentnego gracza komputerowego.Clojure: Iterowanie nad wektorami wektorów, aby znaleźć pierwszy wektor, który spełnia pewien warunek.

Do testu piszę, aby pomóc tym, chcę, aby sprawdzić, czy komputer odbiera miejsce 9 czy to Włącz komputer i to jest rada:

X | O | 3
4 | X | O
7 | 8 | 9

Aby rozpocząć grę, płyta jest zdefiniowane tak, jak mapa z par klucz-wartość reprezentująca położenie na planszy i zawartości tej przestrzeni:

(def board {1 "1" 2 "2" 3 "3" 4 "4" 5 "5" 6 "6" 7 "7" 8 "8" 9 "9"}) 

miałem kilka myśli o tym, jak rozwiązać ten problem. Jedno było określenie zwycięskie sety jak to:

(def winning-sets 
    [[(board 1) (board 2) (board 3)], 
    [(board 4) (board 5) (board 6)], 
    [(board 7) (board 8) (board 9)], 
    [(board 1) (board 4) (board 7)], 
    [(board 2) (board 5) (board 8)], 
    [(board 3) (board 6) (board 9)], 
    [(board 1) (board 5) (board 9)], 
    [(board 3) (board 5) (board 7)]]) 

iteracyjne nad każdym zestawie:

(for [set winning-sets] 
    (filter #(= symbol %) set)) 

Ale to nie wydaje się słuszne ... Nie wiem gdzie bym go stamtąd . Problem usiłuję rozwiązać można opisać tak:

Powiedz komputer patrzeć na 8 zwycięskich zestawów i znaleźć jeden zestaw, który składa się z dwóch swoich symboli i jednym otwartym miejscu.

Jestem całkiem nowy w Clojure, więc nie jestem pewien, czy rozumiem najlepszy sposób podejścia do tego problemu. Patrzę na ClojureDocs (sprawdzanie funkcji iterujących, takich jak for i loop i case), ale nie udało się tego zrobić.

Jaki byłby najlepszy sposób na powtórzenie tych zwycięskich zestawów, obecnie w postaci wektorowej, i znalezienie zestawu, który ma dwa określone symbole i jedno otwarcie? A może najlepiej byłoby przechowywać zwycięskie zestawy w innej strukturze danych?

UWAGA: Przeczytałem odpowiedzi na this question, ale nie udało mi się zastosować ich do moich.

+0

Myślę, że chcesz mieć jakąś funkcję. – Kevin

Odpowiedz

4

Przede wszystkim radzę używać tej struktury do położenia płytki:

(def board [[1 1 0] 
      [0 0 0] 
      [1 0 1]]) 

Gdzie X jest 1, O jest -1 i pusta komórka jest 0. Tablica w moim przykładzie ma tylko symbole X (w celu uproszczenia). Następnie

(def winning-sets 
    '([[0 0] [0 1] [0 2]] 
    [[1 0] [1 1] [1 2]] 
    [[2 0] [2 1] [2 2]] 
    [[0 0] [1 0] [2 0]] 
    [[0 1] [1 1] [2 1]] 
    [[0 2] [1 2] [2 2]] 
    [[0 0] [1 1] [2 2]] 
    [[0 2] [1 1] [2 0]])) 

To jest "zwycięski" zestaw współrzędnych. Możesz to obliczyć w razie potrzeby, ale dla 3x3 ta lista nie jest tak duża.W tym ujęciu, odpowiedź dla ciebie pytanie jest

(defn check 
    [target combo] 
    (= (map #(count (filter (partial = %) combo)) [target 0]) '(2 1))) 

(defn extract 
    [coords] 
    (apply vector (map (fn [[f s]] ((board f) s)) coords))) 

(filter #(check 1 (extract %)) winning-sets) 

Jeśli wykonanie tego kodu w REPL, widać

user=> (filter #(check 1 (extract %)) winning-sets) 
([[0 0] [0 1] [0 2]] 
[[2 0] [2 1] [2 2]] 
[[0 0] [1 0] [2 0]] 
[[0 0] [1 1] [2 2]]) 

który wygląda właściwej odpowiedzi (2 poziome linie, 1 pionową i 1 przekątnej). Kod jest szorstki i istnieje kilka sposobów, aby uczynić go piękniejszym i wielokrotnego użytku. Czy powinienem wyjaśnić, co się dzieje, czy kod jest wystarczająco jasny?

Powiązane problemy