Erlang/OTP Forums

Author Message

<  Erlang  ~  cas...of with incoming binary

paolo
Posted: Thu Jun 03, 2010 12:51 pm Reply with quote
User Joined: 03 Jun 2010 Posts: 11
Hi all!

i'm currently working on a cards game in erlang. The problem is the following:

i'm receiving the incoming commands through gen_tcp as:
Code:
   
receive
   {tcp, Socket, Bin} ->
       inet:setopts(Socket, [{active, once}]),
       case Bin of
      <<"join">> ->
                   .....
      <<"get_cards">> ->
         .....
      <<"play", Number/integer, Seed/binary>>  ->
         .....
       end,


i would like to receive also a "take" command, where user gives the card (only 1) he wants to play and a list of cards he want to take. I have no idea on how to put down the case option...any clues? The seed can be one among "denari", "bastoni", "coppe", "spade".

thanks in advance for your help!

paolo
View user's profile Send private message
zajda
Posted: Fri Jun 04, 2010 4:30 pm Reply with quote
User Joined: 22 Aug 2009 Posts: 83
I don't understand entirely what is the problem. Matching on a value which is a list? Why not add then an option with pattern <<"take", Somestuff/binary >> and cope with bounded variable later?

Since all you options have some 'constant' string at the beginning, there is no chance that incoming message will drop into wrong case clause.
View user's profile Send private message
paolo
Posted: Sat Jun 05, 2010 7:11 am Reply with quote
User Joined: 03 Jun 2010 Posts: 11
hi,
yes, you are right. The point is that can receive something as:


Code:
<<"take", Number/integer, Seed/binary, OtherStuff/Binary>>  ->


but OtherStuff may be for example [{7,denari}] or [{6,spade},{1,denari}] and so on...tbut i don't know ex ante the size of the list.

I was just thinking about a smart way to deal with this.

Paolo
View user's profile Send private message
zajda
Posted: Sat Jun 05, 2010 11:21 pm Reply with quote
User Joined: 22 Aug 2009 Posts: 83
the last part of binary does not have to have declared length. Match on it and split it later. Be careful with building the binary - the good way is to collect all data and use binary_to_term. Binary_to_list can give you side effects. btw thats the easiest way.. maybe you should define some 'protocol' and parse defined offsets of bits.
View user's profile Send private message
paolo
Posted: Sun Jun 06, 2010 6:57 pm Reply with quote
User Joined: 03 Jun 2010 Posts: 11
thanks, i will definitely follow your hints!
View user's profile Send private message
zajda
Posted: Tue Jun 08, 2010 9:19 am Reply with quote
User Joined: 22 Aug 2009 Posts: 83
the 'match on last part' solution is kind of a hack. Now, I think that the nicest way (which is still simple) would be to send a message e.g. <<"take">> and it would be just a init-message and later send card by card. In this solutions you would have a gate (some Pattern) for single card, but initial message would set a state saying what this incoming card is doing. The other thing is tracking cards per player (to know which card comes from which user - executing particular part of the game). But this is just as simple: match on pid added at beginning. Btw it looks like FSM (finite state machine - take a look at gen_fsm) to manage state of the game.
View user's profile Send private message
paolo
Posted: Wed Jun 09, 2010 8:42 am Reply with quote
User Joined: 03 Jun 2010 Posts: 11
hi,

what about this?
1) user sends <<"take">>
2) user sends multiple times <<Number, Seed>> where the first one is the card he wants to play and the following are the card/s he wants to take
3) this cards are stored in the state of the gen_server
4) user sends <<"end-take">>

actually to know which player sent what i use the socket...

paolo
View user's profile Send private message
zajda
Posted: Wed Jun 09, 2010 4:30 pm Reply with quote
User Joined: 22 Aug 2009 Posts: 83
yes, it looks good as far as you sort out the problem of injection to the state card send by malicious user. So, maybe also in state keep some tree structure which represents cards per socket/Pid/Id.
View user's profile Send private message
paolo
Posted: Thu Jun 10, 2010 6:51 am Reply with quote
User Joined: 03 Jun 2010 Posts: 11
yeah...i thought about that..
in my current implementation i'm storing in the state of the gen_server a list of sockets representing the players. every time a player does an action allowed by the game his socket goes to the end of the list (a sort of update_turn function).

thus in my case i did something like:

Code:

"get_cards" ->
       case{is_player(Socket),is_player_turn(Socket)} of
         {true, true} ->
                                .......
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum