web-dev-qa-db-ja.com

チェス:チェックメイトが行われたかどうかを効率的に決定

この質問 は、チェスエンジンの構築を扱います。私はちょうどそれをやった、そして私の控えめな意見ではかなりエレガントに。しかし、私には終了条件がありません。

ここに私が使用するいくつかの擬似Python関数があります。

# Move from position old to new
def move(old, new):
    if is_legal(old, new):
        # Eat and move
        if is_legal(new, enemy_king) or check_in_los(enemy_king, old):
            # Set check on enemy king
        if piece_type == 'Pawn' and position at the end of board:
            # Convert to Queen

def is_legal(old, new):
    # Assure piece is moving, it's your own and new position not on another own piece
    # Based on piece type, assure it's maneuvering properly
    # Assure there are no pieces in between the positions if applicable

    if piece_type == 'King':
        is_checked(new)  # Not moving to a checked square
    Elif checked:
        # Assure check is removed
    else:
        check_in_los(own_king, old)  # Moving the piece does not create a check from behind

# Determine if king is checked from line of sight
def check_in_los(king_pos, direction):
    # Divide path into single-square steps
    # Find next piece in direction by incrementing king position by step
    if is_legal(next, king_pos):
        # King is checked from direction

# Determine if king is checked
def is_checked(king_pos):
    # Check if knight positions around kings contain enemy knights
    # For every 8 directions around king, check_in_los(king, direction)

チェックメイトに移りましょう。王が正当な位置にいるなら、王の周りのすべての位置を確認するのは簡単ですが、それだけでは十分ではありません。

白い王が脅かされている次のシナリオを考えてみましょう:

   A    B    C    D    E    F    G    H
1  BR |    | BR |    |    |    |    |   
2     |    |    |    |    |    |    |   
3     |    |    |    |    |    |    |   
4     |    |    |    |    |    |    |   
5     |    |    |    |    |    |    |   
6     |    |    |    |    |    |    |   
7     |    |    |    | WN |    |    |   
8     | WK | BQ |    |    |    |    |   

王(B8)には法的な動きは残っていませんが、騎士(E7)は女王を食べることで彼を救うことができます。同様に、クイーンの配置が切り替えられ、代わりにナイトがルークである場合:

   A    B    C    D    E    F    G    H
1  BR |    | BR |    |    |    |    |   
2     |    |    |    |    |    |    |   
3     |    |    |    |    |    |    |   
4     | BQ |    |    |    |    |    |   
5     |    |    |    |    |    |    |   
6     |    |    |    |    |    |    |   
7     |    |    |    | WR |    |    |   
8     | WK |    |    |    |    |    |   

白いルークはB7に移動することで王を救うことができます。

仲間をチェックするための素朴なアプローチは、すべての可能性をチェックすることを含むと思いますが、それは無駄に見えます。

これを達成するための良い方法は何でしょうか?できれば、すでに用意されている機能を使用します。必要に応じて、他のアプローチも受け入れます。チェックのピース、またはチェックされているすべての四角形、および各ピースのチェックのパターンを個別に追跡することは役立つと思いましたが、よくわかりません。

3
Felix

これは、人間の心がコンピュータよりも優れている状況の1つです。チェスのポジションがチェックメイトであるかどうかを人間が決定するのはかなり簡単です。

ほとんどの動きは、位置に関係がないとして破棄できます。これらの動きを破棄するアルゴリズムを作成するのは非常に困難です。

すべての可能な動きを通過するだけの簡単な解決策(多くの場合、ボード上に多数のピースがあり、多くの場合40-50の範囲になる可能性があります)は素朴ですが、高速で、デバイスを試すよりもはるかに少ない労力しか使用しませんポジションがチェックメイトかどうかを決定するアルゴリズム。

騎士と司教が王をチェックする位置をイメージすると、騎士を取ることができますが、それでも司教からのチェックです。または、クイーンをチェックしてキングをチェックすることもできますが、それを実行できるピースは、ルークからチェックされるため、移動できません。

非常に複雑になり、非常に速くなります。プログラムの他の部分の改善に同じ時間を費やしてみませんか?

これが、Ewanがコメントで言及した https://chess.stackexchange.com/questions/13871/check-for-checkmate が、ストックフィッシュがすべての動きを試み、何もない場合は、法的移動は、チェックメイトです(そもそもチェックがない場合は、古いメイトと同様です)。

2
Bent

考えられるすべての動きを生成し、それらを最良に評価する場合、取る可能性のあるピースの価値を確実に考慮する必要があります。

同じ方法を使用して、王に非常に高い値を与えます。それが通常のアプローチです。
チェックメイトを認識するための魔法の近道はありません-それはdefinedであることを覚えておいてください。

王の捕獲の前にチェスゲームを1動き止めることは歴史的な礼儀です。プログラムで同じことを行うのは問題ありませんが、別のメカニズムを考案する必要も利益もありません。

2
Aganju

この要件は、ゲームの各ポイントで行う最善の動きを決定するルーチンから外れるだけではありませんか?

王を抑えて移動を終了することはできません。これは有効な移動ではないので、移動ルーチンはそれを選択してはなりません。

ですから、対戦相手の動きが終わったら、通常どおりできる最善の動きを決定してみてください。正当な動きがない場合、ゲームは終了です。キングが現在チェックされている場合、それはチェックメイトです。それ以外の場合は、ステイルメイトです。

2
Simon B