読者です 読者をやめる 読者になる 読者になる

#16 あの娘と内緒に将棋を指したい

AdventCalendar2014 ruby 将棋
tech.kayac.com Advent Calendar 2014の16日目です。
今回アドベントカレンダー初参加の森です。

今年も竜王戦が終わり、年末になってきた感がありますが、見ていると指してきたくなってきますよね。
そこで、仕事中に指せる将棋盤を作ってみました。コンソールでさせるリモート将棋盤です。これで、あなたも斜め前のあの娘と内緒で心と心の会話が出来ます。

そして、それがこれです。


どーん
jchess__.gif

色とか付いちゃっててバレバレ間は否めないですが、とりあえずすすめましょう。
まずは使い方からです。

使い方

まず、github からcloneします。
git clone git@github.com:kozakana/console-jchess.git
bundle install --path vendor/bundle
コードの準備が出来たところで、次はサーバーを起動します。
bundle exec ruby jcserver.rb
次にクライアントを起動します。(先にサーバーに接続した方が先手になります)
bundle exec ruby jcclient.rb -i <サーバーのIPアドレス>
もし、ネットワークが不安定等で途中で切断されてしまった場合は-rオプションで再接続できます。あの娘と再接続できなくなってしまっては、げんなりですからね。
bundle exec ruby jcclient.rb -r

コマンド

move

その名の通り駒を動かします。元の駒の位置と動かす先の駒の位置を指定します。
こんな感じです。

move 77 76

set

駒台にある駒を盤上に置きます。
こんな感じで使います。

set 74 fu
ちなみに、駒の名前は下記の様に指定してください。
  • 王/玉:ou
  • 金将 :kin
  • 銀将 :gin
  • 桂馬 :kei
  • 香車 :kyo
  • 歩行 :fu
  • 飛車 :hi
  • 角行 :kaku

print

盤面を表示します。
first/secondを指定すると先手/後手から見た盤面を表示できます。
first/secondを省略した場合は自分の手番から見た盤面を表示します。

print second

makemashita / mairimashita

負けました派にも参りました派にも対応しています。打ち間違えるとかっこ悪いので、一度心を落ち着かせた後対局できてありがとうという気持ちで入力しましょう。

help

困ったらすぐhelp

技術的な部分

普段あまり使わないライブラリ等を使用したので、最後にちょっとだけ技術的な部分にも触れておきます。

dRuby

通信部分にはdRubyを使用しています。エラーの出かたが複雑になるので、そこらへんは少し大変ですが使い方はとても簡単です。

サーバー側

下記のようにポート番号(1117)とクライアントに渡すインスタンス(Board.instance)を設定するだけです。あとは、終了しないよう無限ループとかにしたら準備完了です。
require 'drb/drb’

DRb.start_service(“druby://:1117", Board.instance)

while true
  sleep 1
end

クライアント側

接続先サーバーのIPアドレス(localhost)とポート番号(1117)を指定するだけで、返り値がサーバー側で設定したインスタンスを得る事が出来ます。
DRbObject.new_with_uri("druby://localhost:1117")

Readline

コマンド入力にはReadlineを使用しました。ちなみに1文字ずつ入力を受け取ったり、もっとリッチに画面書き換えなどをしたい場合はcursesというライブラリがあります。
require ‘readline'

WORDS = %w(move set print help)

Readline.completion_proc = proc {|word|
      WORDS.grep(/\A#{Regexp.quote word}/)
}
line = Readline::readline(“> ")

Readline::HISTORY.push(line)

使い方

line = Readline::readline(“> “)
主要な部分はこの一行だけです。 Readline::readlineの引数に文字列を渡す事でプロンプト部分(“ >")を好きな様に変更できます。返り値は入力文字列です。

履歴

文字列をHISTORYにpushする事で履歴に入れられます。
また、Readline::HISTORY.to_aで履歴の表示もできます。

Readline::HISTORY.push(line)

予測変換

予測変換はReadline.completion_procにprocオブジェクトを入れておく事で、tabキーが押された時ブロック引数に入力途中の”ワード”が渡されます。
例えば、moまで入力されてタブが入力された場合はブロック引数には”mo”の文字列が渡されます。また、”move 3”と入力された場合は入力中の”ワード”が渡されるので”3"が渡されます。

Readline.completion_proc = proc {|word|
      WORDS.grep(/\A#{Regexp.quote word}/)
}

最後に

今回のはコマンドライン上でのみ実行してプレイ出来るというものですが、あえてコマンドラインでのみ使用できるようにすることで駒の移動判定部分だけを切り出して他の部分のみを使おうとか、盤の部分を改良して使おうというように部品として使えたらいいなと思っています。

カヤックではエンジニアを募集しています!

カヤックでは将棋が好きなエンジニアも将棋に興味がないエンジニアも大歓迎です!
社員と直接話せるイベント、一社だけの合同説明会を、1月17日(土)に渋谷ヒカリエで開催します!見に行くだけでも良いのでぜひご参加ください!

明日のアドベントカレンダーは

明日は安定感抜群の@nobu_ohtaです。個人的にもかなり注目しています!