56将棋開発ブログ

5×6マスのミニ将棋、「56将棋」で遊べるものをいろいろ開発してます。

進捗いろいろ

せめて数ヶ月に1回くらいは開発状況を書いておくかな、という気分になったので更新してみます。

最近取り組んでいるのは大きくわけて2つ、

ごーろく将棋 56shogi ブラウザ版への機能追加
プチボナ 56shogi機械学習

です。


ごーろく将棋 56shogi ブラウザ版には、これからいろいろな機能を追加していく予定です。

とりあえず現時点で形になっているのは以下の2つです。


・局面編集
駒を好きなところに動かして局面をつくることができる機能をつくりました。

ごーろく将棋 56shogi 局面編集


f:id:tetsuzuki1115:20160226162536p:plain


デバッグなどでつかう局面をつくるのが捗るので、正直に言うと自分用の意味が強いです。

こういうものはコンピュータ将棋におけるインフラみたいなものだと思うのですが、

56shogi の解に近づくという目標を達成するため、

あるいは、もう少しごーろく将棋が普及するといいな、というささやかな希望が実現するためには、

そういったインフラを少しずつでも整えていく必要があるのだな、と実感しています。

(どうでもいいことですが、コンピュータ将棋に関係する文脈では "56shogi"、
本将棋への導入、普及、教育といった文脈では"ごーろく将棋"あるいは"ごーろく将棋 56shogi"というふうに、わたしは勝手に呼び分けています)


・練習問題

COMとの対局だけでなく、ごーろく将棋や本将棋の棋力が向上するような練習問題が毎日アップされるページをつくっています。

開発言語はphpMySQLで、ドットインストールをみて勉強しました。

練習問題の内容としては、ある局面において、浮き駒(味方の駒に支えられていない駒)をすべてクリックすると正解、というものです。

f:id:tetsuzuki1115:20160226162218p:plain

f:id:tetsuzuki1115:20160226162227p:plain

毎日数問ずつアップされるようにするのと、解くまでにかかった時間を最後に表示するようにしたら公開しようかなと思っています。


ほかにも、ある局面での駒割りを計算する問題や、あるマスで駒交換したときの駒割りを答える問題を出題するページもつくる予定です。


プチボナ 56shogi の開発の方も、ゆっくりではありますが進めています。

機械学習
去年公開したプチボナ 56shogi は、指し手生成と探索部分はほぼBonanzaそのままで、56shogiで動くようにしたというものだったのですが、
評価関数はわたしが手調整で値を決めたものでした。(というほど調整もしていないのですが)

より棋力を向上するため、機械学習による評価関数のパラメータ調整に挑戦してみよう、ということでBonanzaのコードを読んでいます。

「コンピュータ将棋の進歩6 プロ棋士に並ぶ」という本にある解説が非常に参考になっています。
(というか解説文がないと、それぞれの関数のざっくりとした役割すら全くわからないレベルです…)

とりあえず学習部分のコードすべてに目を通したら、駒得のみの評価関数同士で自己対戦させた棋譜から学習させてみる予定でいます。

学習について勉強しはじめる前は、56shogiは本将棋に比べて駒の組み合わせの数が少ないので、学習にかかる時間が少なくて済むんじゃないかと思っていました。

しかし、パラメータを調節するステップよりも、探索してPV(最善応手系列≒読み筋)を求める処理のほうが時間がかかるらしいので、
うーん考えが甘かったかな、と思い直しています。
(本将棋より早く学習が進むのは間違いないと思うのですが)

まあやってみないとわからないので早く動かしてみたいですね。

それでは。

「ごーろく将棋 56shogi ブラウザ版」をリニューアルしました

タイトルのとおり、「ごーろく将棋 56shogi ブラウザ版」をリニューアルしました。

ごーろく将棋 56shogi

f:id:tetsuzuki1115:20151028092524p:plain


リニューアルに伴いレンタルサーバを移転、URLを変更しました。

追加した主な機能としては、

1.COMレベル3、4、5
2.棋譜ツイート機能

です。

COMのレベル3、4、5は、以前に公開したプチボナ 56shogiJavaScriptに移植したものです。

反復深化のiterationを制限して強さを調節しました。

レベル4とレベル3で先後入れかえて100局連続対局した結果は96-4、
レベル5とレベル4の結果は80-20でした。

レベル5も(時間ではなく)探索ノード数を制限しているので、PCのスペックによらず一定の棋力になっているはずです。
スペックによっては思考時間が少しかかってしまうかもしれませんが、できるだけ棋力が一定になる方法を採用しました。

