近況
Bonanzaを5*6マスのごーろく将棋に書き換えてみよう
↓
ビット操作、ビットレイアウト、指し手生成に必要な配列の初期化は
だいたいできたっぽいので、そろそろ指し手生成にチャレンジだ
↓
そのまえにCSA形式の棋譜をとりこめるようにしないとデバッグできないぞ
↓
BonanzaのCSA形式のデータ読み込み部分のソースがよくわからん
$ANSWERってなに?CSA標準棋譜ファイル形式 (V2.2)に載ってないよ?
↓
Bonanzaソース完全解析ブログで、
CSA形式のデータ読み込み部分のソース解説までされてる!すごい!←いまここ
ごーろく将棋
「ごーろく将棋」のサイトを引っ越しました。
【2015/11/5 追記 さらに引っ越したのでリンク先を変更しました】
COMのレベル(レベル1とレベル2しかないけど)と、
二枚落ちなどのハンデを選択できるようにしてみました。
遊んでみていただけるとうれしいです。
遊んでみた感想をいただけると、とてもうれしいです。
COMのレベル1は、
を参考にさせていただいています。
もちろんそのままというわけではなくて、
自分なりに工夫してみたのですが、
「自然に弱くする」のはなかなか難しかったです。
それについては、そのうちまた別の記事にしたいと思っています。
さて、今後しばらくは、
より強いレベルのCOMをつくることを目標にしたいと思います。
もっと自然に弱い、レベル0をつくるのもおもしろそうなのですが、とりあえず。
最近は、オープンソース
( 2014/6/6 17:25追記
ソースコードは公開されていますが、営利目的での利用は制限されているので、いわゆる「オープンソース」ではないようです。)
のBonanzaを、
ごーろく将棋のプログラムに改変できたらと思いまして、
Bonanzaソース完全解析ブログを少しずつ読んでいます。
しかし道遠しという感じで、
今年度中にできたらなー、という気持ちになってます。
いきなりBonanzaのごーろく将棋版をつくるのは難しすぎるので、
JavaScriptでbitboardを実装してみる
↓
指し手生成の部分をBonanzaのマネをしてつくってみる
↓
探索部分をBonanzaのマネをしてつくってみる
みたいなステップでやっていくのが妥当かなという感じでしょうか。
それでも簡単なステップではないですががが。
あと、前回の記事で、
「ごーろく将棋は先手有利、もしかしたら必勝かも」
なんて書いてしまいましたが、
もう少し研究してみたところ、
そうでもないかもしれない感じがしてきました。
はっきりいってよくわかりません。
「これで後手ダメだな」と思っていた変化があったのですが、
しらべてみると、後手もまずまず、どころか後手有利かも、
となってしまったりして、なかなか結論がでてません。
もし「ごーろく将棋」を研究されて、
必勝法を発見した、というかたがいらっしゃいましたら、
ご連絡をおまちしております。
(もちろんわたしも研究します)
(ちなみにわたしは将棋倶楽部24で現在9級なので、自分のことながら
あまり期待できません)
(でもがんばります)
それでは。
あたらしいミニ将棋を考えて、COMと対局できるものをつくりました。( 仮 )
こんな感じです。
こちらのページで対局することができます。
<2014.6.13 10:50 追記 ページを引っ越したのでリンク先を変更しました>
【2015/10/30 追記】 さらに引っ越したのでリンクを変更しました。現在はこんな感じです
バグなどあれば、この記事にコメントしていただけるとうれしいです。
さて、思考エンジンですが、
・探索部分
3手先読み + 駒がぶつかっているあいだは精算するまで読む
・評価関数
基本は駒得(駒に点数をつけて単純に足す)
歩、と金、金、銀は、敵玉との距離が近いほど価値が高くなるように補正
飛、角の利いているマスの数によって加点
というふうにしました。
将棋初級者のかたの練習相手になればいいかな、
というぐらいの強さになっていると思います。たぶん。
というか、今のわたしの技術では強いものがつくれないんですけども。
この初期配置はかなり先手有利(というか必勝かも)なのですが、
あと6つほど考えている初期配置があるので、
その中から選べるようにしたいと思っています。
ほかにも、
・強くする or 弱くする → レベルを選べるようにする
・千日手に対応する
・トライルール
・打ち歩詰めは禁則にするかどうか。するなら実装。
盤面が狭く、出現頻度が高いので禁則にしないかも。
・setIntervalで、どちらの手番かずっと確認している処理をなんとかする
(setTimeoutの存在を知りませんでした。それにしてもあほです。)
など、やることがたくさんあるのでがんばります。
電王戦をたのしく観ていたら、こんなに更新が遅くなってしまいました。ははは。
(ごめんなさい)
それでは。
( とんでもなく弱いけど )将棋プログラムができました
びっくりしました。よわくて。
2つのタブで、かわりばんこに自分でクリックするという、
かなりめんどうくさい方法で、
と対局させてみたところ、
先手(手前): こまお
後手(奥) : つくったもの
という投了図ができあがりました。
はい。まけました。
以下、3四玉、3三成桂まで詰みですが、
自玉の詰みを読むと投了するようにしてあったので、
きちんと投了してくれました。(アラートがでます)
このあと自分で3四玉と指してみると、
「こまお」は3三成銀としたので、
2四玉で詰まなかったのですが。
負けは負けですね。
こちらの特徴(欠点)としては、
・3手先までしか読めない
(駒のとりあいがつづく手は精算するまで読む)
・局面の良し悪しを評価する基準が駒得だけ
・しかも持ち駒の評価点を高くしてしまったので、
ぜんぜん持ち駒をつかってくれない
基本的な問題として、処理にムダが多すぎて重いです。
とりあえず反則の手を指さずに、
きちんと投了してくれたという点だけがよかったところでしょうか。
さすがに弱すぎるうえにムダに重いので、
処理を軽くして、「こまお」になんとか勝てるくらいになったら、
公開してもいいのかなとは思っています。
勝手かつ一方的ではありますが、
「こまお」の作者さまには感謝もうしあげます。
それでは。
おまけ
つくってる途中のバグ。カオス。
JavaScriptで将棋のルール その4 ~ 局面の内部表現 ~
こんばんは、ただのあほです。
今回は、JavaScript将棋盤の、
局面の内部表現がどうなっているかについて書いてみようと思います。
まず、「 Position (局面)」というオブジェクトに、
どんな情報をもたせているか、ですが、
・ 盤 Board
番兵(OUT_OF_BOARD)もいれて11×11
9×9の将棋盤のまわりに1層の番兵をおいている
・ 持ち駒 Capture
先後、駒の種類という2つの変数がインデックスになっている配列
配列の中身がもっている駒の枚数
・ 手番 turn
true が先手、false が後手
・ 歩のフラグ FuFlg
ある筋に歩があるかないかをあらわすフラグ 二歩の判定につかう
先後、筋という2つの変数がインデックスになっている配列
その筋に歩が、true ならあり、false ならない
・ 玉の位置 blackKingPos whiteKingPos
先後それぞれの玉が、どの段、筋にいるか
というふうにしています。
ま、なにはともあれ、コードを貼ってみたいとおもいます。
また、このオブジェクトのプロトタイププロパティには、
do_move 動かす
undo_move もどす
Set_default 初期配置にセット
IsControl あるマスに先後どちらかの駒の利きがあるかどうかしらべる
CanMove ある駒があるマスに動けるかどうかしらべる
CanDrop 歩、桂、香を打っていい段かどうか、二歩かどうかをしらべる
MakeLegalMoves 合法手を生成する
EvalPieceValue 駒割にもとづいて局面を評価、点数化する
といった関数をもたせています。
その中身は、長くなるので次回以降に。
それはそうと、メンバの頭文字が大文字だったり小文字だったりと統一感がないですね。
あまり意識せず適当につけていたのですが、(よくないですね)
よくみると、配列は大文字にしているというルールがありますね。
いま気づきました。どないやねん。
単語の区切りを大文字にする方法(キャメルケースというらしい)と、
_ で区切る方法(スネークケースというらしい)があるみたいですが、
基本はキャメルケースをつかって、
ある関数の中だけでつかう変数(ローカル変数でいいんでしょうか)は、
スネークケースをつかってます。
あと、do_move と undo_moveは、
やねうらおさんのブログに書いてあったものを
そのままマネしたのでスネークケースになっています。
Set_default もそれにひっぱられてスネークケースになっていて、
あと「 Set 」は大文字にするクセがあるのでそうなっています。
気になったかたは、ごめんなさい。
なんにせよ合理的なルールにのっとって変数名をつけるのがだいじなんでしょうね。
気をつけてプログラミングしていきたいと思います。
つぎは、「 局面 Position 」オブジェクトのプロトタイプにもたせた
それぞれの関数について書くことになると思います。
それでは。
JavaScriptで将棋のルール その3 ~ 手の内部表現 ~
どうもこんばんは、ただのあほです。
前回、つぎは局面の内部表現について書くといっていたのですが、
そのまえに、「 手 」の内部表現について書いておきます。
では、とりあえずコードをごらんください。
駒の位置をあらわすオブジェクト(という用語でいいのか自信なし)を、
Pos から PiecePos に名前をかえました。
あと、駒を動かすときに、駒の位置(段と筋)を足したりかけたりするための、
Add と Multiply という関数も用意しています。
そして、「 手 」をあらわすのが Move というオブジェクトです。
どの駒( piece )が、どこから( from )、どこへ( to )動いたか、
成/不成( promotion )、
とった駒( capture )、
をメンバ(この用語も自信なし)としてもっています。
これもほとんど、うさぴょんの作者さまのページのマネです。
感謝してもしきれないので、何度もリンクを貼っています。
JavaScriptでのオブジェクト指向(ほんとこれをつかうとカッコいい感じがしますね)
については、こちらの記事が参考になりました。
JavaScriptにおけるオブジェクトの基本的性質:CodeZine
このページもリンクするのは2回目です。
こんなことが無料で学べるなんて、インターネットは偉大ですね。
かがくのちからってすげー!
次こそは、局面の内部表現について書きたいとおもいます。
それでは。
将棋用語の英訳
どうも、ただのあほです。
JavaScript将棋盤の局面の内部表現について書こうとおもったのですが、
そのまえに変数名をいろいろいじったので、
将棋用語の英訳についてまとめておこうかなと思います。
参考にしたページがこちら。
Shogi - Wikipedia, the free encyclopedia
将棋用語 | 英訳 |
---|---|
駒 | piece |
段 | rank |
筋 | file |
手 | move |
手番 | the move / turn / color |
駒の位置 | position (king's p.など) |
局面 | position |
持ち駒 | captured piece / hand |
持ち駒を打つ | drop |
駒の利き | control |
駒の名前もぜんぶ英名があるのですが、
とりあえず日本語のローマ字表記のままでコードを書いています。
将棋じたいが日本のものなので、
どこまで英語にするかちょっと微妙なところがあります。
段とか筋もそのまま dan と suji でもいいかなと思ったのですが、
カッコつけて rank と file に変えてみました。
最初は違和感ありますが、すぐに慣れました。
(タイプミスしまくったのはひみつです)
「駒の位置」と「局面」は、おなじ「 Position 」という単語なので、
「駒の位置」のほうを「 PiecePos 」にして区別しました。
あと、「手番」が「 the move 」で、
「手」の「 move 」とかぶっていて困ったのですが、
twitterで、とあるかたに「 turn 」というかんたんな単語を教えていただき、
解決しました。
ありがたやありがたや。
次こそは、JavaScriptで将棋のルール、局面の内部表現という記事になると思います。
それでは。
追伸 JavaScript将棋盤の、二歩の判定にバグがあったのでなおしました。
6日くらい気づきませんでした。どあほう。もしくはたわけ。