HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
1121
x-manUSI(Universal Shogi Interface)プロトコルのコマンド受信について16解決


x-man

リンク

2015/11/21(Sat) 13:51:38|NO.73168

USI(Universal Shogi Interface)プロトコルとは、将棋GUIソフトと思考エンジンが通信をするため考案された通信プロトコルです。
将棋所というソフトに組み込める思考エンジンをHSPで作りたいのですが、プロトコルコマンドの送受信の方法が分かりません。

プロトコル受信で調べても受信サーバー系のものしか出てきませんでした。
詳しい仕組みは分かりませんが、ネットサーバーに接続するわけではなく、直接コマンドをやり取りするのだと思うのです。
拡張ファイルが必要なのだと思いますが、そのあたりも詳しく教えていただけるとありがたいです。
私の理解が足りていないだけかもしれませんが、将棋ソフトの開発をしたいのでよろしくお願いします。

↓将棋所:USIプロトコルについてのURLです。
http://www.geocities.jp/shogidokoro/usi.html



この記事に返信する


mjhd

リンク

2015/11/21(Sat) 18:05:46|NO.73170

標準入出力を使ってやりとりを行うとのことなので,HSP3CLを使って,input命令とmes命令を使えば大丈夫だと思います.
試せないので,おそらくですが….


#runtime "hsp3cl" sdim buf, 512 repeat // コマンドを受け取る input buf, 512, 1 // 例えばここで // if (buf == "usi") : mes "id name HSP" // などとする loop



kanamaru

リンク

2015/11/21(Sat) 18:38:17|NO.73171

こんなサイトを見つけました。
http://sarushogi.blog.fc2.com/blog-entry-16.html



x-man

リンク

2015/11/22(Sun) 06:22:07|NO.73186

紹介していただいたサイトを参考にして思考エンジンとして登録することが出来ました。
標準入出力(input,mes)は画面に反映されるものだと思い込んでいたので、そのまま使えるとは盲点でした。
他のコマンドはまだ試していませんが少しずつ試していきたいと思います。
親切にありがとうございました。
また分からないことがあれば質問させていただきますので、そのときはよろしくお願いします。



x-man

リンク

2015/11/23(Mon) 17:34:37|NO.73219

投稿者です。
さる将棋のやり方でエンジン登録はできたのですが、その後のコマンドのやり取りができまぜん。
そこでなぜ出来ないのか考えたのですが、さる将棋のやり方は

>本当はinputStrの中身を確認(instr(inputStr, 0, "usi")!=0なら「usi」が送られてきた、とか)
>テスト的に動かすために、省略した。

と書かれているように、inputの内容を確認することなく一方的にコマンドの送信をしているものです。

そのためもしかしたらinputでコマンド受信はできないのではないかと思い至りました。
試しにはじめにコメントをしてくれたmjhdさんのをまるまるコピーして試してみましたが、やっぱりエンジン登録できません。
mesで相手に送信はできますがどうもコマンドの受信方法が間違っているように思います。

そのあたりも踏まえて、一体なぜコマンドの受信ができないのか、一緒に考えていただけると助かります。



kanamaru

リンク

2015/11/23(Mon) 17:55:05|NO.73220

どうしてなんでしょう?
そこでですが、、http://hsp.tv/play/pforum.php?mode=all&num=71398
を使ったらどうでしょう。



Noap

リンク

2015/11/23(Mon) 19:46:19|NO.73225

1ではなく2です

#runtime "hsp3cl" sdim input_output_buf,128 input input_output_buf,123,2 if input_output_buf=="usi"{ mes {"id name test-shogi id author test-shougi usiok"} } end



Noap

リンク

2015/11/23(Mon) 19:52:23|NO.73226




x-man

リンク

2015/11/24(Tue) 10:05:55|NO.73232

返信ありがとうございます。
いろいろ試して登録と、その後の挙動を調べていましたが、ひとつの仮定が生まれました。

それはRepeat~loopで処理している間はコマンドの送信を受け付けないのではないかというものです。
試しにNoapさんの書き方にRepeat~loopを組み込むとエンジン登録できませんでした。
(上記のEndで終わっているものはエンジン登録できます)
試しにエンジン登録はループ内に入れず、後の命令はRepeat~loopで送受信するように試みましたがうまくいきません。
もしかしたらHSPでは作ることが出来ないのではないかと不安になっています。
私のPCの挙動がおかしいだけなのか分かりませんが、良い改善案や、間違いがあれば教えてください。


#runtime "hsp3cl"

sdim input_output_buf,128

repeat
input input_output_buf,123,2

