LoginSignup
3
3

More than 5 years have passed since last update.

Erlang gen_fsmで作る鳴き続ける猫

Posted at

有限ステートマシンを簡単に実装できるOPTのgen_fsm ビヘイビア(behaviour)を利用して、鳴き続ける猫とたまに逃げる猫を実装してみました。

スクリーンショット 2016-06-15 12.06.41.png
スクリーンショット 2016-06-15 12.06.44.png

1. 鳴き続ける猫

neko.erl
-module(neko).
-author("hami").
-behaviour(gen_fsm).

%% API
-export([start_link/1, cat/2, action/0]).
-export([init/1]).

start_link(CatName) ->
  gen_fsm:start_link({local, neko}, neko, CatName, []).

init(CatName) ->
  {ok, cat, CatName}.

action() ->
  gen_fsm:send_event(neko, []).

%% 猫本体
cat(FromAction, CatName) ->
  %% 鳴く
  print(string:concat(atom_to_list(CatName), ":< meow")),

  %% 次の状態
  {next_state, cat, CatName}.


%% printer
  print(Message) -> io:format("E: ~p~n",[Message]).

main.erl
-module(main).
-author("hami").

%% API
-export([main/0]).

main() ->
  %% 猫生成
  neko:start_link(shiro),

  %% アクションを実行
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action().

make.sh
# コンパイルと実行
echo "+++++++++++++"
erlc ./neko.erl
erlc ./main.erl
echo "+++++++++++++"
erl -noshell -s main main -s init stop
echo "+++++++++++++"

実行結果
+++++++++++++
E: "shiro:< meow"
E: "shiro:< meow"
E: "shiro:< meow"
E: "shiro:< meow"
E: "shiro:< meow"
E: "shiro:< meow"
+++++++++++++

2. たまに逃げる猫

スクリーンショット 2016-06-15 12.06.44.png

neko.erl
-module(neko).
-author("hami").
-behaviour(gen_fsm).

%% API
-export([start_link/1, cat/2, action/0]).
-export([init/1]).

start_link(CatName) ->
  gen_fsm:start_link({local, neko}, neko, CatName, []).

init(CatName) ->
  {ok, cat, {CatName, sleep, 0}}.

action() ->
  gen_fsm:send_event(neko, []).

%% 猫本体
cat(FromAction, {CatName, CatStatus, StrokeCount}) ->
  case CatStatus of
    sleep ->
      %% 鳴く
      print(string:concat(atom_to_list(CatName), ":< meow")),

      %% 次の状態
      if StrokeCount + 1 < 3 ->
        {next_state, cat, {CatName, sleep, StrokeCount + 1}};
      StrokeCount + 1 >= 3 ->
          {next_state, cat, {CatName, standing, 0}}
      end;

    standing ->
      %% 逃げる
      print(string:concat(atom_to_list(CatName), " ran away...")),

      %% 次の状態
      if StrokeCount + 1 < 3 ->
        {next_state, cat, {CatName, standing, StrokeCount + 1}};
        StrokeCount + 1 >= 3 ->
          {next_state, cat, {CatName, sleep, 0}}
      end;

    _ ->
      null
  end.


%% printer
  print(Message) -> io:format("E: ~p~n",[Message]).

main.erl
-module(main).
-author("hami").

%% API
-export([main/0]).

main() ->
  %% 猫生成
  neko:start_link(kuro),

  %% アクションを実行
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action(),
  neko:action().


make.sh
# コンパイルと実行
echo "+++++++++++++"
erlc ./neko.erl
erlc ./main.erl
echo "+++++++++++++"
erl -noshell -s main main -s init stop
echo "+++++++++++++"

実行結果
+++++++++++++
E: "kuro:< meow"
E: "kuro:< meow"
E: "kuro:< meow"
E: "kuro ran away..."
E: "kuro ran away..."
E: "kuro ran away..."
E: "kuro:< meow"
E: "kuro:< meow"
E: "kuro:< meow"
E: "kuro ran away..."
E: "kuro ran away..."
E: "kuro ran away..."
E: "kuro:< meow"
+++++++++++++
3
3
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
3