C++用将棋ライブラリ"OpenShogiLib"の紹介

65
C++ 用用用用用用用用 "OpenShogiLib" 用用 H.Hiro (Sapporo.cpp) http://hhiro.net/ab out/ Twitter: @h_hiro _ 2013.7.13 CLR/H & Sapporo.cpp 用用用

description

2013.7.13 CLR/H & Sapporo.cpp 勉強会で発表

Transcript of C++用将棋ライブラリ"OpenShogiLib"の紹介

Page 1: C++用将棋ライブラリ"OpenShogiLib"の紹介

C++用将棋ライブラリ"OpenShogiLib"の紹介 H.Hiro (Sapporo.cpp)

http://hhiro.net/about/Twitter: @h_hiro_

2013.7.13 CLR/H & Sapporo.cpp 勉強会

Page 2: C++用将棋ライブラリ"OpenShogiLib"の紹介

自己紹介

Page 3: C++用将棋ライブラリ"OpenShogiLib"の紹介

H.Hiro•大学院生•現在は就活と研究が同時並行なので忙しめです•こんなアイコン使ってます→

Page 4: C++用将棋ライブラリ"OpenShogiLib"の紹介

H.Hiro• Sapporo.cpp• Ruby札幌•数学勉強会@札幌   :いろいろやってます

Page 5: C++用将棋ライブラリ"OpenShogiLib"の紹介

部分文字列の取得を

効率よく!楽に!~ fundoshi.hppの紹介と

今後の予定~

Photo by KAIZUKACreative Commons BY-NC-SA 2.0

http://www.flickr.com/photos/kaizuka/386511394/

http://www.slideshare.net/maraigue/20121117-clrhc-fundoshihpp

【前回の発表 (2012.11.17)】

Page 6: C++用将棋ライブラリ"OpenShogiLib"の紹介

宣伝

Page 7: C++用将棋ライブラリ"OpenShogiLib"の紹介

http://www.ospn.jp/osc2013-do/• 今年は 9月なのでお間違いなく!• 場所もコンベンションセンターなのでお間違いなく!• ブース・セミナー申込締切は

7月 22日(月)です

Page 8: C++用将棋ライブラリ"OpenShogiLib"の紹介

よろしくお願いします

Page 9: C++用将棋ライブラリ"OpenShogiLib"の紹介

本題

Page 10: C++用将棋ライブラリ"OpenShogiLib"の紹介

C++用将棋ライブラリ"OpenShogiLib"の紹介 H.Hiro (Sapporo.cpp)

http://hhiro.net/about/Twitter: @h_hiro_

Page 11: C++用将棋ライブラリ"OpenShogiLib"の紹介

ということでこれから将棋の話をするわけですが

Page 12: C++用将棋ライブラリ"OpenShogiLib"の紹介

第 2回電王戦(プロ棋士とコンピュータの五番勝

負 )http://ex.nicovideo.jp/denousen2013/

Page 13: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータ側の第 5局を

戦った「 GPS将棋」http://gps.tanaka.ecc.u-tokyo.ac.jp/gpsshogi/

Page 14: C++用将棋ライブラリ"OpenShogiLib"の紹介

このうち、汎用的な部分を切り出したのがOpenShogiLibです

Page 15: C++用将棋ライブラリ"OpenShogiLib"の紹介

さて

Page 16: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータに将棋を扱わせるに

は何が必要か

Page 17: C++用将棋ライブラリ"OpenShogiLib"の紹介

[質問 ]将棋をよく /たま

にやるよ!という方

Page 18: C++用将棋ライブラリ"OpenShogiLib"の紹介

[質問 ]将棋はあまりしないけど

何となくどんなゲームかは分かる

Page 19: C++用将棋ライブラリ"OpenShogiLib"の紹介

今日必要な前提知識 (1/3)将棋は、二人が順番に駒を動かすゲームです

駒の動かし方の表を別途配布しております

Page 20: C++用将棋ライブラリ"OpenShogiLib"の紹介

今日必要な前提知識 (1/3)将棋は、二人が順番に駒を動かすゲームです

取った駒は盤上に打つことができます

Page 21: C++用将棋ライブラリ"OpenShogiLib"の紹介

今日必要な前提知識 (2/3)駒にはそれぞれ動きが決められています

Page 22: C++用将棋ライブラリ"OpenShogiLib"の紹介

今日必要な前提知識 (3/3)勝利条件は、相手の玉(王 )を取ることです

右図のように、実際に玉を取らなくても、次に取れることが確定すれば勝ち (詰み )。

Page 23: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータ上で将棋を扱うのに必要そうなデータ

構造

Page 24: C++用将棋ライブラリ"OpenShogiLib"の紹介

•将棋盤 (81マス )•将棋駒 (40個 )•駒が動ける場所

Page 25: C++用将棋ライブラリ"OpenShogiLib"の紹介

•将棋盤 (81マス )→9×9の 2次元配列?•将棋駒 (40個 )→40個の配列?•駒が動ける場所→ 8種をハードコーディング→ルール上動けない場所

Page 26: C++用将棋ライブラリ"OpenShogiLib"の紹介

