web-dev-qa-db-ja.com

チェスエンジンを作成するための最良の方法は?

私はチェス愛好家であり、プログラマーです。私は最近、チェスとプログラミングの知識を使用してチェスエンジンの作成を開始することを決定しました。だから私の質問です:

チェスエンジンを作成するときに、どの言語(Java、C++、Pythonに精通している)と方法論を採用する必要がありますか?

少しのガイダンスをいただければ幸いです。

編集:

そこで、JavaScriptで作成することにしました。 githubから this Chess UIをダウンロードしました。これで準備が整いました。私の最初のステップは、そのための法的な動きを書くことです。誰かが私を正しい方向に向けることができますか? (私はjQueryを初めて使いますが、プログラミングの経験は豊富です)。

PS:私は非常に効率的なエンジンを作るつもりはありません(私はその方法が難しすぎることを知っています)。単にプロセスに慣れ、その過程でいくつかの新しい技術を学びたいだけです。

15
Adnan Zahid

2072年の評価のチェスプレイヤーはこちら。私は週末に純粋なJavaScriptで このWebサイト を作成しました。それはチェスエンジンではありません(私は、変なChess960エンジンのような面白い開始位置を作成するように設計しました)が、それは出発点です。ソースコードは here です。

機能的なボードの作成には多くの複雑な問題があります。これらには以下が含まれます:

  • 最初に、基本的な法的動きをどのように表すかを考えます。開始座標と終了座標を使って数学を実行する必要があります。たとえば、ルークムーブでは、座標の1つが前後で同じでなければなりません。騎士の動きでは、座標変化の絶対値の合計は3である必要があり、両方の座標が変化する必要があります。ビショップの動きでは、座標の合計が同じままか、どちらも同じ量だけ増加します。ポーンは、2マスまたは1マス移動できるかどうか(行数と色を確認して、行った移動数を保存するのではなく)を把握する必要があるだけでなく、キャプチャ全体を斜めに処理し、移動する必要があるため、最もトリッキーです-進むこと。
  • ポーンとチェックのため、キャプチャは困難です。駒が別の駒の正方形に移動した場合、それはキャプチャであるとは言えません。結局のところ、ポーンは別の駒のマスに移動してキャプチャすることはできません。それらには独自のキャプチャ方法があります。
  • それが合法であるかどうかを決定するために、敵の駒が駒の移動の邪魔になっているかどうかを確認する効率的な方法を理解する必要があります。
  • チェックは対処するのが困難です。すべての移動の後、敵の駒が移動できるすべてのマスをチェックし、それらの1つがキングに関係しているかどうかを確認する必要があります。
  • キャスリング、アンパッサント、プロモーション、行き詰まり、強制ドロー、繰り返し-問題の規模を考えると、これらのどれも処理するのは簡単ではありません。

すべてのチェスエンジンは、位置の合法的な移動のすべて(おそらくヒューリスティックに決定されたサブセット)を調べ、それらの移動を行い、結果の位置に対して同じことを再帰的に行うことにより、相対値を表す数値を評価します。ここであなたの双子の問題は

  • このデータを効率的に保存する方法
  • この再帰的な検索を続行する方法-結局のところ、それを永遠に続けることはできないので、制限を設定してから、その制限内で最適かつ徹底的な検索を行うためのアルゴリズムを設計する方法を理解する必要があります。たとえば、少なくとも開始の手ごとにいくつかの評価が行われるようにする必要がありますが、すべての手に等しい時間を与えるのではなく、より有望な手を評価するのにより多くの時間を費やすこともできます。

これは、最初からアルゴリズムを設計することに加えて、利用可能な情報がたくさんあります。

どの言語を使用するかについては(JavaScriptをすでに決定していると思いますが)、それは何よりも目的に依存すると思います。私は私のものをオンラインにしたかった(そしてJavaScriptがもっと上手くなりたかった)ので、JavaScriptが私の選択でした。ただし、オブジェクト指向プログラミング言語なら何でもできます。

自分がやっていることに慣れたら、次のリソースがおそらく非常に役立つでしょう。

幸運を!

19
Andrew Latham

「チェスプログラム」をコンセプトにした場合の問題点は、多くの時間を吸収できる作品がたくさんあり、現時点では必ずしも興味がないということです。グラフィックス、アルファベータ検索、または視覚化の作業だけで何年も費やして、検索エンジンの開発に役立てることができます。まあ、たくさんの要素があります。

私はオープンソースのチェスプログラムを見つけることをお勧めします(たくさんあるはずです)、そしてあなたが最も興味を持っている部分の改善に着手します。最終的には、プログラム全体を一度に1つの関数で置き換えるか、十分に学習してやる気になり、それを破棄して独自のプログラムをゼロから設計することができます。いずれにせよ、重要なのは、プログラム全体を構築する前に、「軽い」ことから始め、ロープを学ぶことです。

