56将棋開発ブログ

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

ごーろく将棋

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 」オブジェクトのプロトタイプにもたせた

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


それでは。

JavaScriptで将棋のルール その3 ~ 手の内部表現 ~

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


前回、つぎは局面の内部表現について書くといっていたのですが、

そのまえに、「 手 」の内部表現について書いておきます。


では、とりあえずコードをごらんください。



gist9363861


駒の位置をあらわすオブジェクト(という用語でいいのか自信なし)を、

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日くらい気づきませんでした。どあほう。もしくはたわけ。

JavaScript将棋盤 ほぼ完成したので公開してみる

おひさしぶりです。ただのあほです。

JavaScriptで将棋盤の将棋のルールの部分がほぼ完成したので公開してみます。


JavaScript将棋盤



2014/03/04/15:41 追記 二歩の判定にバグがあったので修正しました


対応している将棋のルールがこちら。

・駒の動き

・手番

・成/不成の選択

・行きどころのないマスに動いたら自動で成る(歩、桂馬、香車

・駒をとる、打つ

・行きどころのないマスへ打つことの禁止(歩、桂馬、香車

・二歩の禁止

・自殺手、王手放置の禁止(玉がとられる手は指せない)


「ほぼ完成」というのは、以下のルールに対応していないからです。

・詰みの判定

・打ち歩詰め

千日手


勝ち負けの判定だけなら、玉がとられたら負けにすればかんたんですね。


ほかの方がつくったJavaScript将棋盤もみてみたのですが、

http://www.geocities.co.jp/HeartLand-Sumire/4033/show-gi/show-gi.html : 詰みは判定されない

んとか将棋 | 将棋ゲームの時間 : 玉がとられる手を指した時点で勝負を判定

というように、「詰み」の判定はしていないようです。


コンピュータと対戦できるサイトでは、

hozo.biz
こちらが自殺手を指すと玉がとられて負け(詰み判定はなし)
こちらが詰ますときは詰みが判定されて勝ち


将棋サイト「きのあ将棋」 | QinoaSyougi
こちらが自殺手を指すとその時点で負け(詰み判定はなし) 
こちらが詰ます前に投了する。詰み判定もあるはず。


というように、こちらの玉の詰み判定はされず、

コンピュータの玉の詰み判定だけになっています。


おそらくこちらの玉の詰み判定がないのは、

指し手のたびに詰み判定をしなければならないのがめんどうで、

重くなるということだと思います。


このJavaScript将棋盤は、

コンピュータと対局できるものをつくる練習のようなものです。


棋譜を読み込んで棋譜並べをできるようにするとか、

べんりな機能をつけるつもりはありません。

そういったことができるものはすでにありますしね。


というわけで、いまは合法手を生成する関数をつくっています。


JavaScriptで将棋盤の、将棋のルールに関する記事はまだ書き終わっていないので、

自分が書いたきったないコードを直すというもっとも過酷な作業がおわれば、

そのうち書くと思います。

(たぶん)(きっと)(ニコ生将棋とネット将棋の誘惑に勝てれば)


しかし、あほが書いたコードをみてみたいという需要があるのか、

疑問にはなってきた今日このごろです。

ただアドバイスいただけると本当にうれしいですし、

記事にするとじぶんの頭の中でも整理ができるので、

がんばって記事にしたいと思います。


それでは。