OpenShogiLibがこれらを全部

提供してくれます

Page 27: C++用将棋ライブラリ"OpenShogiLib"の紹介

導入方法&

簡単な利用方法

Page 28: C++用将棋ライブラリ"OpenShogiLib"の紹介

導入方法• # apt-get install libosl-dev

•ソースコードから導入の場合、 boostが必要•Windowsでは試してませんもしかしたら面倒かも

Page 29: C++用将棋ライブラリ"OpenShogiLib"の紹介

// http://blog.livedoor.jp/maraigue/archives/1711816.html

// SimpleStateは盤面のみを保持するクラスstate::SimpleState sstate(osl::HIRATE);// NumEffectStateは盤面+駒の動きを扱えるクラスstate::NumEffectState nstate(sstate);

Move move;// 先手 (BLACK)の (7,7)にある PAWN(歩兵 )を、// (7,6)という何もないマス (PTYPE_EMPTY)に動かすmove = Move(Square(7,7), Square(7,6), PAWN, PTYPE_EMPTY, false, BLACK);if(nstate.isValidMove(move)){ nstate.makeMove(move);}

Page 30: C++用将棋ライブラリ"OpenShogiLib"の紹介

// http://blog.livedoor.jp/maraigue/archives/1711816.html

// SimpleStateは盤面のみを保持するクラスstate::SimpleState sstate(osl::HIRATE);// NumEffectStateは盤面+駒の動きを扱えるクラスstate::NumEffectState nstate(sstate);

Move move;// 先手 (BLACK)の (7,7)にある PAWN(歩兵 )を、// (7,6)という何もないマス (PTYPE_EMPTY)に動かすmove = Move(Square(7,7), Square(7,6), PAWN, PTYPE_EMPTY, false, BLACK);if(nstate.isValidMove(move)){ nstate.makeMove(move);}

Page 31: C++用将棋ライブラリ"OpenShogiLib"の紹介

// http://blog.livedoor.jp/maraigue/archives/1711816.html

// SimpleStateは盤面のみを保持するクラスstate::SimpleState sstate(osl::HIRATE);// NumEffectStateは盤面+駒の動きを扱えるクラスstate::NumEffectState nstate(sstate);

Move move;// 先手 (BLACK)の (7,7)にある PAWN(歩兵 )を、// (7,6)という何もないマス (PTYPE_EMPTY)に動かすmove = Move(Square(7,7), Square(7,6), PAWN, PTYPE_EMPTY, false, BLACK);if(nstate.isValidMove(move)){ nstate.makeMove(move);}

Page 32: C++用将棋ライブラリ"OpenShogiLib"の紹介

これで、とりあえず

将棋が指せることはわかった

Page 33: C++用将棋ライブラリ"OpenShogiLib"の紹介

では、もう少し凝ったことをしてみよう

Page 34: C++用将棋ライブラリ"OpenShogiLib"の紹介

詰将棋

Page 35: C++用将棋ライブラリ"OpenShogiLib"の紹介

こんなのが詰将棋です

Page 36: C++用将棋ライブラリ"OpenShogiLib"の紹介

こんなのが詰将棋です

Page 37: C++用将棋ライブラリ"OpenShogiLib"の紹介

詰将棋の目的 :王手のみを続けて相手の玉を詰める

Page 38: C++用将棋ライブラリ"OpenShogiLib"の紹介

まずは人手で解いてみる

Page 39: C++用将棋ライブラリ"OpenShogiLib"の紹介

人手だと何となく

「この手が正解っぽい」

と分かるけど

Page 40: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータにはどう解かせる?

Page 41: C++用将棋ライブラリ"OpenShogiLib"の紹介

詰将棋の目的 :王手のみを続けて相手の玉を詰める

Page 42: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータには王手になる手を総当りで指させる

Page 43: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータには王手になる手を総当りで指させる

(自分の立場 )

Page 44: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータには王手を回避する手

を総当りで指させる

(相手の立場 )

Page 45: C++用将棋ライブラリ"OpenShogiLib"の紹介

•詰みとなる条件相手がどう指そうとも自分の手によっては王手を回避できなくなる•詰まない条件自分がどう指そうとも相手の手によっては王手をかけられなくなる

Page 46: C++用将棋ライブラリ"OpenShogiLib"の紹介

ここから王手になる手は?

Page 47: C++用将棋ライブラリ"OpenShogiLib"の紹介

実は 4通りある

Page 48: C++用将棋ライブラリ"OpenShogiLib"の紹介

先に進めると手の数はすごいことになる

Page 49: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータに全部試させればよい

// [駒を動かして王手 ]ActionTryMove acm(mt_new, nstate, depth, max_depth);

for(int i = 0; i < osl::Piece::SIZE; ++i){p = nstate.pieceOf(i);if(p.isOnBoardByOwner(osl::BLACK)){

// 盤上にある先手の駒の場合

nstate.forEachEffectOfPiece<ActionTryMove>(p, acm);}

}valid_moves += acm.valid_moves();

Page 50: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータに全部試させればよい

// [駒を動かして王手 ]ActionTryMove acm(mt_new, nstate, depth, max_depth);

