%% code_lock.erl
-module(code_lock). -behaviour(gen_fsm). -export([start/1, button/1]). -export([locked/2, open/2]). -export([init/1, handle_event/3, handle_sync_event/4, handle_info/3, code_change/4, terminate/3]). start(Code) -> gen_fsm:start_link({local, code_lock}, code_lock, Code, []). button(Digit) -> gen_fsm:send_event(code_lock, {button, Digit}). locked({button, Digit}, {SoFar, Code}) -> io:format("Now the code you input is: ~w~n", [SoFar ++ [Digit]]), case SoFar ++ [Digit] of Code -> io:format("Open!~n"), {next_state, open, {[], Code}, 3000}; Incomplete when length(Incomplete) < length(Code) -> {next_state, locked, {Incomplete, Code}}; _Wrong -> io:format("Wrong Code! Start Again!~n"), {next_state, locked, {[], Code}} end. open(timeout, State) -> io:format("Lock!~n"), {next_state, locked, State}. init(Code) -> {ok, locked, {[], Code}}. handle_event(_A, _B, _C) -> {next_state, ok, ok}. handle_sync_event(_A, _B, _C, _D) -> {reply, ok, ok, ok}. handle_info(_A, _B, _C) -> {next_state, ok, ok}. code_change(_A, _B, _C, _D) -> {ok, ok, ok}. terminate(_A, _B, _C) -> ok.
编译运行:
D:\erl\code>erl Eshell V5.6.3 (abort with ^G) 1> c(code_lock). {ok,code_lock} 2> code_lock:start([1,2,3]). {ok,<0.36.0>} 3> code_lock:button(1). Now the code you input is: [1] ok 4> code_lock:button(2). Now the code you input is: [1,2] ok 5> code_lock:button(3). Now the code you input is: [1,2,3] ok Open! 6> Lock! 6> code_lock:button(1). Now the code you input is: [1] ok 7> code_lock:button(2). Now the code you input is: [1,2] ok 8> code_lock:button(2). Now the code you input is: [1,2,2] ok Wrong Code! Start Again! 9>