プチボナ 56shogi はBonanzaの指し手生成と探索部を改変したものなので、
それを移植したブラウザ版のCOMレベル3、4、5のベースはBonanzaということになります。

ただどうしてもJavaScriptだと速度が出ず、(わたしの技術力不足もありますが)
探索速度はプチボナ 56shogiの10分の1程度になっているはずです。
(一度ちゃんと測ったのですがPCが故障した時に紛失してしまいました)

なので、試していないのですが、同じ時間で対局するとプチボナ 56shogi (ダウンロード版)のほうが強いはずです。

ブラウザ版は面倒な設定をしなくて済むのが良いところなので、ある程度棋力は落ちてもしょうがないかな、というところです。


棋譜ツイート機能はColamoneのアイデアを真似させていただきました。
colamone

ツイートに埋め込まれたリンク先のページで、URLを解析して棋譜を再生する仕組みになっています。

 
細かい変更点としては、千日手とトライルールに対応したのと、デザイン・レイアウトを変更しました。

COMのレベル、手合、先後の選択画面は先日公開された「ねずみ将棋」を参考にさせていただきました。
「ねずみ将棋」には目隠し将棋、初形ランダム将棋といった楽しいモードがあるのでおすすめです。
ねずみ将棋 - SoupSeed


トライルールを含めた将棋のルールについては詳しい説明を用意するつもりです。

あとは英語版もつくりたいと思っています。(自分の英語力が心配ですが)


自分はスマートフォンを持っておらず、とりあえずPCで動作するものをつくるという方針でやってきたので、申し訳ないのですが、スマートフォンへの対応は何もしていません。

googleモバイルフレンドリーテストをやってみたところ、
盤面がものすごく小さく表示されてしまい、他にもいろいろ怒られてしまいました。

f:id:tetsuzuki1115:20151028141245p:plain

今後はスマートフォンに対応したレイアウトを考えたいと思っています。
まずは自分がスマートフォンを買うところからなのですが。


それでは。


【2015/10/28 19:05 追記】
ごーろく将棋 56shogi ブラウザ版のCOMレベル3、4、5のベースであるBonanzaを開発された保木邦仁様には本当に感謝しております。
改めて御礼申し上げます。

近況

5ヶ月も放ったらかしてしまいましたが、心機一転、ブログタイトルを変えてみました。

現在は、ブラウザ版ごーろく将棋 56shogi のリニューアルに向けて開発を進めています。

追加する主な機能としては、

1.COMのレベル3、4、5
2.棋譜ツイート機能
3.トライルールの実装
4.千日手への対応

です。

COMのレベル3、4、5については、5ヶ月前に公開した「プチボナ 56shogi」 をJavaScriptに移植したものをつかって、
探索深さやノード数を制限して強さを調節する予定です。

棋譜ツイート機能は、colamoneのアイデアをそのまま56shogiに対応させました。
colamoneを開発したkurehajimeさまには感謝申し上げます。
colamoneもとても素晴らしいボードゲームですので、是非遊んでみてください。

トライルールとは、玉が敵陣の特定のマスまで進むと勝ちになるルールです。
(相手に玉をとられないことが条件ですが)
ごーろく将棋 56shogi は盤面の広さのわりに駒が多いので、
詰むや詰まざるや、トライできるかできないかのような、
複雑な局面になっておもしろいです。

千日手は今まで実装していなかったのが怠慢でした。
これでルール上の不備はなくなったと思います。バグが怖いですが。


JavaScriptに移植する上で工夫した点としては、

1.Cのマクロをつかっている部分をSweet.jsのマクロ機能で代用
2.RequireJSで分割したファイルを管理、統合

ぐらいです。

コンピュータ将棋の技術的な話としては、
飛び利きの算出をrotated bitboardからkindergarten bitboardに変更しました。
こちらのブログを参考にさせていただきました。

Kindergarten Bitboardsの将棋への応用 - コンピュータ将棋開発中


少し前にEmscriptenBonanzaのコードをJavaScriptに変換したembonaというものが公開されましたが、
プチボナのブラウザ版への移植は人力でやりました。

かなり時間がかかりましたが、Bonanzaの指し手生成と探索部分の理解が深まった感じがしているので、まあいいかなと思っています。


とりあえず現在は、移植したプチボナの思考エンジンがブラウザ上で動くようにはなっています。
今のブラウザ版のレベル2との棋力差が大きすぎるので、移植したプチボナをレベル5として、探索深さやノード数を制限して強さを調整したものをレベル3、4とする予定です。