14
ddyer

チェスのルールに精通している場合は、基本的なテクニックの出発点として最適です http://www.frayn.net/beowulf/theory.html 豊富な資料とリンクのコレクションここ: http://chessprogramming.wikispaces.com/ そして3番目:他のコードから学ぶ。 Crafty のソースをご覧ください。主要なオープンソースエンジンです。テストケースについて考え、改善を加えるかどうかを確認することは非常に重要です。たとえば、3桁または4桁の簡単なエンドゲームポジションから始めます。

9
CSE

先に述べたように、チェスエンジンを構築することはそれほど難しいことではありません。おそらく、これがおそらく言語の選択を決定するため、このアプリケーションをどのように使用し、(潜在的に)デプロイしたいかに集中する必要があります。

これが楽しい演習の場合は、JavaScriptでコーディングして、Webページとしてデプロイすることをお勧めします。あなたがそれをエキスパートのチェスゲームにしたくなければ、少なくとも他の人はそれとそのソースコードで遊ぶことができます。

WPFのように特定のテクノロジーを同時に学びたい場合、これは1石で2羽の鳥を殺すのに良い方法かもしれません。 MVVMはこのアプリにとってはやり過ぎかもしれませんが、少なくともそれを学ぶでしょう。

Androidデバイスをターゲットにする場合は、Javaが適切です。同様に、iOSデバイス用のObjective-Cを使用します。

長くて短く、言語の選択は孤立して存在しません。

3
dave

Min-Max、ツリーとプルーニング、ヒューリスティックおよびその他の基本の概念についてすでに知っていると思います。ここで私が書くことは、過小評価されているかもしれない詳細の一部にすぎません。

私は友人と一緒に、時々前に私たち自身のチェスエンジンを書きました。私たちが抱えていたいくつかの問題とアイデアを共有します。それらが役立つことを願っています。

私たち2人はJavaプログラマだったので、私たちの言語はJavaになり、オブジェクト指向のアプローチから始めました。ピースはオブジェクト、ボードはオブジェクト、ファイル、ランク(チェスの文献の行と列)はオブジェクトでしたが、これは誤りでした。オーバーヘッドが大きく、プログラムは検索ツリーで2移動(4プライ)よりも先に進むのに苦労していました。

そのため、いくつかの検索を行った結果、素晴らしいアイデアが得られました(私たちのアイデアではありません!):ピースとボードをLong整数(64ビット)として表す。チェス盤には64個の正方形があるので、これは理にかなっています。残りはビット単位の操作でした(cpuに非常に近いところで実行=非常に高速)。たとえば、64ビットの2進整数を考えてみましょう。これらの整数は、あなたの駒が攻撃できるボード上の正方形を示しています。このように2つの数値間で論理「AND」を実行すると、ゼロ以外の結果は、攻撃者のいる正方形があることを示します。チェス盤と駒を提示する方法はいくつかあります。

1-あなたの決定 ボードプレゼンテーション

次に、必要なデータベースを開きます。チェスのオープニングは何とか解決されており、オープニングブックを持つことを強くお勧めします。この場合、電撃ゲームには多くの時間があります。

2-オープニングブックを見つけます。

私たちはこれらのことをしましたが、それでも私たちは良くなるにはほど遠かったです:

3-優れたチェスエンジンは、6ハンド(12プライ)先を見通せるはずです。

そこで私たちがしたことは、むだ時間を使用することでした(それが人間対コンピューターエンジンの場合)。

4-対戦相手があなたのツリーのいくつかのレベルを作成しようと考えている時間を使用します。

それでも、12プライから遠く離れていました。さらに研究することにより、いくつかのトリックを発見します!たとえば、ツリーの1つのプライをスキップして、次のプライから開始することが提案されました(対戦相手がいないような)。アイデアは、動きが非常にばかげている場合、なぜ時間を無駄にし、その動きに対する対戦相手の反応を確認するのかということです。ただし、1つの優れたエンジンは、ばかばかしい動きと天才女王の犠牲を区別できるはずです。

5- プログラミングのトリックを学ぶ この特定の問題(チェス)について。

私と私の友人は、この状態ではまだ悪かった:/私たちができること-そして私たちは部分的に-計算された位置を保存することでした。位置を計算したら、将来のために保存してください!検索ツリーのループについても同様です。ポイントは、効率的に保存/取得することでした:

6-生成したデータを効率よく保存...

そして最後に:

7-最大の最適化を伴うコード。

この問題は、CPU時間とメモリの両方で非常にコストがかかります。コードを非常に効率的に作成することは非常に重要です。ここでは、分岐係数35について話していることを思い出してください。これは、ヒューリスティックのどこかで役に立たない "if"が、検索ツリーのどこかで3.3792205e+18役に立たない "if"に変わる可能性があることを意味します。

