LoginSignup
3
4

More than 5 years have passed since last update.

FXRubyでどうぶつ将棋をつくろう

Last updated at Posted at 2016-07-01

はじめに

「wxPythonでオセロをつくろう」の姉妹編です。
Rubyの勉強がしたい、そうだ、どうぶつ将棋をつくろう。
Rubyで簡単にマルチプラットフォームで動作するGUIアプリを作成できるFXRubyを使用して、どうぶつ将棋をつくってみます。
この記事に触発されてポーカーやバックギャモンなど作っていただければ嬉しいです。
どうぶつ将棋とは?という方はWikipediaをご覧ください。
ソースはGitHubに上げてありますので、そちらから取得してください。

FXRubyのインストール

  • LinuxMint(Ubuntu, Debian)
$ sudo apt-get install ruby-full
$ sudo apt-get install libfox-1.6-dev
$ sudo apt-get install libxrandr-dev
$ sudo gem install fxruby

他のディストリビューションでもruby gemがインストールできれば、あとは同様だと思います。

  • Windows
    • こちらから、以下をダウンロードしてインストールします。32bit/64bitはご自身の環境に合わせてください。
      • rubyinstaller-x.x.x.exe  
    • コマンドプロンプトで以下を実行します。
gem install fxruby

FXRuby Tips

今回、FXRubyを使用していてハマったところを紹介します。参考になればと思います。

  • FXTextのテキストクリア方法
    • FXText.clearTextとかあるだろう、と思ってましたが、無い... indexを指定してテキストを消すremoveTextしかありません。そのためテキストのクリアは以下のようにやりました。
...
@log_text = FXText.new(sub_frame_mid, :opts => LAYOUT_FIX_WIDTH| \
                           LAYOUT_FIX_HEIGHT, :width => 300, :height => 200)
...
@log_text.removeText(0, @log_text.length)
  • FXTableのIconセット時に"illegal icon specified"のエラーが出る場合の対処
    • 詳しくはこちらを参照ください。強引ですが手っ取り早く解決するには、最初に作成したアイコンすべてを、一旦フォーム上に表示させておく、という方法があります。具体的には以下のようにします。
  def initialize(app)
    ...  

    # out_table is needed for showing all icon to use.
    # refer to "http://fox-toolkit.org/faq.html#ILLEGALICON"
    #
    # out_tableの:width=>5がミソです。幅を狭くしてGUI上に見えないようにしています。
    # こうして一度GUIに表示してしまえば、どのiconでもillegalにならずに使えます。
    out_frame = FXHorizontalFrame.new(base_frame, :opts => LAYOUT_FIX_WIDTH| \
                                      LAYOUT_FIX_HEIGHT, :x => 870, :width=>5,\
                                      :height => 480)
    @out_table = FXTable.new(out_frame, :opts => LAYOUT_FILL|TABLE_READONLY)
    @out_table.defColumnWidth = 90
    @out_table.defRowHeight = 120
    @out_table.setTableSize(4,3)
    @out_table.rowHeaderMode = LAYOUT_FIX_WIDTH
    @out_table.rowHeaderWidth = 0
    @out_table.columnHeaderMode = LAYOUT_FIX_HEIGHT
    @out_table.columnHeaderHeight = 0
    # show all icon to use
    @out_table.setItemIcon(0, 0, @piece_lion)
    @out_table.setItemIcon(0, 1, @piece_lion_inv)
    @out_table.setItemIcon(0, 2, @piece_giraffe)
    @out_table.setItemIcon(1, 0, @piece_giraffe_inv)
    @out_table.setItemIcon(1, 1, @piece_elephant)
    @out_table.setItemIcon(1, 2, @piece_elephant_inv)
    @out_table.setItemIcon(2, 0, @piece_cock)
    @out_table.setItemIcon(2, 1, @piece_cock_inv)
    @out_table.setItemIcon(2, 2, @piece_chick)
    @out_table.setItemIcon(3, 0, @piece_chick_inv)

    ...
  • FXTableのHeader行(列)を無くす
    • FXTableを普通に使うと、以下のグレーの部分のようにHeader行(列)ができてしまいます。

fix_cell.png

  • 今回のようにテーブル全部にアイコンを並べたい場合にはHeader行(列)は邪魔です。消すには単にHeader行(列)の幅(高さ)を"0"にします。
    @main_table = FXTable.new(main_frame, :opts => LAYOUT_FILL|TABLE_READONLY)
    @main_table.defColumnWidth = 90
    @main_table.defRowHeight = 120
    @main_table.setTableSize(4,3)
    ## hide table header row and col
    @main_table.rowHeaderMode = LAYOUT_FIX_WIDTH
    @main_table.rowHeaderWidth = 0
    @main_table.columnHeaderMode = LAYOUT_FIX_HEIGHT
    @main_table.columnHeaderHeight = 0

動作確認環境

  • LinuxMint 17.3 (ruby 1.9.3p484 + fxruby 1.6.34)
  • Windows10 (ruby 2.2.4p230 + fxruby 1.6.34)

遊び方

animal_chess.png

Game Modeを選んでGame Startを押してプレイします。下側が先攻の陣地です。

  • Game Mode

    • Man vs Comp : 人が先攻、コンピュータが後攻
    • Comp vs Man : コンピュータが先攻、人が後攻
    • L : Lion (ライオン)
    • E : Elephant (ゾウ)
    • G : Giraffe (キリン)
    • c(小文字) : chick (ひよこ)
    • C(大文字) : cock (にわとり)

駒の動かせる位置は駒の赤丸で示しています。
ウィンドウの右側の上下のTableは相手から取った持ち駒が表示されます。
あとは駒を交互に動かします。コンピュータは自動で動かします。
相手のライオンを取る(catch)、または相手の陣地の奥一段に自分のライオンを動かす(try)すれば勝利です。

  • 制限事項
    • 千日手の実装はしていません。
    • ライオンは相手の次手で取られる位置にも動かせます。
    • 一度つかんだ駒は戻せません。ただ、どこにも動かせない駒をつかんだ場合は元に戻せます。

コンピュータのAIの実装

以下の場所にインプリできます。

  def decide_next_move(move_pieces, pos_list, got_pieces)
    from = []
    to = []

    #### insert computer AI here. ####

    ...

    ##################################

    p "from = " + from.to_s
    p "to = " + to.to_s
    return from, to
  end

現状、インプリに使用できる情報として、「動かせる駒のリスト」(move_pieces)、「動かせる駒が移動できる場所のリスト、のリスト」(pos_list)、「移動した結果取れる駒のリスト、のリスト」(got_pieces) が用意してあります。
現在インプリされているAIは非常に拙いもので、「相手のライオンが取れる状態の場合はライオンを取る」、「その他の場合は打てる手をランダムで打つ」というものになっています。

ぜひ自分で強いAIを作成して、友人と戦ってみてください。
一人が Man vs Computer, もう一人が Computer vs Manを使用すれば、それぞれのコンピュータAI同士で勝負できます。
(相手の手をManの手としてそれぞれ入力していく)

2種類のAIを実装してComputer vs Computerで戦わせるのもおススメです。
(AIの切り替え機構は入れていないので、別途インプリが必要です。)

参考

http://www.fxruby.org/doc/book.html
http://fxruby.org/doc/api/
http://fox-toolkit.org/
http://www.rubydoc.info/gems/fxruby

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4