5

Clojure を学ぶために、ちょっとした Tic Tac Toe ゲームに取り組んでいます。ゲームの最初の部分を比較的簡単に完了した後、インテリジェントなコンピューター プレーヤーを作成するのに苦労しました。

これをガイドするために書いているテストでは、コンピューターの番で、これがボードである場合、コンピューターがスポット 9 を選択することを確認したいと思います。

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

ゲームを開始するには、ボード上の位置とそのスペースの内容を表すキーと値のペアを持つマップとして、ボードを次のように定義します。

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

この問題を解決する方法について、いくつかの考えがありました。1 つは、ウィニング セットを次のように定義することでした。

(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)]])

各セットを反復します。

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

しかし、それは正しくないようです...そこからどこへ行くのかわかりません。私が解決しようとしている問題は、次のように説明できます。

コンピューターに 8 つのウィニング セットを調べて、2 つのシンボル1 つのオープン スポットがあるセットを 1 つ見つけるように指示します。

私は Clojure にかなり慣れていないので、この問題に取り組む最善の方法を理解しているかどうかはわかりません。私はClojureDocsforを見てきました(とのような反復関数をチェックアウトしています)が、これloopを機能caseさせることができませんでした。

現在ベクトル形式であるこれらの勝利セットを繰り返し処理し、特定のシンボルが 2 つと開始点が 1 つあるセットを見つける最良の方法は何でしょうか? それとも、勝利セットを別のデータ構造に保存するのが最善でしょうか?

注:この質問への回答を読みましたが、私の回答に適用できませんでした。

4

1 に答える 1

4

まず第一に、取締役会のポジションには次の構造を使用することをお勧めします。

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

X は1、O は-1、空のセルは0です。私の例のボードには、(単純化するために) X シンボルしかありません。次、

(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]]))

これは、座標の「勝利」セットです。必要に応じてこれを計算できますが、3x3 の場合、このリストはそれほど大きくありません。この条件では、あなたの質問に対する答えは

(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)

このコードを REPL で実行すると、次のように表示されます。

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]])

これは正しい答えのように見えます (2 本の水平線、1 本の垂直線、1 本の対角線)。コードはラフであり、より美しく再利用可能にする方法はほとんどありません。何が起こっているかを説明する必要がありますか、それともコードは十分に明確ですか?

于 2012-10-29T21:34:25.170 に答える