for(int i = 0; i < osl::Piece::SIZE; ++i){p = nstate.pieceOf(i);if(p.isOnBoardByOwner(osl::BLACK)){

// 盤上にある先手の駒の場合

nstate.forEachEffectOfPiece<ActionTryMove>(p, acm);}

}valid_moves += acm.valid_moves();

将棋で用いる全部の駒(40個 )についてループ

Page 51: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータに全部試させればよい

// [駒を動かして王手 ]ActionTryMove acm(mt_new, nstate, depth, max_depth);

for(int i = 0; i < osl::Piece::SIZE; ++i){p = nstate.pieceOf(i);if(p.isOnBoardByOwner(osl::BLACK)){

// 盤上にある先手の駒の場合

nstate.forEachEffectOfPiece<ActionTryMove>(p, acm);}

}valid_moves += acm.valid_moves();

動かしてみる

Page 52: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータに全部試させればよい

// class ActionTryMove の中身template<osl::Player pl> void doAction(const osl::Piece & pc, const osl::Square & sq){

/*(中略 )*/if(osl::isPiece(pc.ptype()) &&

osl::canPromote(pc.ptype())){// 成れる駒ならば、成ってみるif(recursive_search(/*(中略 )*/) != -2){ +

+valid_moves_; }}// 成らない場合if(recursive_search(/*(中略 )*/) != -2){ +

+valid_moves_; }}

Page 53: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータに全部試させればよい

// class ActionTryMove の中身template<osl::Player pl> void doAction(const osl::Piece & pc, const osl::Square & sq){

/*(中略 )*/if(osl::isPiece(pc.ptype()) &&

osl::canPromote(pc.ptype())){// 成れる駒ならば、成ってみるif(recursive_search(/*(中略 )*/) != -2){ +

+valid_moves_; }}// 成らない場合if(recursive_search(/*(中略 )*/) != -2){ +

+valid_moves_; }}

成れるかどうか判定し成らないケースとともに試す

Page 54: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータに全部試させればよい

if(nstate.isValidMove(*p_move)){ // 動かせるか確認nstate.makeMove(*p_move); // 動かす// (先手が指した結果の場合)後手玉が王手になっている// (後手が指した結果の場合)後手玉が王手になっていないif(logical_xor(depth % 2 == 1, nstate.inCheck(osl::WHITE))){

mt_new = MoveTree::createNewPtr(*p_move);mt->children.push_back(mt_new);

}else{return -2;

}}else{

return -2; // 動かせない場合}

Page 55: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータに全部試させればよい

if(nstate.isValidMove(*p_move)){ // 動かせるか確認nstate.makeMove(*p_move); // 動かす// (先手が指した結果の場合)後手玉が王手になっている// (後手が指した結果の場合)後手玉が王手になっていないif(logical_xor(depth % 2 == 1, nstate.inCheck(osl::WHITE))){

mt_new = MoveTree::createNewPtr(*p_move);mt->children.push_back(mt_new);

}else{return -2;

}}else{

return -2; // 動かせない場合}

まず、将棋のルールとして動けるかをチェック

Page 56: C++用将棋ライブラリ"OpenShogiLib"の紹介

コンピュータに全部試させればよい

if(nstate.isValidMove(*p_move)){ // 動かせるか確認nstate.makeMove(*p_move); // 動かす// (先手が指した結果の場合)後手玉が王手になっている// (後手が指した結果の場合)後手玉が王手になっていないif(logical_xor(depth % 2 == 1, nstate.inCheck(osl::WHITE))){

mt_new = MoveTree::createNewPtr(*p_move);mt->children.push_back(mt_new);

}else{return -2;

}}else{

return -2; // 動かせない場合}

続いて、王手をかける /回避するという条件をチェック

Page 57: C++用将棋ライブラリ"OpenShogiLib"の紹介

実際に動かしてみる

https://github.com/maraigue/clrhsapporocpp-20130713

Page 58: C++用将棋ライブラリ"OpenShogiLib"の紹介

補足

Page 59: C++用将棋ライブラリ"OpenShogiLib"の紹介

•詰将棋を解くだけならOpenShogiLibに最初からコードがある•でも、それ以上のことをしたかったので自前で書いた

Page 60: C++用将棋ライブラリ"OpenShogiLib"の紹介

詰将棋制作支援のプログラムが欲しかった•回答が一意に定まる必要•余計な駒を使わない:

Page 61: C++用将棋ライブラリ"OpenShogiLib"の紹介

•そういう機能を持つソフトもあるのだが有料なうえに絶版•なので自分で作りたかった

Page 62: C++用将棋ライブラリ"OpenShogiLib"の紹介

おわりに

Page 63: C++用将棋ライブラリ"OpenShogiLib"の紹介

将棋は自身で遊ぶだけでなくてコンピュータ的にも奥が深いです

Page 64: C++用将棋ライブラリ"OpenShogiLib"の紹介

OpenShogiLibはドキュメントがあまり整

備されてないので

Tipsをブログとかに書くと

喜ばれるかも?

Page 65: C++用将棋ライブラリ"OpenShogiLib"の紹介

ありがとうございました