Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
%% 1> c(snake).
%% {ok,snake}
%% 2> snake:run().
-module(snake).
-export([
run/0
]).
-define(DICE, 6).
-define(MAX, ?WIDTH * ?HEIGHT).
-define(WIDTH, 10).
-define(HEIGHT, 10).
-define(N_SNAKES, 10).
-define(N_LADDERS, 10).
-define(N_PLAYER, 4).
-record(state, {
positions = {0, 0, 0, 0},
n = 0,
ladders,
snakes
}).
%% public
run() ->
random:seed(os:timestamp()),
loop(#state {
ladders = generate(ladder, ?N_LADDERS),
snakes = generate(snake, ?N_SNAKES)
}).
%% private
loop(#state {
positions = Positions,
n = N,
ladders = Ladders,
snakes = Snakes
} = State) ->
Player = N rem ?N_PLAYER + 1,
Position = element(Player, Positions),
Dice = random(?DICE),
Position2 = Position + Dice,
Position3 = case lookup(Position2, Snakes) of
undefined ->
case lookup(Position2, Ladders) of
undefined ->
Position2;
Ladder ->
Ladder
end;
Snake ->
Snake
end,
Position4 = case Position3 of
?MAX ->
io:format("player ~p rolled ~p: moves from ~p to ~p and WINS~n",
[Player, Dice, Position, Position3]),
exit(winner);
X when X > ?MAX ->
Position;
X ->
X
end,
io:format("player ~p rolled ~p: moves from ~p to ~p~n",
[Player, Dice, Position, Position4]),
loop(State#state {
n = N + 1,
positions = setelement(Player, Positions, Position4)
}).
generate(Type, N) ->
[generate(Type) || _ <- lists:seq(1, N)].
generate(ladder) ->
X = random(?MAX - 1),
Y = X + random(?MAX - X - 2),
{X, Y};
generate(snake) ->
X = random(?MAX - 2),
Y = X + random(?MAX - X - 2),
{Y, X}.
lookup(Key, List) ->
case lists:keyfind(Key, 1, List) of
false -> undefined;
{_, Value} -> Value
end.
random(N) ->
trunc(random:uniform() * N) + 1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment