2012-12-05 58 views
0

我正在Erlang開發一個簡單的框架來處理2人玩家回合制遊戲。該代碼是下面的:在不同的終端窗口上運行Erlang程序時的例外情況

-module(game). 
-export([start_server/0,generate_server/0,add_player/0,remove_player/0]). 


generate_server() -> 
Table_num = 0, 
Player_num = 0, 
io:format("Server generated...~n", []), 
io:format("The current number of tables is ~w~n", [Table_num]), 
io:format("The current number of players is ~w~n", [Player_num]), 
receive 
    login -> 
     io:format("A new player has connected!~n", []), 
     New = Player_num + 1, 
     io:format("The current number of players is ~w~n", [New]); 
    logout -> 
     io:format("You have beeen succesfully disconnected~n", []) 
end. 



start_server() -> 
    io:format("Welcome player!~nInitializing game...~n", []), 
    io:format("Generating server...~n", []), 
    register(server,spawn(game, generate_server, [])). 


add_player() -> 
    server ! login. 


remove_player() -> 
    server ! logout. 

有兩個主要的問題,當運行此代碼:

  1. 當我執行add_player(),然後remove_player(),該第二功能崩潰與異常
  2. 如果我在一個終端窗口上啓動程序,然後在第二個終端窗口上執行add_player(),則會出現錯誤。我應該怎麼做才能在多個終端窗口上運行它?

任何幫助將不勝感激。

回答

3

1/ 服務器中沒有環路。當你啓動它時,在一些打印之後,它等待接收語句。

當它收到登錄消息時,它執行操作,然後服務器代碼完成;該進程死亡並且未註冊。所有的變量消失,虛擬機清理內存......

所以,以後,任何向服務器發送消息的進程都會崩潰,因爲您使用的是不再註冊的名稱。

爲了使其工作,您應該保留一個連接的球員列表(例如列表中),並以此列表爲參數調用服務器環路。

generate_server(Tlist,Plist) -> 
io:format("The current number of tables is ~w~n", [length(Tlist)]), 
io:format("The current number of players is ~w~n", [length(Plist)]), 
receive 
    {login,Name} -> 
     io:format("A new player ~p has connected!~n", [Name]), 
     generate_server(Tlist,[Name|Plist]); 
    {logout,Name} -> 
     io:format("You have beeen succesfully disconnected~n", []), 
     generate_server(Tlist,lists:delete(Name,Plist)) 
end. 

,並調用generate_server由

register(server,spawn(game, generate_server, [[],[]])) 

2/ 爲了使用2個不同節點之間的Erlang消息來進行,你需要:

  • 共享相同的Erlang coockie
  • 發現節點(例如使用netadm)
  • 得到服務器的PID或使用註冊如果看不到名字

見例如在http://learnyousomeerlang.com/distribunomicon#alone-in-the-dark

+0

非常感謝您的幫助:)我會有更多的問題:P – user1301428

1

你錯過了一個loop體服務器。您的程序崩潰,因爲服務器只收到一條消息並退出。考慮下面的服務器的另一個版本:

 
generate_server() -> 
    Table_num = 0, 
    Player_num = 0, 
    io:format("Server generated...~n", []), 
    io:format("The current number of tables is ~w~n", [Table_num]), 
    io:format("The current number of players is ~w~n", [Player_num]), 
    loop([]).
loop(Players)-> receive {From,{login,PlayerId}} -> io:format("A new player has connected!~n", []), io:format("The current number of players is ~w~n", [New]), NewPlayers = case lists:member(PlayerId,Players) of true -> From ! {login_failed,exists}, Players; false -> From ! {login_success,true}, [PlayerId|Players] end, loop(NewPlayers); {From,{logout,PlayerId}} -> NewPlayers = case lists:member(PlayerId,Players) of true -> From ! {logout,ok}, Players -- [PlayerId]; false -> From ! {logout,failed}, Players end,
loop(NewPlayers); _ -> loop(Players) end.
那裏;看起來好多了。

相關問題