56将棋開発ブログ

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

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

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

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で将棋盤の、将棋のルールに関する記事はまだ書き終わっていないので、

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

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

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


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

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

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

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

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


それでは。

JavaScriptで将棋のルール その2 ~ 駒の動き ~

はいどうも、ただのあほです。

今日は、駒の動きをチェックする関数をつくりました。


とにかくできたものを動かしたいというかたは、

こちらのページへどうぞ。

http://www54.atpages.jp/tetsuzuki/


まずは下準備として、駒が動ける方向を、配列にいれておきます。



gist9107351


Directionという配列が、

8方向 + 桂馬の動き4方向 = 12方向

をあらわしていて、それぞれの方向に対応した dan , suji の値がはいっています。


CanGoという配列は、二次元配列もどきになっています。

(正確には配列の各要素に、別の配列を格納しているらしいです)


たとえばCanGo[0][FU]には、

0 の方向(Directionのインデックスと対応している)に、FU(歩)が動けるかどうかをあらわす、

1 or 0 がはいっています。


CanJumpも同様で、その方向に飛べるかどうかを 1 or 0 であらわしています。


このやりかたは、うさぴょんの作者様のページ
将棋プログラムの作り方

をマネしたものです。感謝です。


さて、ようやく駒の動きをチェックする関数ですが、

これはわりと短いコードなので、とりあえず貼ってみます。


gist9107532


いちおうポイントとしては、14行目の、

if(board[moved.dan][moved.suji] != EMPTY)break;

というコードをいれることで、駒を飛びこえないようにしているところでしょうか。


この関数をつかうことで、駒の種類ごとの動きしかできないようになりました。

ただの将棋盤のページにも、変更を反映させたので、

よかったら動かしてみてください。

http://www54.atpages.jp/tetsuzuki/


つぎは、王手をチェックする関数をつくることになると思います。

それでは。

JavaScriptで将棋のルール その1 ~ 駒の位置の内部表現 ~

おひさしぶりになってしまいましたが、どうも、ただのあほです。


さて、とりあえず駒が動かせるだけの将棋盤ができていたわけですが、

今回から、将棋のルールを守った指し手(合法手)

しか指せないような将棋盤をつくっていきたいと思います。


C++のほうでは、とりあえず合法手を生成することができているので、

おんなじやりかたで、JavaScriptでもやっていきたいと思います。


しばらく C++JavaScript をいったりきたりすると思いますがお付き合いください。


まずは、これまで dan , sujiという2つの変数であらわしていたものを、

C++でいう構造体のように、ひとまとめにして扱いたいなということで、

いろいろ調べた結果、こういったコードを書いてみました。


gist9089303


Posという関数に dan , suji というプロパティをもたせて、

引数をそのままプロパティに代入するようにしました。


C++では構造体とかクラスというものがあるのですが、

それは、C++がクラスベースオブジェクト指向言語だからで、

JavaScirptはプロトタイプベースオブジェクト指向言語というものらしいです。


ついに「オブジェクト指向」という、

やたらとかっこいい言葉をつかう日がきてしまいました。

(言葉をつかうだけなら小学生でもできるので、つかいこなせるかどうかが問題です)


そのあたりは、こちらの記事がとても勉強になったのでリンクを貼っておきます。

JavaScriptにおけるオブジェクトの基本的性質:CodeZine

JavaScriptの関数とメソッド:CodeZine

プロトタイプ(prototype)によるJavaScriptのオブジェクト指向:CodeZine


C++からはいった自分にはこちらのページも参考になりました。

JavaScriptでオブジェクト指向しよう1・構造体


というわけで、つぎは、

「あるマスに、ある駒が動けるかどうか」 を調べる関数をつくりたいと思います。


それでは。