将棋ソフト作りに挑戦 その4
私が不安だったのが次のこと。
指し手を生成する将棋ソフトができたとして、どうやって将棋所に登録させればいいのか。
これが分からないと、将棋ソフトを作ることに専念できない。だから、まず将棋所に登録ができることを確認します。
試しに、将棋所を立ち上げて、対局→エンジン管理→追加で、"hello world"と出力するだけのコードの実行ファイルを登録してみます。実行ファイルの場所は、C:\Users\ユーザ名\Documents\Visual Studio 2015\Projects\プロジェクト名\プロジェクト名\bin\Debugにあると思います。すると、「これはUSIエンジンではありません」とあって登録できません。
USI(universal shogi interface)は将棋ソフトと将棋GUIが通信するためのプロトコルです。メッセージのやり取りは標準入出力で行われます。だから、標準入出力を扱える言語ならUSIが使えることになります(将来的には、C++で作ろうかな?)。将棋所に将棋ソフトを登録するときはこのプロトコルに従ったメッセージを送るときだけ許可されるようです。試しに、次のコードの実行ファイルを登録してみます。
using System; using System.IO; public class USI { TextReader input= Console.In; string line; public void USI_Start() { while (true) { if ((line = input.ReadLine()) != null) { if (line == "usi") { Console.WriteLine("id name test"); Console.WriteLine("id author Program Writer"); Console.WriteLine("usiok"); } //①ここに後で文を追加 if (line == "quit") { break; } } } } }
すると、登録されているのが分かります。将棋所の表示→デバックウィンドウを見てみます。これは将棋所と将棋ソフトのメッセージのやり取りのログです。>が将棋所から、<が将棋ソフトからのメッセージです。
>C:usi <C:id name test <C:id author Program Writer <C:usiok >C:quit
はじめに将棋所が"usi"を送信して、将棋ソフトが自己紹介したあとに,"usiok"を返信までが基本の挨拶になっているようです。"quit"が来たら、将棋ソフトの実行を終わらせないとダメです。
登録できた将棋ソフトと自分が戦ってみます。コードの①に次のコードを追加しておきます。
if (line == "isready") { Console.WriteLine("readyok"); } if (line.Contains("go")) { Console.WriteLine("bestmove resign"); }
対局を開始すると、いきなりユーザの勝ちになりますw。将棋ソフトに即投了するよう命令してあるからです("bestmove resign"メッセージ)。
これで、GUIについてはなんとかなることが分かったので、将棋ソフト本体の開発に進んでいくことができます。
続く?
将棋ソフト作りに挑戦 その3
2015年11月22日 とりあえず目標を立てました。
「ルール内でランダムな手を指すソフトを作る」
「視覚的に作者とソフトが対局できるようにする」
これを実現することが記事の目的です。思考ルーチンとかはその次の話なのでしません(できません)。
C#の環境を構築します。正直、これ自体私にとってハードルが高い。なるべく躓きたくない。
visual studio community 2015(以下VS)をインストールします。これは統合開発環境とよばれるもので、コードの編集からコンパイル、実行、文字の補完機能とかそろっている強力なツール。Microsoftが好きなわけではないけど、これは正直充実していると思う。
VSを立ち上げたら、新規作成→プロジェクト、からテンプレート→Visal C#→クラシックデスクトップ→空のプロジェクトを作ります。プロジェクトは一つの製品のようなものだと思いますたぶん。なので、これに将棋ソフトの名前でも付けます。「空の」は何も最初に設定されていないということだと思います。全部、ゼロから作るぞということです。
プロジェクトができたら、画面右のソリューションエクスプローラにある、プロジェクト名の上で右クリックをし、追加→新しい項目をクリック、コードファイルを作成します。コードファイルに次のように記述して、ソリューションのビルドします。そして、デバッグの開始。
class Test { public static void Main() { System.Console.WriteLine("test"); while (true) ; } }
するとコンソール画面が出てきてtestと表示されたら成功です。最後のwhile文は実行を終了しないようにし、コンソール画面が消えないようにするためです。
これで基本的な環境は整ったのであとは自分の好きにコードを書いてください終w
ここから私は、よくわからなかったので、Formを作ってその中に将棋盤を表示するプログラムを書き始めました。つまり、視覚的な部分(GUI)から先に作ろうとしました。実際、駒をクリックして移動させるところまでできたんですが、そのあと、「ルール内の移動かどうかを調べる」ところでつまりました。ややこしすぎて。
問題は、GUIとそれ以外の部分を同時に作ろうとしてパニックになったことです。そして、GUIをつくるのハードル高いと気づきました。避けたい。
実は、GUI部分は公開されているアプリで代用できると知りました。
そのアプリは将棋所です。
2015年11月29日
今まで作っていたGUIを捨てて、一からやり直すことを決意。
続く?
将棋ソフト作りに挑戦 その2
最初に断っておくと、私は将棋ソフト開発初心者です。そして、プログラミングは授業で習ったレベルです。つまり、プログラムに関しては完全な初心者ではなく開発とか経験したことないけど基本的な文ぐらいなら書けるというレベルです。
なので、この記事は「プログラムが最低限書けて、将棋ソフト開発始めたい人」を意識して書きます(対象狭w)
使う言語はC#です。C++にさらに++して#ですごいにきまってる!と思ったからです(笑)
サイトとか見てると計算の効率上C++がベストみたいですが、私はわかりやすさを重視して、とっかかりをつかむためにC#にしました。(計算効率について考慮しないで作るorz)
2015年11月15日 勉強開始
C#を知らなかったので、本をポチって知識の詰め込み(一週間)
- 作者: ハーバート・シルト,エディフィストラーニング株式会社矢嶋聡
- 出版社/メーカー: 翔泳社
- 発売日: 2010/12/03
- メディア: 大型本
- 購入: 5人 クリック: 55回
- この商品を含むブログ (6件) を見る
プログラム初心者の人はまず、入門サイトなどで学習してから、この本を読めばちょうどいいと思います。
オブジェクト指向で書いた方がわかりやすそうだ。読みやすさ重視がいいな云々。
プログラムの知識はこれでついたので、いよいよ...
何していいかわからないorz
続く?
将棋ソフト作りに挑戦 その1
最近将棋ソフト作りに挑戦し始めた私です。
もともと、私は将棋が趣味です。自分が強くなるために、検討用に将棋ソフトを使ったり、将皇とかハム将棋と対戦したりしてました。そのときは、そういうのもあるよな、ぐらいにしか思ってなかったんですが、今年の3月ぐらいにニコニコで電王戦があって、人間対ソフトの5番勝負を見て、ソフトへの興味が強くなりました。初戦と第2戦、最終戦が物議をかもしたので、機械ってなんだろ的な視点で考えさせれたのを覚えています。初戦は、ソフトが負けにもかかわらず、投了をしないことが批判されてて、マナー求めるのはどうなんだろなあと。第2戦は、角成らずによってバグを引き起こして人間の勝利でしたが、結局単なるバグだったと思いますが、自分は「ソフトの本質的な欠陥をついた人間の勝利だ」なんて間違った解釈をして盛り上がってしまいました。ソフトの弱みと強みについて想像をめぐらして楽しめました。第5戦は角を打たせて召し取る戦法で人間の勝利でした。たぶん、これは「数十手先を感覚的に見通せないソフト特有の欠陥」なんだろなあと想像して、なんか課題が山積みで面白そうだと思った記憶があります。
ソフト作ろうと思ったのは純粋な興味と、もうひとつおまけとして、ソフトの考え方を知って自分の棋力も上がったらいいなと思ったことです。将棋に関すること何でもやってみろ精神ですw
というわけで、2015年11月15日から、チャレンジを開始したのでその記録を残しておこうと思います。どうせなら、同じようにソフト作りたいと思った人の手助けになるような形の記事を書こうと思います。
C#初心者備忘録1
C#を学習していて初心者が思ったことを書いていく。
メソッドってクラスの変数を使わずに引数にしか依存しないものがある。だから、そういうメソッドをクラスの外に単独で記述したいと思った。つまり、メソッドをグロバール空間(?)に書いて、どこからでもアクセスできるようにしたい。残念ながら、オブジェクト指向ではメソッドは必ず何らかのクラスの中に記述されてる必要があるみたい。それなら、汎用的なメソッドを持ったクラスを作って、usingでそのクラスのショートカットみたいなの作る方法を思いついた。ただし、メソッドにstaticをつけている必要あり。クラスにはつけなくていい。まあ、汎用的なメソッドを集めたクラスなら、すべてのメソッドとクラスをstaticにしてた方がいいのか。
というかこれってモジュールと呼ばれるものか。
それでstaticについて分からなくなってきた。staticなクラスは変数もstatic。ということは、生成したオブジェクトをstaticクラスの変数に代入できないのか。staticなクラスはプログラムの初めに作られるらしいから、後の処理であるオブジェクトの生成が間に合うわけがない。でも、それは不便すぎる。どうしたらいいんだ。と悩んでいたら、staticクラスにはstaticコンストラクタがあるみたいで、その中ならオブジェクトを生成できるみたい。
あと、インデクサーはstaticクラスでは作れないことが分かった。なぜかは知らない。だけど、これだとstaticクラスは配列のように扱えないので不便だなあ。