%% 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