チェスプログラミングは非常に興味深い課題であり、プログラミングの機能を真剣にテストするときです。他にも提案できる点はいくつかありますが、きっと自分で発見できると思います。まだわからないことがたくさんありますが、インターネットで見つけることができます!

頑張って楽しんでね!

pS私はJavaScriptをよく知りませんが、問題の難しさに基づいて何かが私に伝えています。おそらく、C++が提供できるすべてのことを考えると、JavaScriptをドロップしてC++で実行する方が良いでしょう。

3
Pouya

あなたの編集によると、あなたは「合法的な」動きを定義する段階まで来ています。

チェスの動きを説明する方法は2つあります。 説明 表記および 代数 表記。おそらく必要なのは、ピース、開始位置、終了位置をパラメーターとして取る関数です。例えば。 QN1からQB2への騎士は無効ですが、QN1からQ2への騎士は有効です。考えてみれば、「相対」位置を簡単に計算できるため、代数表記の方が簡単かもしれません。

必要最小限のコードを記述していることを確認するために、その関数のテストfirstの記述から始めます。代数表記を使用している場合は、ピース/開始/終了ごとのテストはおそらく必要ありません。各テストを機能させ、次の「移動」に進む前に重複をリファクタリングします。あなたのコードはよりクリーンになります。

各ピースの法的および違法な動きを十分にカバーしたら、他の変数のチェックを追加します(キングを「チェック」および「メイト」条件に移動するなど)。

単体テストには qunit を、JavaScriptの動作テストには jasmine をお勧めします。

2
Catharz

ゲームのコンピュータープレーヤーによる意思決定の部分については、「人工知能:現代的なアプローチ」という本(本のWebサイト http://aima.cs。 berkeley.edu/ )。数学のバックグラウンドにもよりますが(グラフ理論が役立ちます)、それは少し高いレベルかもしれませんが、これはこの学術的なものと同じくらい簡単に書かれており、それは非常に最新の概観(そしてある程度の深さ)を含むプログラムに物事を決定させる。

目標(つまり、チェックメイトまたはnull)を述べること、特定の状態(ボードレイアウト)がその目標にどれだけ近いかを評価すること、現在の状態から始まるさまざまな可能な状態を生成する方法などを指摘します。巨大な問題空間を横断する方法。

AIアルゴリズムの設計に役立つ可能性があることの1つは、勝利したゲームに非常に近い状況から始めて、まるで世界中にいるかのように、次にプレイする動きを決定する方法を見つけることです。妥当な時間(時間)でソリューションを見つけるように最適化し、まだすべての結果を調べていなくても、勝つためのパスを選択する方法を見つけ、実際に「思考」を中断できるようにします。ターンの時間の価値があります。

そのときだけ、提案されたように長整数を使用するなど、個々の計算を高速化するためにの表現を最適化することを検討します。単一の比較を行うためにどれほど速くても、問題の空間をトラバースする方法に優れたヒューリスティックがなければ、時間がかかることになります。

1
QuantumOmega

私は実際にチェスエンジンを作成しました。御馳走と悪夢の両方に備えてください。私の友人と私がそれをしたとき、それは時限プログラミングコンテストにあり、私たちが一緒に行くことを決めた言語はJavaでした。 JavaまたはCがあなたの最良の選択ですが、Javascriptを使用することに決めたようです。私はそれをあまり知らないので、慣れていません。

ここでの主な問題は、すべての部分について説明する必要がある移動/勝利のシナリオが非常に多いということです。したがって、実際にコーディングを開始する前に、各部分について考えられるすべての状況を書き出すことをお勧めします。計画せずに飛び込むだけで、この楽しいプロジェクトは反復的な雑用に変わります。しかし、それが本当に重要なことです。最初にコードの外側で計画を立て、一度に1つのピースのすべてのシナリオを取得するようにしてください。

幸運を

1
Bobby

あなたは本当に好きなように行くことができますが、これらはこのテーマについての私の考えです:

私はJavaを使用するので、非常に高レベルになり、ユーザーインターフェイスライブラリ(AWT、Swing)を直接使用できます。オブジェクト指向のアプローチを使用してモデリングすることができますチェス盤と駒です。他のオブジェクトが移動履歴とスコアリングの代わりになる可能性があります。プレーヤーでさえオブジェクトである可能性があり、将来はPlayerクラスを拡張して人工知能コンピュータープレーヤーを提供する可能性があります。

model-view-controller(MVC) を確認することをお勧めします。この場合、モデルオブジェクト(ドメインモデル)をユーザーインターフェイス(ビュー)に結び付け、ユーザーが(コントローラーを介して)モデルを操作できるようにします。

test-driven development を適用することもできます。これにより、すべてのメソッドが期待どおりに動作することが保証されるだけでなく、テスト可能なモジュール式コードを作成することも強制されます。