Erlang
OTP
gen_fsm

Erlang gen_fsmで作る鳴き続ける猫

More than 1 year has passed since last update.

有限ステートマシンを簡単に実装できる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"
+++++++++++++