if input_output_buf=="usi"{
mes {"id name test-shogi
id author test-shougi
usiok"}
}
loop
end



kanamaru

リンク

2015/11/24(Tue) 12:25:14|NO.73233

ループ中に、waitかawaitを入れてみてください。
たぶんそれで解決です。



ゼーット!!

リンク

2015/11/24(Tue) 12:31:58|NO.73234

こんにちは。

hsp3clですが・・とりあえず、研究はできるかもしれませんが、ゲームを作るには厳しいかと思います。
標準コンソールを使用してGUIなゲームを作ることを目的とするならばパイプ(pipeexec)を
使ってHSPと通信をする必要があると思います。

ただ・・、HSP標準のpipeexecはpipeput、pipegetなどと連携して使うのですが、どうも使いづらく、
テストプログラム組んで試してみてもうまく動作しませんでした。

あちらこちら探してみたところ、月影ともさんという方が、使いやすいパイプモジュールを公開されてました。
>Win32 コンソール向きパイプ通信モジュール
http://tu3.jp/0569

このモジュールを、感謝の意を表しながらHPからもらって来て、pipe2.hsp という名前で保存します。
プログラムと同じフォルダ、もしくはHSPのcommonフォルダに入れてください。

以下、このモジュールを使用してのUSIとの通信テストプログラムです。
USIエンジンの Lesserkai.exe 等は、今プログラムのあるところのEngineフォルダ内にある前提です。

#include "pipe2.hsp" screen 0, 640, 480 title "pipe2execを使ってUSIプロコってみるテスト" sdim buf, 4016 //バッファサイズは適当 pid = 0 //これにパイプID入れる //実行ファイル指定 pipe2exec "Engine\\Lesserkai.exe" if stat < 0 { //エラー(↑実行ファイルの場所間違わないように。もしくは自分環境に書き換える) dialog "パイプ作成できず..げふっ" end } //パイプIDがstatに帰ってくるので回収する pid = stat //ためしに初期化コマンドを送ってみる //(最後に必ず"\n"を入れないと無限ループになるようだ)別に"usi\n"でもおk pipe2put pid, "usi" + "\n" //ループさせて状況を調べ、確定後先にすすむ repeat //パイプから来る情報を確認 pipe2check pid if stat & 1 { mes "pipe:実行中" } if stat & 2 { mes "pipe:標準出力" //標準出力でデータを受信 pipe2get pid, buf break } if stat & 4 { mes "pipe:エラー出力" //エラー出力でデータを受信 pipe2err pid, buf break } await 17 loop //USIエンジンから取得したデータを画面に表示する mes buf //パイプを閉じる pipe2term pid //最後にキメゼリフ mes "正常に終了したよ!" stop

きちんとUSIからの返事がありましたか?

実行中はパイプIDを使ってコマンド送信、受信確認、受信を繰り返す感じになります。
受信データはbufに入っているので、これを加工すればゲームに使えますね。

以上。(・ω・`)



mjhd

リンク

2015/11/24(Tue) 13:02:45|NO.73236

どうやら,hsp3clのmesは,stop命令が現れるまで内容を実際に出力しない(フラッシュしない)仕様のようです.
つまりmesがダメだったという….

こちら
http://hsp.tv/play/pforum.php?mode=pastwch&num=8923
を参考にして,mesの代わりにWriteFile関数を使うことでrepeat~loopを使っても将棋所などに登録できるようになりました.


#runtime "hsp3cl" // 標準出力を取得する #include "kernel32.as" #define STD_OUTPUT_HANDLE (-11) GetStdHandle STD_OUTPUT_HANDLE hStdOut = stat sdim input_buf,128 sdim output_buf,128 repeat input input_buf,128,2 // usiコマンド if input_buf == "usi" { // 返答を代入する(注意: 最後に改行を追加している) output_buf = {"id name test-shogi id author test-shougi usiok"} + "\n" // mesの代わり WriteFile hStdOut, varptr(output_buf), strlen(output_buf), 0, 0 } loop



ゼーット!!

リンク

2015/11/24(Tue) 15:53:19|NO.73238

あ、そうなのか。

「GUIを自分で作って、ショウギドコロに付属しているUSIエンジンと接続して−−−。」
ではなく、

「HSPでLesserkai.exeに代わるUSIエンジンを作りたい。」
ということなんですね。失敬失敬。

(ω−`;;)焦るわぁ。



Noap

リンク

2015/11/24(Tue) 18:00:10|NO.73240

mjhdさん指摘してくださりありがとうございます。
わたしもそのことには朝準備しているときに気がついていたのですが準備しているときはいそがしく昼は家ではないので当然掲示板に投稿することもできずもどかしい思いをずっとしていました。
ただmjhdさんのコードには問題がありましてそれでは登録した後終了されずHSPのプロセスが残ったままになってしまいます。

わたしの手抜きが原因でした。
この自作のモジュールを使って説明のスクリプトを書いたのですが、モジュールを投稿することがじゃまに感じて適当に出力バッファのことを考えずにmes2をmesに変えて投稿しました。
出力バッファのことをちゃんと説明していなくてすみませんでした。



#module #uselib "kernel32.dll" #cfunc GetStdHandle "GetStdHandle" int #func WriteFile "WriteFile" sptr, sptr, int, sptr, sptr #define STD_OUTPUT_HANDLE $FFFFFFF5 #define INVALID_HANDLE_VALUE (-1) #deffunc _mes2_writefile str p1, local sz_buf, local in_size_written, local h_standard_output sz_buf=p1 h_standard_output= GetStdHandle( STD_OUTPUT_HANDLE ) if h_standard_output!=INVALID_HANDLE_VALUE { WriteFile h_standard_output, varptr(sz_buf), strlen(sz_buf), varptr(in_size_written), 0 } return in_size_written #global #define mes2(%1="") _mes2_writefile ""+%1 #define BUFSIZE 128 sdim input_output_buf,BUFSIZE repeat input input_output_buf,BUFSIZE-1,2 if input_output_buf=="usi"{ mes2 {"id name test-shogi id author test-shougi usiok "} } if input_output_buf=="quit"{ break } loop end



x-man

リンク

2015/11/25(Wed) 03:02:34|NO.73252

返信ありがとうございます。
Noapさんのをコピーして試したところエラー33 オブジェクト数が多すぎます とでます。
ループ内で何度もinputを設置しているせいだと思いますので、今のままだと使えません。
解消しようとclrobjを組み込みましたがうまくいきません。解決方法を教えてください。

それとmjhdさんのWriteFile関数を使うプログラムですが、実行したものをデバッグウィンドウで見るとなぜか

>C:usi
<C:id name test-shogi
<C:id author test-shougi
<C:usiok
>C:quit

のように最後にquitが返信されています。他の人のはquitが返されていません。
この違いはどこから来るのか分からないのでおしえてください。



皆さんのおかげでエンジン受信はできるようになりましたが、その後の対局開始からの送受信ができません。
isreadyコマンドを受け取ったらreadyokを返さなければいけないのですが、usiを受信したのと同じように書いて返信しようとしても反応してくれません。

test-shogi対人間 で開始ボタンを押したときのデバッグウィンドウは下記のように返されます。

>1:usi
<1:id name test-shogi
<1:id author test-shougi
<1:usiok
>1:setoption name USI_Ponder value true
>1:setoption name USI_Hash value 256
>1:isready

エンジン登録できても対局できなければ意味がないので、どうすればいいのか教えてください。
デバッグウィンドウは「表示」の一番下、もしくはCtrl+Dで確認できます。



Noap

リンク

2015/11/25(Wed) 06:26:29|NO.73253

今いそがしいくてあわててかので間違いがあるかもしれません
そのスクリプトは#runtime "hsp3cl"を前につけてください


#runtime "hsp3cl" #module #uselib "kernel32.dll" #cfunc GetStdHandle "GetStdHandle" int #func WriteFile "WriteFile" sptr, sptr, int, sptr, sptr #define STD_OUTPUT_HANDLE $FFFFFFF5 #define INVALID_HANDLE_VALUE (-1) #define BUFSIZE 128 #deffunc _mes2_writefile str p1, local sz_buf, local in_size_written, local h_standard_output sz_buf=p1 h_standard_output= GetStdHandle( STD_OUTPUT_HANDLE ) if h_standard_output!=INVALID_HANDLE_VALUE { WriteFile h_standard_output, varptr(sz_buf), strlen(sz_buf), varptr(in_size_written), 0 } return in_size_written #global #define mes2(%1="") _mes2_writefile ""+%1 sdim input_output_buf,BUFSIZE repeat input input_output_buf,BUFSIZE-1,2 switch input_output_buf case "usi" mes2 {"id name test-shogi id author test-shougi usiok "} swbreak case "quit" break case "isready" mes2 "readyok\n" swbreak swend loop end



x-man

リンク

2015/11/25(Wed) 08:54:11|NO.73256

Noapさん、ありがとうございます。
おかげさまで対局開始から、時間切れ負けまでちゃんと動きました。
これでようやく開発に入れます。
私はプログラムの知識に乏しく分からないことだらけなので、今後も相談することもあると思います。
できるだけ自分で解決を試みますが、どうしても分からないときはまた知恵を貸していただけると幸いです。

↓エンジン登録から対局終了までのデバッグウィンドウの内容です。

>C:usi
<C:id name test-shogi
<C:id author test-shougi
<C:usiok
>C:quit
>1:usi
<1:id name test-shogi
<1:id author test-shougi
<1:usiok
>1:setoption name USI_Ponder value true
>1:setoption name USI_Hash value 256
>1:isready
<1:readyok
>1:usinewgame
>1:position startpos
>1:go btime 0 wtime 0 byoyomi 10000
>1:gameover lose
>1:quit



ONION software Copyright 1997-2021(c) All rights reserved.