あとはルール説明のページをきちんと用意して、それができれば公開しようかなと思っています。

最後に開発中の画面を貼っておきます。
(トライされてプチボナに負けた局面です。くやしい)

f:id:tetsuzuki1115:20151007205923p:plain


それでは。

ごーろく将棋

f:id:tetsuzuki1115:20140604174009p:plain

「ごーろく将棋」のサイトを引っ越しました。

【2015/11/5 追記 さらに引っ越したのでリンク先を変更しました】

ごーろく将棋 56shogi


COMのレベル(レベル1とレベル2しかないけど)と、

二枚落ちなどのハンデを選択できるようにしてみました。

遊んでみていただけるとうれしいです。

遊んでみた感想をいただけると、とてもうれしいです。


COMのレベル1は、

こまお

を参考にさせていただいています。

もちろんそのままというわけではなくて、

自分なりに工夫してみたのですが、

「自然に弱くする」のはなかなか難しかったです。

それについては、そのうちまた別の記事にしたいと思っています。


さて、今後しばらくは、

より強いレベルのCOMをつくることを目標にしたいと思います。

もっと自然に弱い、レベル0をつくるのもおもしろそうなのですが、とりあえず。


最近は、オープンソース
2014/6/6 17:25追記 
ソースコードは公開されていますが、営利目的での利用は制限されているので、いわゆる「オープンソース」ではないようです。)

Bonanzaを、

ごーろく将棋のプログラムに改変できたらと思いまして、

Bonanzaソース完全解析ブログを少しずつ読んでいます。

しかし道遠しという感じで、

今年度中にできたらなー、という気持ちになってます。


いきなりBonanzaのごーろく将棋版をつくるのは難しすぎるので、

JavaScriptでbitboardを実装してみる

指し手生成の部分をBonanzaのマネをしてつくってみる

探索部分をBonanzaのマネをしてつくってみる

みたいなステップでやっていくのが妥当かなという感じでしょうか。

それでも簡単なステップではないですががが。


あと、前回の記事で、

「ごーろく将棋は先手有利、もしかしたら必勝かも」

なんて書いてしまいましたが、

もう少し研究してみたところ、

そうでもないかもしれない感じがしてきました。

はっきりいってよくわかりません。


「これで後手ダメだな」と思っていた変化があったのですが、

しらべてみると、後手もまずまず、どころか後手有利かも、

となってしまったりして、なかなか結論がでてません。


もし「ごーろく将棋」を研究されて、

必勝法を発見した、というかたがいらっしゃいましたら、

ご連絡をおまちしております。

(もちろんわたしも研究します)

(ちなみにわたしは将棋倶楽部24で現在9級なので、自分のことながら
 あまり期待できません)

(でもがんばります)


それでは。

あたらしいミニ将棋を考えて、COMと対局できるものをつくりました。( 仮 )

こんな感じです。

f:id:tetsuzuki1115:20140422192242p:plain

こちらのページで対局することができます。
2014.6.13 10:50 追記 ページを引っ越したのでリンク先を変更しました>

【2015/10/30 追記】 さらに引っ越したのでリンクを変更しました。現在はこんな感じです

f:id:tetsuzuki1115:20151028092524p:plain


バグなどあれば、この記事にコメントしていただけるとうれしいです。


さて、思考エンジンですが、

・探索部分

3手先読み + 駒がぶつかっているあいだは精算するまで読む


・評価関数

基本は駒得(駒に点数をつけて単純に足す)

歩、と金、金、銀は、敵玉との距離が近いほど価値が高くなるように補正

飛、角の利いているマスの数によって加点


というふうにしました。


将棋初級者のかたの練習相手になればいいかな、

というぐらいの強さになっていると思います。たぶん。

というか、今のわたしの技術では強いものがつくれないんですけども。


この初期配置はかなり先手有利(というか必勝かも)なのですが、

あと6つほど考えている初期配置があるので、

その中から選べるようにしたいと思っています。


ほかにも、

・強くする or 弱くする → レベルを選べるようにする

千日手に対応する

・トライルール

・打ち歩詰めは禁則にするかどうか。するなら実装。
盤面が狭く、出現頻度が高いので禁則にしないかも。

・setIntervalで、どちらの手番かずっと確認している処理をなんとかする
(setTimeoutの存在を知りませんでした。それにしてもあほです。)


など、やることがたくさんあるのでがんばります。


