2011-08-12 20 views
3

私はチック・タック・トー・ゲームを開発しています。ゲームが終わる(そして勝った)ときをチェックするアルゴリズムが必要です。 3x3のゲームでは、私はそれぞれの可能な勝利状況をチェックします(8つの能力があります)。しかし、7x7(行または柱、または対角線の4つの記号が必要)は、可能な勝利パターンの多くです。tic-tac-toeでゲーム終了を判断する方法は?

+0

java example、note gameover()[link](http://www.dreamincode.net/code/snippet1414.htm) – mbowles

+0

@mbowlesこれは、tic-tac-toeのためのものです。これは、N行のN行では失敗します。 –

答えて

4

非常に基本的なアプローチは、すべての単一セルからすべての方向にランを見ることですが、ここでアプローチは1つの「ライン」内のセルを1回だけチェックします。 「行」は、おそらく、:)ラスベガスのスロットマシンのように、各「行」について

  1. を獲得する「行」の開始に移動することができ、行、列、または対角線です。 (順番にライン横断)「線」の各セルについて0
  2. から
  3. セットカウンタ:
    • 細胞がP1の場合、カウンタはカウンタに1を追加し、> = 0である
      • カウンタが4の場合、P1が勝ちます。
    • 細胞がP1とカウンタが負である場合、細胞はP2とカウンタ= 0 <である場合、カウンタ0
    • に設定し、カウンタ場合カウンタ
      • から1を減算= -4次いでP2セルがP2で、カウンタが0
にカウンタ設定、正の場合
  • 重要編集:セルにP1またはP2が含まれていない場合は、カウンタを0にリセットします(doh!)。私はこの些細ではあるが必須のステップを省いた。それ以外の場合、「11-11」は勝利としてカウントされます。

    「線」は、反復ごとに開始点と行/列オフセット(たとえば、NWからSEまでの最長対角線の場合は(0,0)および前進(1,1)で始まる)を渡って移動できます。長さが4未満の対角線は、もちろん、完全にチェックされることを避けることができます。

    ハッピーコーディング。

  • 2

    すべての位置がループします。各位置について、4つのフィールドを斜め右下にチェックします(常にフィールド自体を含む)。あなたが存在しないフィールドをチェックしているときにアプリケーションを爆発させないように適切なチェックをしてください。

    +0

    1つの方法は、チェック中に開始位置から「移動する」再帰を使用することです。 –

    0

    シンプルです。 4 forループをすべての行、列に対して行い、対角線を増加させ、対角線を減少させます。 それぞれ4つの連続した部分があるかどうかをテストします。

    34

    各プレイヤーにbitboardを使用している場合は、ビットシフト操作を使用してボードの勝利をテストできます。

    ビットボードは、構造次有するであろう:

    6 14 22 30 38 46 54 
    5 13 21 29 37 45 53 
    4 12 20 28 36 44 52 
    3 11 19 27 35 43 51 
    2 10 18 26 34 42 50 
    1 9 17 25 33 41 49 
    0 8 16 24 32 40 48 
    

    をプレイヤがゲームボード内の位置を占めている場合、対応するビットがビット1さもなければ0(通知であろう7、15、23、..が0)。プレイヤーは次の機能を使用でき勝っボードがあるかどうかを確認するには、次の例の助けを借りて

    bool haswon(int64_t board) 
    { 
        int64_t y = board & (board >> 7); 
        if (y & (y >> 2 * 7)) // check \ diagonal 
         return true; 
        y = board & (board >> 8); 
        if (y & (y >> 2 * 8)) // check horizontal - 
         return true; 
        y = board & (board >> 9); 
        if (y & (y >> 2 * 9)) // check/diagonal 
         return true; 
        y = board & (board >> 1); 
        if (y & (y >> 2))  // check vertical | 
         return true; 
        return false; 
    } 
    

    を私が説明しようとします:1人のプレーヤーの以下のビットボードは、垂直、斜め勝利のそばでの勝ちの組み合わせを含んでいます最初の行

    0101010 
    1110111 
    0111011 
    1101110 
    0001000 
    1010101 
    0011110 ... four occupied positions --> winning board 
    

    水平チェックする手順は、次のとおり

    1. y = board & (board >> 8)

      0101010 0010101 0000000 
      1110111 0111011 0110011 
      0111011 0011101 0011001 
      1101110 & 0110111 = 0100110 
      0001000 0000100 0000000 
      1010101 0101010 0000000 
      0011110 0001111 0001110

    2. y & (y >> 2 * 8)

      0000000 0000000 0000000 
      0110011 0001100 0000000 
      0011001 0000110 0000000 
      0100110 & 0001001 = 0000000 
      0000000 0000000 0000000 
      0000000 0000000 0000000 
      0001110 0000011 0000010

    1ビットがセットされた基板に水平なチェックの結果、これは、ボードには勝利が含まれ、関数はtrueを返します。

    私はsimilar functionを使って勝利のためにconnect fourゲームをチェックしました。私はこの魅力的な機能をソースで見つけました。がJohn Trompです。

    +0

    Boggles my mind、+1 –

    +0

    実際にyの '(行>> 1)'をしていませんか? 「0011110 == 30」と「30 >> 8 == 0」であるためです。一方、 '30 >> 1 == 15 == 0001111' – naeg

    +1

    @naeg:実際にボード全体がシフトして、1つの行が1ビットシフトされる必要があります。ボード全体が8だけシフトする必要があります。 '誤解を招く。 –