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

ゆとりーなの日記

日記的な事を書いて行くと思はれる

今年もあと二日だけどBoostでいくよ!

同人ゲーム制作に使えそうなBoostまとめ的な物はまだまだ続くんです。

その9:range_ex

色々とお世話になることの多い標準のアルゴリズムですが、イテレータの組渡すのだるいよ、というか組間違えたらどないすんねんと思ったあなたにはrange-baseのアルゴリズムをどうぞ。以下は色々なアルゴリズムを使ってみた例です。

#include <array>
#include <iostream>
#include <vector>
#include <boost/range/algorithm.hpp>
#include <boost/range/algorithm_ext.hpp>

int main() {
  const std::array<int, 4> v1 = {0, 1, 2, 3};
  boost::for_each(v1, [](int x) {std::cout << x << " ";});
  std::cout << std::endl;
  std::vector<int> v2;
  boost::copy(v1, std::back_inserter(v2));
  boost::for_each(v2, [](int x) {std::cout << x << " ";});
  std::cout << std::endl;
  std::vector<int> v3;
  boost::transform(v2, std::back_inserter(v3), [](int x) {return x * x;});
  boost::for_each(v3, [](int x) {std::cout << x << " ";});
  std::cout << std::endl;
  std::cout << *boost::find(v3, 4) << std::endl;
  boost::remove_erase_if(v3, [](int x) {return x < 4;});
  boost::for_each(v3, [](int x) {std::cout << x << " ";});
  std::cout << std::endl;
  return 0;
}

出力

0 1 2 3
0 1 2 3
0 1 4 9
4
4 9

その10:msm

状態遷移をやってくれる子です。ゲームでも状態遷移を扱うことは多いと思うのでそんなときに使えるかもしれません。以下はオープニングが終わったらタイトルに行って、startを入れたらゲーム開始、それ以外を3回入れたらオープニングに戻る的な状態遷移の例です。

#include <iostream>
#include <string>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>

struct start {};
struct opening_end {};
struct title_time_up {};
struct run {};

struct opening : public boost::msm::front::state<> {
  template<class Event, class FSM>
  void on_entry(const Event& event, FSM &fsm) {
    std::cout << "美しい連携が今、始まる!" << std::endl;
    fsm.process_event(opening_end());
  }
};

struct title : public boost::msm::front::state<> {
  title() : count_(0) {}

  template<class Event, class FSM>
  void on_entry(const Event& event, FSM &fsm) {
    std::cout << "タイトル画面ですよ\nコマンド:" << std::endl;
    std::string str;
    std::cin >> str;
    if (str == "start") {
      count_ = 0;
      fsm.process_event(start());
    } else {
      ++count_;
    }
    if (count_ > 2) {
      fsm.process_event(title_time_up());
    }
  }

 private:
  int count_;
};

struct game : public boost::msm::front::state<> {
  template<class Event, class FSM>
  void on_entry(const Event& event, FSM &fsm) {
    std::cout << "ゲーム画面ですよ\nコマンド:" << std::endl;
    std::string str;
    std::cin >> str;
  }
};

struct framework_t : public boost::msm::front::state_machine_def<framework_t> {
  struct transition_table : public boost::mpl::vector<_row<opening, start, title>,
                                                      _row<opening, opening_end, title>,
                                                      _row<opening, run, opening>,
                                                      _row<title, title_time_up, opening>,
                                                      _row<title, start, game>,
                                                      _row<title, run, title>,
                                                      _row<game, run, game>> {};
  typedef opening initial_state;
};

typedef boost::msm::back::state_machine<framework_t> framework;

int main() {
  framework f;
  f.start();
  for (;;) {
    f.process_event(run());
  }
  return 0;
}

出力

美しい連携が今、始まる!
タイトル画面ですよ
コマンド:
hoo
タイトル画面ですよ
コマンド:
hoge
タイトル画面ですよ
コマンド:
hage
美しい連携が今、始まる!
タイトル画面ですよ
コマンド:
start
ゲーム画面ですよ
コマンド:
・
・
・

その11:tokenizer

簡単なゲームの内部データにcsv形式を使うことがあるかもしれません。コンマ区切りのデータをお手軽に使いたいときはこの子の出番です。以下はコンマ区切りの文字列を列挙する例です。

#include <algorithm>
#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>

int main() {
  const std::string str = "nishiogikubo,ogikubo,asagaya,koenji";
  const boost::char_separator<char> sep(",");
  const boost::tokenizer<boost::char_separator<char>> tokens(str, sep);
  std::for_each(tokens.begin(), tokens.end(), [](const std::string &str) {
    std::cout << str << std::endl;
  });
  return 0;
}

出力

nishiogikubo
ogikubo
asagaya
koenji

その12:property_tree

設定ファイルにiniファイルを使っているのであればこの子は凄い便利です。win32で読もうとしていた時の面倒さと比べたらもうほんとに楽です。以下は適当なiniファイルを読む例です。
test.ini

[Alice]
Val = 10 
Str = Seven color puppeteer
#include <iostream>
#include <string>
#include <boost/property_tree/ini_parser.hpp>

int main() {
  boost::property_tree::ptree pt;
  boost::property_tree::read_ini("test.ini", pt);
  std::cout << pt.get<int>("Alice.Val") << std::endl;
  std::cout << pt.get<std::string>("Alice.Str") << std::endl;
  return 0;
}

出力

10
Seven color puppeteer