電王戦をたのしく観ていたら、こんなに更新が遅くなってしまいました。ははは。
(ごめんなさい)


それでは。

( とんでもなく弱いけど )将棋プログラムができました

びっくりしました。よわくて。

2つのタブで、かわりばんこに自分でクリックするという、
かなりめんどうくさい方法で、

こまお

と対局させてみたところ、

f:id:tetsuzuki1115:20140310184345p:plain

先手(手前): こまお   

後手(奥) : つくったもの

という投了図ができあがりました。
はい。まけました。

以下、3四玉、3三成桂まで詰みですが、
自玉の詰みを読むと投了するようにしてあったので、
きちんと投了してくれました。(アラートがでます)

このあと自分で3四玉と指してみると、
「こまお」は3三成銀としたので、
2四玉で詰まなかったのですが。

負けは負けですね。

こちらの特徴(欠点)としては、

・3手先までしか読めない 
(駒のとりあいがつづく手は精算するまで読む)

・局面の良し悪しを評価する基準が駒得だけ

・しかも持ち駒の評価点を高くしてしまったので、
 ぜんぜん持ち駒をつかってくれない

基本的な問題として、処理にムダが多すぎて重いです。

とりあえず反則の手を指さずに、
きちんと投了してくれたという点だけがよかったところでしょうか。

さすがに弱すぎるうえにムダに重いので、
処理を軽くして、「こまお」になんとか勝てるくらいになったら、
公開してもいいのかなとは思っています。

勝手かつ一方的ではありますが、
「こまお」の作者さまには感謝もうしあげます。

それでは。


おまけ

つくってる途中のバグ。カオス。

f:id:tetsuzuki1115:20140310190919p:plain

JavaScriptで将棋のルール その4 ~ 局面の内部表現 ~

こんばんは、ただのあほです。

今回は、JavaScript将棋盤の、

局面の内部表現がどうなっているかについて書いてみようと思います。


まず、「 Position (局面)」というオブジェクトに、

どんな情報をもたせているか、ですが、


・ 盤 Board

番兵(OUT_OF_BOARD)もいれて11×11
 
9×9の将棋盤のまわりに1層の番兵をおいている


・ 持ち駒 Capture

先後、駒の種類という2つの変数がインデックスになっている配列

配列の中身がもっている駒の枚数


・ 手番 turn

true が先手、false が後手


・ 歩のフラグ FuFlg

ある筋に歩があるかないかをあらわすフラグ 二歩の判定につかう

先後、筋という2つの変数がインデックスになっている配列

その筋に歩が、true ならあり、false ならない


・ 玉の位置 blackKingPos whiteKingPos

先後それぞれの玉が、どの段、筋にいるか


というふうにしています。


ま、なにはともあれ、コードを貼ってみたいとおもいます。


gist9386134


また、このオブジェクトのプロトタイププロパティには、

do_move    動かす

undo_move   もどす

Set_default  初期配置にセット

IsControl    あるマスに先後どちらかの駒の利きがあるかどうかしらべる

CanMove     ある駒があるマスに動けるかどうかしらべる

CanDrop    歩、桂、香を打っていい段かどうか、二歩かどうかをしらべる

MakeLegalMoves 合法手を生成する

EvalPieceValue 駒割にもとづいて局面を評価、点数化する


といった関数をもたせています。

その中身は、長くなるので次回以降に。


それはそうと、メンバの頭文字が大文字だったり小文字だったりと統一感がないですね。

あまり意識せず適当につけていたのですが、(よくないですね)

よくみると、配列は大文字にしているというルールがありますね。

いま気づきました。どないやねん。


単語の区切りを大文字にする方法(キャメルケースというらしい)と、

_ で区切る方法(スネークケースというらしい)があるみたいですが、

基本はキャメルケースをつかって、

ある関数の中だけでつかう変数(ローカル変数でいいんでしょうか)は、

スネークケースをつかってます。


あと、do_move と undo_moveは、

やねうらおさんのブログに書いてあったものを

そのままマネしたのでスネークケースになっています。

Set_default もそれにひっぱられてスネークケースになっていて、

あと「 Set 」は大文字にするクセがあるのでそうなっています。

気になったかたは、ごめんなさい。


なんにせよ合理的なルールにのっとって変数名をつけるのがだいじなんでしょうね。

気をつけてプログラミングしていきたいと思います。


つぎは、「 局面 Position 」オブジェクトのプロトタイプにもたせた

それぞれの関数について書くことになると思います。


それでは。